2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 16:52:15 +00:00

Compare commits

..

66 Commits

Author SHA1 Message Date
Dave Abrahams
c9f0b74bd2 checkpoint for volodya
[SVN r37161]
2007-03-08 15:56:58 +00:00
nobody
c722fe8fb1 This commit was manufactured by cvs2svn to create branch 'bbv2python'.
[SVN r37109]
2007-02-27 23:59:41 +00:00
Dave Abrahams
c73ad50286 Roll back improved error message because it causes problems for vc6/7
[SVN r36435]
2006-12-16 22:00:35 +00:00
Dave Abrahams
0910710ac4 Correct class/function mismatches for MSVC and bring across
documentation tweaks from HEAD.


[SVN r36355]
2006-12-13 15:08:26 +00:00
Dave Abrahams
04c528138b Fully switch to BBv2
[SVN r36327]
2006-12-11 05:22:04 +00:00
nobody
1b66cd9643 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r36324]
2006-12-11 05:02:35 +00:00
Dave Abrahams
c2dd9fa833 Fix auto-link to look at the right variable.
[SVN r36319]
2006-12-11 03:00:26 +00:00
Dave Abrahams
b085121369 merged from trunk
[SVN r36292]
2006-12-07 17:45:17 +00:00
Beman Dawes
fa219bce9b Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
Rene Rivera
10b85d67e7 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Stefan Seefeld
ca91dc828e Fix symbol visibility.
[SVN r35754]
2006-10-27 21:19:47 +00:00
Dave Abrahams
3a53c1dec0 Add fixes somehow missed for darwin
[SVN r35612]
2006-10-14 19:10:30 +00:00
nobody
da8e309957 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35598]
2006-10-13 21:34:27 +00:00
Dave Abrahams
2bd9141d4a make numpy tests portable to Darwin with older docutils
[SVN r35597]
2006-10-13 21:34:26 +00:00
Dave Abrahams
c3bda6a903 Fix some problems with testing on old docutils installations
[SVN r35594]
2006-10-13 19:35:28 +00:00
Dave Abrahams
d61909d3ea Make object comparison operators return object instead of bool, to
accomodate strange beasts like numarray arrays that return arrays that
can't be used as truth values from their comparison ops.

Fix numpy test for portability with old doctest (again!)


[SVN r35572]
2006-10-12 09:07:07 +00:00
Dave Abrahams
1755dad7e6 merged from trunk
[SVN r35569]
2006-10-12 06:42:20 +00:00
Dave Abrahams
3b392c99be Adjust tests to account for numarray behavior differences
[SVN r35539]
2006-10-10 22:44:09 +00:00
Dave Abrahams
24ba93607b Try for backward compatibility with older versions of doctest
[SVN r35535]
2006-10-10 18:12:43 +00:00
Dave Abrahams
49d4aac8ec Fix lots of bugs in the numeric interface and tests.
Tests:
* Coerce a result to bool to deal with Python's new Bool type
* Better reporting of mismatches in expected and received results
* Remove bogus nullary y.astype() call
* Fix all uses of trace and diagonal so they don't cause errors
* Use appropriate typecodes
* Use doctest detailed API to run just the relevant tests
* Factor out error handling from macro

API:
* Added get_module_name() function to get current numeric module
* new_(x) now returns an array instead of object
* Fixed the signatures of the factory() family of functions
* Updated docs accordingly.


[SVN r35528]
2006-10-09 04:05:25 +00:00
Dave Abrahams
545be29ad3 (hopefully) grab the last bit of logic from HEAD for a bugfix I've been trying to apply to the branch for days(!)
[SVN r35436]
2006-10-01 18:25:44 +00:00
Dave Abrahams
8553c109c7 merged from HEAD
[SVN r35429]
2006-09-29 22:27:57 +00:00
Dave Abrahams
315c3d50ee Apply missing elements of previously-"applied" bug fix.
[SVN r35421]
2006-09-29 15:45:29 +00:00
Dave Abrahams
d5219979a4 Fix bugs uncovered by Roman Yakovenko
[SVN r35410]
2006-09-29 02:09:13 +00:00
Dave Abrahams
d42054f3a0 Cleans up license/copyright warnings
[SVN r35409]
2006-09-29 02:08:32 +00:00
nobody
72b06e70ee This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35366]
2006-09-28 14:41:02 +00:00
Dave Abrahams
375cc3aa93 Fix broken links
[SVN r35330]
2006-09-26 04:25:49 +00:00
Ralf W. Grosse-Kunstleve
4eb286a034 ssize_t patches merged from HEAD
[SVN r35327]
2006-09-26 00:48:44 +00:00
nobody
a824230155 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35326]
2006-09-26 00:25:08 +00:00
Gottfried Ganßauge
1bc3750ab3 repaired broken links
[SVN r35315]
2006-09-25 07:35:57 +00:00
Dave Abrahams
36abcee847 merged from HEAD
[SVN r35277]
2006-09-22 15:13:30 +00:00
Gottfried Ganßauge
b8b7768eb7 Test for cross module support of opaque
[SVN r35256]
2006-09-21 16:47:49 +00:00
Gottfried Ganßauge
7ad9dc6c64 Changed references to opaque_pointer_converter.html to point to opaque.html instead
[SVN r35255]
2006-09-21 16:47:31 +00:00
Gottfried Ganßauge
decc34551a Renamed to opaque.html because class name changed
[SVN r35254]
2006-09-21 16:47:00 +00:00
Gottfried Ganßauge
5acb44ede0 Renamed from opaque_pointer_converter.html because class name changed
[SVN r35253]
2006-09-21 16:46:42 +00:00
Gottfried Ganßauge
ef62f87963 type object gets initialized. Cross module support works
[SVN r35252]
2006-09-21 16:46:21 +00:00
Joel de Guzman
b5c893381f merge from head
[SVN r35246]
2006-09-21 10:52:01 +00:00
Vladimir Prus
815969bf8b Merge: Add tests
[SVN r35245]
2006-09-21 07:27:11 +00:00
nobody
0d57e9e808 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35243]
2006-09-21 07:07:15 +00:00
Dave Abrahams
7ba6a00617 Apply Boost license, with permission from Prabhu Ramachandran.
[SVN r35240]
2006-09-21 03:43:59 +00:00
Dave Abrahams
e70bbe4791 Fix license/copyright.
Also port some "glaringly obvious" bugfixes from HEAD.  Hope it
doesn't cause problems.


[SVN r35237]
2006-09-20 22:49:18 +00:00
Stefan Seefeld
7ff0f62729 Fix copyright issues.
[SVN r35236]
2006-09-20 22:30:39 +00:00
Dave Abrahams
95f0b39c90 merged from HEAD
[SVN r35185]
2006-09-18 22:22:31 +00:00
nobody
23057688f9 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35170]
2006-09-18 19:56:20 +00:00
Dave Abrahams
029618f719 merged from HEAD
[SVN r35165]
2006-09-18 18:25:57 +00:00
Dave Abrahams
38f7a4e9b6 merge from HEAD
[SVN r35141]
2006-09-17 02:42:51 +00:00
Dave Abrahams
326c871224 attempt unverified workaround for http://tinyurl.com/gvrgd
[SVN r35103]
2006-09-13 22:47:11 +00:00
Dave Abrahams
924eeccd53 merged from trunk
[SVN r35080]
2006-09-13 00:02:56 +00:00
Dave Abrahams
4a63cf4843 Move definition of BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION back
where it belongs.


[SVN r35076]
2006-09-12 22:37:09 +00:00
Dave Abrahams
1d65b74273 Add missing license/copyright
[SVN r35070]
2006-09-11 22:27:29 +00:00
Dave Abrahams
3c1ae689a7 merged from trunk
[SVN r34943]
2006-08-24 19:04:23 +00:00
Dave Abrahams
a99bd50e52 merged from trunk
[SVN r34940]
2006-08-24 13:05:30 +00:00
Dave Abrahams
8b178594ff merged from trunk
[SVN r34915]
2006-08-22 11:51:18 +00:00
Dave Abrahams
786aeef998 merged from trunk
[SVN r34872]
2006-08-11 15:51:09 +00:00
Dave Abrahams
45e4cf506f merged from trunk
[SVN r34865]
2006-08-11 00:48:19 +00:00
Gennaro Prota
8fb6e1f48d (merge from head)
removed tabs (inspect tool)


[SVN r34723]
2006-07-24 22:28:41 +00:00
Gennaro Prota
ecf70b05f2 (merge from head)
removed tabs (inspect tool)


[SVN r34721]
2006-07-24 22:21:39 +00:00
Gennaro Prota
c54acdb9db (merge from head)
minor fix: violation of min/max guidelines


[SVN r34718]
2006-07-24 22:06:09 +00:00
Vladimir Prus
489dae2b58 Clarify comment
[SVN r34668]
2006-07-22 12:53:49 +00:00
Vladimir Prus
f852ce6f7b Windows
[SVN r34667]
2006-07-22 12:28:43 +00:00
Vladimir Prus
e500919d25 Merge: Don't link Boost.Python to python library
[SVN r34663]
2006-07-22 07:16:18 +00:00
Markus Schöpflin
7a645a6d8a Merged header inclusion order fix from trunk to release branch.
[SVN r34195]
2006-06-06 09:44:35 +00:00
Markus Schöpflin
fa2185e5ab Merged header inclusion order fix from trunk to release branch.
[SVN r34194]
2006-06-06 09:39:16 +00:00
Vladimir Prus
5cc33461dd Merge from trunk
[SVN r33626]
2006-04-10 09:02:57 +00:00
Markus Schöpflin
7b93f2fdc5 Merged fix from HEAD for Tru64/CXX compilation error.
[SVN r33455]
2006-03-23 09:40:38 +00:00
nobody
219743964d This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
297 changed files with 1502 additions and 24027 deletions

BIN
build/Attic/python_v1.zip Normal file

Binary file not shown.

View File

@@ -7,13 +7,12 @@ import modules ;
import python ;
if [ python.configured ] {
project boost/python
: source-location ../src
;
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
: source-location ../src
;
lib boost_python
: # sources
@@ -46,7 +45,6 @@ lib boost_python
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
@@ -63,12 +61,7 @@ lib boost_python
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
<library>/python//python_for_extensions
: # default build
<link>shared
@@ -76,5 +69,9 @@ lib boost_python
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<link>shared:<define>BOOST_PYTHON_DYNAMIC_LIB
;
boost-install boost_python ;
}
else
{
ECHO "warning: Python location is not configured" ;
ECHO "warning: the Boost.Python library won't be built" ;
}

View File

@@ -1,23 +0,0 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import docutils ;
import path ;
sources = building.rst ;
bases = $(sources:S=) ;
# This is a path relative to the html/ subdirectory where the
# generated output will eventually be moved.
stylesheet = "--stylesheet=../../../rst.css" ;
for local b in $(bases)
{
html $(b) : $(b).rst :
<docutils-html>"-gdt --source-url="./$(b).rst" --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
;
}
alias htmls : $(bases) ;
stage . : $(bases) ;

View File

@@ -1,415 +1,461 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<title>Boost C++ Libraries: Boost.Python Build and Test HOWTO</title>
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-boost-python-build-and-test-howto">
<h1 class="title"><a class="reference" href="../index.htm"><img alt="Boost C++ Libraries:" class="boost-logo" src="../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at -->
<!-- http://www.boost.org/LICENSE_1_0.txt) -->
<div class="contents sidebar small topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="auto-toc simple">
<li><a class="reference" href="#requirements" id="id20" name="id20">1&nbsp;&nbsp;&nbsp;Requirements</a></li>
<li><a class="reference" href="#background" id="id21" name="id21">2&nbsp;&nbsp;&nbsp;Background</a></li>
<li><a class="reference" href="#getting-boost-python-binaries" id="id22" name="id22">3&nbsp;&nbsp;&nbsp;Getting Boost.Python Binaries</a><ul class="auto-toc">
<li><a class="reference" href="#no-install-quickstart" id="id23" name="id23">3.1&nbsp;&nbsp;&nbsp;No-Install Quickstart</a></li>
<li><a class="reference" href="#installing-boost-python-on-your-system" id="id24" name="id24">3.2&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></li>
</ul>
</li>
<li><a class="reference" href="#configuring-boost-build" id="id25" name="id25">4&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a></li>
<li><a class="reference" href="#building-an-extension-module" id="id26" name="id26">5&nbsp;&nbsp;&nbsp;Building an Extension Module</a></li>
<li><a class="reference" href="#testing" id="id27" name="id27">6&nbsp;&nbsp;&nbsp;Testing</a></li>
<li><a class="reference" href="#advanced-configuration" id="id28" name="id28">7&nbsp;&nbsp;&nbsp;Advanced Configuration</a><ul class="auto-toc">
<li><a class="reference" href="#python-configuration-parameters" id="id29" name="id29">7.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></li>
<li><a class="reference" href="#examples" id="id30" name="id30">7.2&nbsp;&nbsp;&nbsp;Examples</a></li>
</ul>
</li>
<li><a class="reference" href="#choosing-a-boost-python-library-binary" id="id31" name="id31">8&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a><ul class="auto-toc">
<li><a class="reference" href="#the-dynamic-binary" id="id32" name="id32">8.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></li>
<li><a class="reference" href="#the-static-binary" id="id33" name="id33">8.2&nbsp;&nbsp;&nbsp;The Static Binary</a></li>
</ul>
</li>
<li><a class="reference" href="#notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users" id="id34" name="id34">9&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></li>
</ul>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id20" id="requirements" name="requirements">1&nbsp;&nbsp;&nbsp;Requirements</a></h1>
<p>Boost.Python requires <a class="reference" href="http://www.python.org/2.2">Python 2.2</a><a class="footnote-reference" href="#id16" id="id2" name="id2"><sup>1</sup></a> <em>or</em> <a class="reference" href="http://www.python.org"><em>newer</em></a>.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id21" id="background" name="background">2&nbsp;&nbsp;&nbsp;Background</a></h1>
<p>There are two basic models for combining C++ and Python:</p>
<ul class="simple">
<li><a class="reference" href="http://www.python.org/doc/current/ext/intro.html">extending</a>, in which the end-user launches the Python interpreter
executable and imports Python “extension modules” written in C++.
Think of taking a library written in C++ and giving it a Python
interface so Python programmers can use it. From Python, these
modules look just like regular Python modules.</li>
<li><a class="reference" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a>, in which the end-user launches a program written
in C++ that in turn invokes the Python interpreter as a library
subroutine. Think of adding scriptability to an existing
application.</li>
</ul>
<p>The key distinction between extending and embedding is the location
of C++' <tt class="docutils literal"><span class="pre">main()</span></tt> function: in the Python interpreter executable,
or in some other program, respectively. Note that even when
embedding Python in another program, <a class="reference" href="http://www.python.org/doc/current/ext/extending-with-embedding.html">extension modules are often
the best way to make C/C++ functionality accessible to Python
code</a>, so the use of extension modules is really at the heart of
both models.</p>
<p>Except in rare cases, extension modules are built as
dynamically-loaded libraries with a single entry point, which means
you can change them without rebuilding either the other extension
modules or the executable containing <tt class="docutils literal"><span class="pre">main()</span></tt>.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id22" id="getting-boost-python-binaries" name="getting-boost-python-binaries">3&nbsp;&nbsp;&nbsp;Getting Boost.Python Binaries</a></h1>
<p>Since Boost.Python is a separately-compiled (as opposed to
<a class="reference" href="../../../more/getting_started/windows.html#header-only-libraries">header-only</a>) library, its user relies on the services of a
Boost.Python library binary.</p>
<div class="section">
<h2><a class="toc-backref" href="#id23" id="no-install-quickstart" name="no-install-quickstart">3.1&nbsp;&nbsp;&nbsp;No-Install Quickstart</a></h2>
<p>If you just want to get started quickly building and testing
Boost.Python extension modules, or embedding Python in an
executable, you don't need to worry about installing Boost.Python
binaries explicitly. These instructions use <a class="reference" href="../../../tools/build">Boost.Build</a> projects,
which will build those binaries as soon as they're needed. Your
first tests may take a little longer while you wait for
Boost.Python to build, but doing things this way will save you from
worrying about build intricacies like which library binaries to use
for a specific compiler configuration.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p>Of course it's possible to use other build systems to
build Boost.Python and its extensions, but they are not
officially supported by Boost and <strong>99% of all “I can't build
Boost.Python” problems come from trying to use another build
system</strong>.</p>
<p class="last">If you want to use another system anyway, we suggest that you
follow these instructions, and then invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> with the
<tt class="docutils literal"><span class="pre">-a</span> <span class="pre">-o</span></tt><em>filename</em> option to dump the build commands it executes
to a file, so you can see what your build system needs to do.</p>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id24" id="installing-boost-python-on-your-system" name="installing-boost-python-on-your-system">3.2&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></h2>
<p>If you need a regular, installation of the Boost.Python library
binaries on your system, the Boost <a class="reference" href="../../../more/getting_started/index.html">Getting Started Guide</a> will
walk you through the steps of installing one. If building binaries
from source, you might want to supply the <tt class="docutils literal"><span class="pre">--with-python</span></tt>
argument to <tt class="docutils literal"><span class="pre">bjam</span></tt> (or the <tt class="docutils literal"><span class="pre">--with-libraries=python</span></tt> argument
to <tt class="docutils literal"><span class="pre">configure</span></tt>), so only the Boost.Python binary will be built,
rather than all the Boost binaries.</p>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id25" id="configuring-boost-build" name="configuring-boost-build">4&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a></h1>
<p>As described in the <a class="reference" href="http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration">Boost.Build reference manual</a>, a file called
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home
directory<a class="footnote-reference" href="#home-dir" id="id5" name="id5"><sup>7</sup></a> is used to
describe the build resources available to the build system. You'll
need to tell it about your Python installation.</p>
<div class="admonition-users-of-unix-variant-oses admonition">
<p class="first admonition-title">Users of Unix-Variant OSes</p>
<p class="last">If you are using a unix-variant OS and you ran Boost's
<tt class="docutils literal"><span class="pre">configure</span></tt> script, it may have generated a
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> for you.<a class="footnote-reference" href="#overwrite" id="id7" name="id7"><sup>4</sup></a> If your <tt class="docutils literal"><span class="pre">configure</span></tt>/<tt class="docutils literal"><span class="pre">make</span></tt> sequence was successful and Boost.Python binaries
were built, your <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file is probably already
correct.</p>
</div>
<p>If you have a fairly “standard” python installation for your
platform, there's very little you need to do to describe it.
Simply having</p>
<pre class="literal-block">
import toolset : using ;
using python ;
</pre>
<p>in a <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file in your home directory<a class="footnote-reference" href="#home-dir" id="id8" name="id8"><sup>7</sup></a>
should be enough.<a class="footnote-reference" href="#user-config-jam" id="id9" name="id9"><sup>6</sup></a> For more complicated setups,
see <a class="reference" href="#advanced-configuration">Advanced Configuration</a>.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">You might want to pass the <tt class="docutils literal"><span class="pre">--debug-configuration</span></tt>
option to <tt class="docutils literal"><span class="pre">bjam</span></tt> the first few times you invoke it, to make
sure that Boost.Build is correctly locating all the parts of
your Python installation. If it isn't, consider passing some of
the optional <a class="reference" href="#python-configuration-parameters">Python configuration parameters</a> detailed below.</p>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id26" id="building-an-extension-module" name="building-an-extension-module">5&nbsp;&nbsp;&nbsp;Building an Extension Module</a></h1>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id27" id="testing" name="testing">6&nbsp;&nbsp;&nbsp;Testing</a></h1>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id28" id="advanced-configuration" name="advanced-configuration">7&nbsp;&nbsp;&nbsp;Advanced Configuration</a></h1>
<p>If you have several versions of Python installed, or Python is
installed in an unusual way, you may want to supply any or all of
the following optional parameters to <tt class="docutils literal"><span class="pre">using</span> <span class="pre">python</span></tt>.</p>
<div class="section">
<h2><a class="toc-backref" href="#id29" id="python-configuration-parameters" name="python-configuration-parameters">7.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></h2>
<dl class="docutils">
<dt>version</dt>
<dd>the version of Python to use. Should be in Major.Minor
format, for example, <tt class="docutils literal"><span class="pre">2.3</span></tt>. Do not include the subminor
version (i.e. <em>not</em> <tt class="docutils literal"><span class="pre">2.5.1</span></tt>). If you have multiple Python
versions installed, the version will usually be the only
additional argument required.</dd>
<dt>cmd-or-prefix</dt>
<dd>preferably, a command that invokes a Python
interpreter. Alternatively, the installation prefix for Python
libraries and header files. Use the alternative formulation if
there is no appropriate Python executable available.</dd>
<dt>includes</dt>
<dd>the <tt class="docutils literal"><span class="pre">#include</span></tt> path for Python headers.</dd>
<dt>libraries</dt>
<dd>the path to Python library binaries. On MacOS/Darwin,
you can also pass the path of the Python framework.</dd>
<dt>condition</dt>
<dd>if specified, should be a set of Boost.Build
properties that are matched against the build configuration when
Boost.Build selects a Python configuration to use.</dd>
<dt>extension-suffix</dt>
<dd>A string to append to the name of extension
modules before the true filename extension. You almost certainly
don't need to use this. Usually this suffix is only used when
targeting a Windows debug build of Python, and will be set
automatically for you based on the value of the
<tt class="docutils literal"><span class="pre">&lt;python-debugging&gt;</span></tt> feature. However, at least one Linux
distribution (Ubuntu Feisty Fawn) has a specially configured
<a class="reference" href="https://wiki.ubuntu.com/PyDbgBuilds">python-dbg</a> package that claims to use such a suffix.</dd>
</dl>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id30" id="examples" name="examples">7.2&nbsp;&nbsp;&nbsp;Examples</a></h2>
<p>Note that in the examples below, case and <em>especially whitespace</em> are
significant.</p>
<ul>
<li><p class="first">If you have both python 2.5 and python 2.4 installed,
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> might contain:</p>
<pre class="literal-block">
using python : 2.5 ; # Make both versions of Python available
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
using python : 2.4 ; # To build with python 2.4, add python=2.4
# to your command line.
</pre>
<p>The first version configured (2.5) becomes the default. To build
against python 2.4, add <tt class="docutils literal"><span class="pre">python=2.4</span></tt> to the <tt class="docutils literal"><span class="pre">bjam</span></tt> command line.</p>
</li>
<li><p class="first">If you have python installed in an unusual location, you might
supply the path to the interpreter in the <tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>
parameter:</p>
<pre class="literal-block">
using python : : /usr/local/python-2.6-beta/bin/python ;
</pre>
</li>
<li><p class="first">If you have a separate build of Python for use with a particular
toolset, you might supply that toolset in the <tt class="docutils literal"><span class="pre">condition</span></tt>
parameter:</p>
<pre class="literal-block">
using python ; # use for most toolsets
<title>Boost.Python - Building and Testing</title>
</head>
# Use with Intel C++ toolset
using python
: # version
: c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
: # includes
: # libraries
: &lt;toolset&gt;intel # condition
;
</pre>
</li>
<li><p class="first">You can set up your user-config.jam so a bjam built under Windows
can build/test both Windows and <a class="reference" href="http://cygwin.com">Cygwin</a> python extensions. Just pass
<tt class="docutils literal"><span class="pre">&lt;target-os&gt;cygwin</span></tt> in the <tt class="docutils literal"><span class="pre">condition</span></tt> parameter
for the cygwin python installation:</p>
<pre class="literal-block">
# windows installation
using python ;
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../boost.png" border="0"></a></h3>
</td>
# cygwin installation
using python : : c:\\cygwin\\bin\\python2.5 : : : &lt;target-os&gt;cygwin ;
</pre>
<p>when you put target-os=cygwin in your build request, it should build
with the cygwin version of python:<a class="footnote-reference" href="#flavor" id="id11" name="id11"><sup>5</sup></a></p>
<blockquote>
<p>bjam target-os=cygwin toolset=gcc</p>
</blockquote>
<p>This is supposed to work the other way, too (targeting windows
python with a <a class="reference" href="http://cygwin.com">Cygwin</a> bjam) but it seems as though the support in
Boost.Build's toolsets for building that way is broken at the
time of this writing.</p>
</li>
<li><p class="first">Note that because of <a class="reference" href="http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection">the way Boost.Build currently selects target
alternatives</a>, you might have be very explicit in your build
requests. For example, given:</p>
<pre class="literal-block">
using python : 2.5 ; # a regular windows build
using python : 2.4 : : : : &lt;target-os&gt;cygwin ;
</pre>
<p>building with</p>
<pre class="literal-block">
bjam target-os=cygwin
</pre>
<p>will yield an error. Instead, you'll need to write:</p>
<pre class="literal-block">
bjam target-os=cygwin/python=2.4
</pre>
</li>
</ul>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id31" id="choosing-a-boost-python-library-binary" name="choosing-a-boost-python-library-binary">8&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a></h1>
<p>If—instead of letting Boost.Build construct and link withthe right
libraries automatically—you choose to use a pre-built Boost.Python
library, you'll need to think about which one to link with. The
Boost.Python binary comes in both static and dynamic flavors. Take
care to choose the right flavor for your application.<a class="footnote-reference" href="#naming" id="id13" name="id13"><sup>2</sup></a></p>
<div class="section">
<h2><a class="toc-backref" href="#id32" id="the-dynamic-binary" name="the-dynamic-binary">8.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></h2>
<p>The dynamic library is the safest and most-versatile choice:</p>
<ul class="simple">
<li>A single copy of the library code is used by all extension
modules built with a given toolset.<a class="footnote-reference" href="#toolset-specific" id="id14" name="id14"><sup>3</sup></a></li>
<li>The library contains a type conversion registry. Because one
registry is shared among all extension modules, instances of a
class exposed to Python in one dynamically-loaded extension
module can be passed to functions exposed in another such module.</li>
</ul>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id33" id="the-static-binary" name="the-static-binary">8.2&nbsp;&nbsp;&nbsp;The Static Binary</a></h2>
<p>It might be appropriate to use the static Boost.Python library in
any of the following cases:</p>
<ul class="simple">
<li>You are <a class="reference" href="http://www.python.org/doc/current/ext/intro.html">extending</a> python and the types exposed in your
dynamically-loaded extension module don't need to be used by any
other Boost.Python extension modules, and you don't care if the
core library code is duplicated among them.</li>
<li>You are <a class="reference" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a> python in your application and either:<ul>
<li>You are targeting a Unix variant OS other than MacOS or AIX,
where the dynamically-loaded extension modules can “see” the
Boost.Python library symbols that are part of the executable.</li>
<li>Or, you have statically linked some Boost.Python extension
modules into your application and you don't care if any
dynamically-loaded Boost.Python extension modules are able to
use the types exposed by your statically-linked extension
modules (and vice-versa).</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id34" id="notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users" name="notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users">9&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></h1>
<p>If you are using a version of Python prior to 2.4.1 with a MinGW
prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will need to
create a MinGW-compatible version of the Python library; the one
shipped with Python will only work with a Microsoft-compatible
linker. Follow the instructions in the “Non-Microsoft” section of
the “Building Extensions: Tips And Tricks” chapter in <a class="reference" href="http://www.python.org/doc/current/inst/index.html">Installing
Python Modules</a> to create <tt class="docutils literal"><span class="pre">libpythonXX.a</span></tt>, where <tt class="docutils literal"><span class="pre">XX</span></tt>
corresponds to the major and minor version numbers of your Python
installation.</p>
<hr class="docutils" />
<table class="docutils footnote" frame="void" id="id16" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2" name="id16">[1]</a></td><td>Note that although we tested earlier versions of
Boost.Python with Python 2.2, and we don't <em>think</em> we've done
anything to break compatibility, this release of Boost.Python
may not have been tested with versions of Python earlier than
2.4, so we're not 100% sure that python 2.2 and 2.3 are
supported.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="naming" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id13" name="naming">[2]</a></td><td><p class="first">Information about how to identify the
static and dynamic builds of Boost.Python:</p>
<ul class="simple">
<li><a class="reference" href="../../../more/getting_started/windows.html#library-naming">on Windows</a></li>
<li><a class="reference" href="../../../more/getting_started/unix-variants.html#library-naming">on Unix variants</a></li>
</ul>
<p class="last">Be sure to read this section even if your compiler supports
auto-linking, as Boost.Python does not yet take advantage of
that feature.</p>
</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="toolset-specific" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id14" name="toolset-specific">[3]</a></td><td>Because of the way most *nix platforms
share symbols among dynamically-loaded objects, I'm not
certainextension modules built with different compiler toolsets
will always use different copies of the Boost.Python library
when loaded into the same Python instance. Not using different
libraries could be a good thing if the compilers have compatible
ABIs, because extension modules built with the two libraries
would be interoperable. Otherwise, it could spell disaster,
since an extension module and the Boost.Python library would
have different ideas of such things as class layout. I would
appreciate someone doing the experiment to find out what
happens.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="overwrite" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id7" name="overwrite">[4]</a></td><td><tt class="docutils literal"><span class="pre">configure</span></tt> overwrites the existing
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home directory
(if any) after making a backup of the old version.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="flavor" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id11" name="flavor">[5]</a></td><td>Note that the <tt class="docutils literal"><span class="pre">&lt;target-os&gt;cygwin</span></tt> feature is
different from the <tt class="docutils literal"><span class="pre">&lt;flavor&gt;cygwin</span></tt> subfeature of the <tt class="docutils literal"><span class="pre">gcc</span></tt>
toolset, and you might need handle both explicitly if you also
have a MinGW GCC installed.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="user-config-jam" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id9" name="user-config-jam">[6]</a></td><td>Create the <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file if you don't
already have one.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="home-dir" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="home-dir">[7]</a></td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id8">2</a>)</em> <p>Windows users, your home directory can be
found by typing:</p>
<pre class="literal-block">
ECHO %HOMEDRIVE%%HOMEPATH%
</pre>
<p class="last">into a <a class="reference" href="../../../more/getting_started/windows.html#or-build-from-the-command-prompt">Windows command prompt</a></p>
</td></tr>
</tbody>
</table>
</div>
</div>
<div class="footer">
<hr class="footer" />
<a class="reference" href="./building.rst">View document source</a>.
Generated on: 2007-04-05 20:04 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.
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
</div>
</body>
<h2 align="center">Building and Testing</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="Reference">
<dt><a href="#requirements">Requirements</a></dt>
<dt><a href="#building">Building Boost.Python</a></dt>
<dd>
<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>
<dt><a href="#variants">Build Variants</a></dt>
<dt><a href="#VisualStudio">Building Using the Microsoft Visual Studio
IDE</a></dt>
</dl>
<hr>
<h2><a name="requirements">Requirements</a></h2>
<b>Boost.Python</b> requires <a href=
"http://www.python.org/2.2">Python 2.2</a> <i>or <a href=
"http://www.python.org">newer</a></i>.
<h2><a name="building">Building Boost.Python</a></h2>
<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
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/v1/build_system.htm">Boost.Build</a> in the
usual way from the <code>libs/python/build</code> subdirectory of your
boost installation (if you have already built boost from the top level
this may have no effect, since the work is already done).</p>
<h3><a name="configuration">Basic Configuration</a></h3> You may
need to configure the following variables to point Boost.Build at
your Python installation. Variables can be either set in the
environment or passed on the <code>bjam</code> command-line
as <code>-s</code><i>name</i><code>=</code><i>value</i>. Variable
names are case-sensitive.
<table border="1" summary="build configuration variables">
<tr>
<th>Variable Name</th>
<th>Semantics</th>
<th>Default</th>
<th>Notes</th>
</tr>
<tr>
<tr>
<td><code>PYTHON_VERSION</code></td>
<td>The The 2-part python Major.Minor version number</td>
<td><code>2.4</code></td>
<td>Be sure not to include a third number, e.g. <b>not</b>
"<code>2.2.1</code>", even if that's the version you have.</td>
</tr>
<td><code>PYTHON_ROOT</code></td>
<td>The root directory of your Python installation</td>
<td>Windows:&nbsp;<code>c:/Python</code><i>(10*Version)</i>, e.g. <code>c:/Python24</code>
<br>
*nix/Cygwin:&nbsp;<code>/usr</code></td>
<td>On *nix, this should be the <code>--prefix=</code> directory used
to configure Python when it was built and installed.</td>
</tr>
<tr>
<td><code>PYTHON_INCLUDES</code></td>
<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>
</tr>
<tr>
<td><code>PYTHON_LIB_PATH</code></td>
<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>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]VERSION</code></td>
<td>The version of python being used under Cygwin.</td>
<td>$(PYTHON_VERSION)</td>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]ROOT</code></td>
<td>*nix-style path containing the <code>include/</code> directory
containing
<code>python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h</code>.</td>
<td>$(PYTHON_ROOT)</td>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]LIB_PATH</code></td>
<td>path containing the user's Cygwin Python import lib
<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.a</code></td>
<td>Autoconfigured from <code>CYGWIN_PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]DLL_PATH</code></td>
<td>path containing the user's Cygwin Python dll
(<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll</code>)</td>
<td><code>/bin</code></td>
</tr>
</table>
<h3><a name="cygwin">Notes for Cygwin GCC Users</a></h3>
<p>If you are using Cygwin GCC to build extension modules, you must use a
Cygwin build of Python. The regular Win32 Python installation that you
can download from <a href="http://www.python.org">python.org</a> will not
work with your compiler because the dynamic linking conventions are
different (you can use <a href="http://www.mingw.org/">MinGW</a> GCC if
you want to build extension modules which are compatible with a stock
Win32 Python). The Cygwin installer may be able to install an appropriate
version of Python, or you can follow the traditional <a href=
"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>If you are using a version of Python prior to 2.4.1 with a
MinGW prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will
need to create a MinGW-compatible version of the Python library;
the one shipped with Python will only work with a
Microsoft-compatible linker. Follow the instructions in the
"Non-Microsoft" section of the "Building Extensions: Tips And Tricks"
chapter in <a 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>
<h3><a name="results">Results</a></h3>
<p>The build process will create a
<code>libs/python/build/bin-stage</code> subdirectory of the boost root
(or of <code>$(ALL_LOCATE_TARGET)</code>, if you have set that variable),
containing the built libraries. The libraries are actually built to
unique directories for each toolset and variant elsewhere in the
filesystem, and copied to the <code>bin-stage</code> directory as a
convenience, so if you build with multiple toolsets at once, the product
of later toolsets will overwrite that of earlier toolsets in
<code>bin-stage</code>.</p>
<h3><a name="testing">Testing</a></h3>
<p>To build and test Boost.Python, start from the
<code>libs/python/test</code> directory and invoke</p>
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../more/getting_started.html#Tools">toolset</a></i> test
</pre>
</blockquote>
This will update all of the Boost.Python v1 test and example targets. The
tests are relatively verbose by default. To get less-verbose output, you
might try
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../more/getting_started.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS= test
</pre>
</blockquote>
By default, <code>PYTHON_TEST_ARGS</code> is set to <code>-v</code>.
<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 "<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.
<p>The files required to build a Boost.Python extension module using bjam
are the "local" files <tt>Jamfile</tt>, <tt>Jamrules</tt>, and
<tt>boost_build.jam</tt>, and the <tt>boost/</tt>
and <tt>tools/build/v1/</tt> subdirectories of your Boost
tree. The latter directory contains the source code of the
Boost.Build system, which is used to generate the correct build
commands for your extension module. The '<tt>v1</tt>' refers to
Boost.Build version 1. Version 2 is pre-release and currently not
ready for general use.
<p>
The <tt>libs/python/example/</tt> project we're going to build is
set up to automatically rebuild the Boost.Python library in place
whenever it's out-of-date rather than just reusing an existing
library, so you'll also need the Boost.Python library sources in
<tt>boost/python/src/</tt>.
</p>
<blockquote>
<b>Note:</b> Third-party package and distribution maintainers
for various operating systems sometimes split up Boost's
structure or omit parts of it, so if you didn't download an
official <a href=
"http://sourceforge.net/project/showfiles.php?group_id=7586">Boost
release</a> you might want to <a href=
"http://cvs.sourceforge.net/viewcvs.py/boost/boost/">browse our CVS
structure</a> to make sure you have everything you need, and in the
right places.
</blockquote>
<p>The <code>libs/python/example</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:</p>
<ol>
<li>
<code><a href=
"../example/boost-build.jam"><b>boost-build.jam</b></a></code> - edit
the line which reads
<blockquote>
<pre>
boost-build ../../../tools/build/v1 ;
</pre>
</blockquote>
so that the path refers to the <code>tools/build/v1</code>
subdirectory of your Boost installation.
</li>
<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.
</li>
</ol>
<p>The instructions <a href="#testing">above</a> for testing Boost.Python
apply equally to your new extension modules in this subproject.</p>
<h2><a name="variants">Build Variants</a></h2>
Three <a href=
"../../../tools/build/v1/build_system.htm#variants">variant</a>
configurations of all python-related targets are supported, and can be
selected by setting the <code><a href=
"../../../tools/build/v1/build_system.htm#user_globals">BUILD</a></code>
variable:
<ul>
<li><code>release</code> (optimization, <tt>-DNDEBUG</tt>)</li>
<li><code>debug</code> (no optimization <tt>-D_DEBUG</tt>)</li>
<li><code>debug-python</code> (no optimization, <tt>-D_DEBUG
-DBOOST_DEBUG_PYTHON</tt>)</li>
</ul>
<p>The first two variants of the <code>boost_python</code> library are
built by default, and are compatible with the default Python
distribution. The <code>debug-python</code> variant corresponds to a
specially-built debugging version of Python. On *nix platforms, this
python is built by adding <code>--with-pydebug</code> when configuring
the Python build. On Windows, the debugging version of Python is
generated by the "Win32 Debug" target of the <code>PCBuild.dsw</code>
Visual C++ 6.0 project in the <code>PCBuild</code> subdirectory of your
Python distribution. Extension modules built with Python debugging
enabled are <b>not link-compatible</b> with a non-debug build of Python.
Since few people actually have a debug build of Python (it doesn't come
with the standard distribution), the normal <code>debug</code> variant
builds modules which are compatible with ordinary Python.</p>
<p>On many windows compilers, when extension modules are built with
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> linking with a special
debugging version of the Python DLL. Since this debug DLL isn't supplied
with the default Python installation for Windows, Boost.Python uses
<tt><a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
<tt>#include</tt>d - unless <code>BOOST_DEBUG_PYTHON</code> is
defined.</p>
<p>If you want the extra runtime checks available with the debugging
version of the library, <tt>#define BOOST_DEBUG_PYTHON</tt> to re-enable
python debuggin, and link with the <code>debug-python</code> variant of
<tt>boost_python</tt>.</p>
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that any
source files in your extension module <tt>#include&nbsp;&lt;<a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>&gt;</tt>
instead of the usual <tt>Python.h</tt>, or you will have link
incompatibilities.<br>
</p>
<h2><a name="VisualStudio">Building Using the Microsoft Visual Studio
IDE</a></h2>
<p>For the those of you who feel more comfortable in the IDE world, a
workspace and project file have been included in the <code>
libs/python/build/VisualStudio</code> subdirectory.
It builds release and debug versions of the Boost.Python libraries and
places them and the same directory as Jamfile build does, though the
intermediate object files are placed in a different directory. The files
have been created using Microsoft Visual C++ version 6, but they should
work for later versions as well. You will need to tell the IDE where to
find the Python <code>Include/</code> and <code>Libs/</code> directories.
Under <b>Tools&gt;Options&gt;Directories</b>, add an entry for the Python
include dir (i.e. <code>c:/Python22/Include</code>), and one for the Lib
(i.e. <code>c:/Python/Libs</code>. Make sure it is <code>Libs</code> with
an "<code>s</code>" and not just <code>Lib</code>).</p>
<h3>Using the IDE for your own projects</h3>
<p>Building your own projects using the IDE is slightly more complicated.
Firstly, you need to make sure that the project you create as the right
kind. It should be a "Win32 Dynamic-Link Library". The default one that
Visual Studio 6 creates needs some modifications: turn on RTTI, and
change the debug and release builds to use the respective debug and
release Multithreaded DLL versions. You should probably turn off
incremental linking too -- I believe it a bit flaky. If you do this, then
change the "Debug Info" to "Program Database" to get rid of the Edit and
Continue warning.</p>
<p>You'll need to add the Boost root directory under
<b>Tools&gt;Options&gt;Directories</b> to get your code compiling. To
make it link, add the above <code>boost_python.dsp</code> file to your
workspace, and make your project depend upon it (under
<b>Project&gt;Dependencies</b>). You should be able to build now.</p>
<p>Lastly, go to the <b>Project Settings&gt;Debug</b> Page and add the
<code>Python.exe</code> as the executable for the project. Set a startup
directory, and make sure that your current project's output dll, the
<code>boost_python.dll</code> and the <code>python22.dll</code> are on
the current <code>PATH</code>. If you have a python script that tests
your dll, then add it in the "Program Arguments". Now, if all went well,
you should be able to hit the Run (F5) button, and debug your code.</p>
<blockquote>
<em>The Visual Studio project files are graciously contributed and
maintained by <a href="mailto:brett.calcott@gmail.com">Brett
Calcott</a></em>.
</blockquote>
<hr>
<p>&copy; Copyright David Abrahams 2002-2004. Permission to copy,
use, modify, sell and distribute this document is granted provided
this copyright notice appears in all copies. This document is
provided ``as is'' without express or implied warranty, and with
no claim as to its suitability for any purpose.</p>
<p>Updated: 13 April 2004 (David Abrahams)</p>
</body>
</html>

View File

@@ -1,404 +0,0 @@
.. Copyright David Abrahams 2006. Distributed under the Boost
.. Software License, Version 1.0. (See accompanying
.. file LICENSE_1_0.txt or copy at
.. http://www.boost.org/LICENSE_1_0.txt)
==============================================
|(logo)|__ Boost.Python Build and Test HOWTO
==============================================
.. |(logo)| image:: ../boost.png
:alt: Boost C++ Libraries:
:class: boost-logo
__ ../index.htm
.. section-numbering::
:depth: 2
.. contents:: Contents
:depth: 2
:class: sidebar small
.. |newer| replace:: *newer*
Requirements
============
Boost.Python requires `Python 2.2`_ [#2.2]_ *or* |newer|__.
.. _Python 2.2: http://www.python.org/2.2
__ http://www.python.org
No-Install Quickstart
=====================
There is no need to install Boost in order to get started using
Boost.Python. These instructions use Boost.Build_ projects,
which will build those binaries as soon as they're needed. Your
first tests may take a little longer while you wait for
Boost.Python to build, but doing things this way will save you from
worrying about build intricacies like which library binaries to use
for a specific compiler configuration.
.. Note:: Of course it's possible to use other build systems to
build Boost.Python and its extensions, but they are not
officially supported by Boost. Moreover **99% of all “I can't
build Boost.Python” problems come from trying to use another
build system**.
If you want to use another system anyway, we suggest that you
follow these instructions, and then invoke ``bjam`` with the
``-a -o``\ *filename* option to dump the build commands it executes
to a file, so you can see what your build system needs to do.
1. Get Boost; see sections 1 and 2 of the Boost `Getting Started Guide`_.
2. Get the ``bjam`` build driver. See sections 5.2.1-5.2.3 of the
Boost `Getting Started Guide`_.
3. cd into the ``libs/python/test/example`` directory.
.. _Getting Started Guide: ../../../more/getting_started/index.html
Background
==========
There are two basic models for combining C++ and Python:
- extending_, in which the end-user launches the Python interpreter
executable and imports Python “extension modules” written in C++.
Think of taking a library written in C++ and giving it a Python
interface so Python programmers can use it. From Python, these
modules look just like regular Python modules.
- embedding_, in which the end-user launches a program written
in C++ that in turn invokes the Python interpreter as a library
subroutine. Think of adding scriptability to an existing
application.
.. _extending: http://www.python.org/doc/current/ext/intro.html
.. _embedding: http://www.python.org/doc/current/ext/embedding.html
The key distinction between extending and embedding is the location
of C++' ``main()`` function: in the Python interpreter executable,
or in some other program, respectively. Note that even when
embedding Python in another program, `extension modules are often
the best way to make C/C++ functionality accessible to Python
code`__, so the use of extension modules is really at the heart of
both models.
__ http://www.python.org/doc/current/ext/extending-with-embedding.html
Except in rare cases, extension modules are built as
dynamically-loaded libraries with a single entry point, which means
you can change them without rebuilding either the other extension
modules or the executable containing ``main()``.
Getting Boost.Python Binaries
=============================
Since Boost.Python is a separately-compiled (as opposed to
`header-only`_) library, its user relies on the services of a
Boost.Python library binary.
.. _header-only: ../../../more/getting_started/windows.html#header-only-libraries
Installing Boost.Python on your System
--------------------------------------
If you need a regular, installation of the Boost.Python library
binaries on your system, the Boost `Getting Started Guide`_ will
walk you through the steps of installing one. If building binaries
from source, you might want to supply the ``--with-python``
argument to ``bjam`` (or the ``--with-libraries=python`` argument
to ``configure``), so only the Boost.Python binary will be built,
rather than all the Boost binaries.
Configuring Boost.Build
=======================
As described in the `Boost.Build reference manual`__, a file called
``user-config.jam`` in your home
directory [#home-dir]_ is used to
describe the build resources available to the build system. You'll
need to tell it about your Python installation.
__ http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration
.. Admonition:: Users of Unix-Variant OSes
If you are using a unix-variant OS and you ran Boost's
``configure`` script, it may have generated a
``user-config.jam`` for you. [#overwrite]_ If your ``configure``\
/\ ``make`` sequence was successful and Boost.Python binaries
were built, your ``user-config.jam`` file is probably already
correct.
If you have a fairly “standard” python installation for your
platform, there's very little you need to do to describe it.
Simply having ::
import toolset : using ;
using python ;
in a ``user-config.jam`` file in your home directory [#home-dir]_
should be enough. [#user-config.jam]_ For more complicated setups,
see `Advanced Configuration`_.
.. Note:: You might want to pass the ``--debug-configuration``
option to ``bjam`` the first few times you invoke it, to make
sure that Boost.Build is correctly locating all the parts of
your Python installation. If it isn't, consider passing some of
the optional `Python configuration parameters`_ detailed below.
Building an Extension Module
============================
Testing
=======
Advanced Configuration
======================
If you have several versions of Python installed, or Python is
installed in an unusual way, you may want to supply any or all of
the following optional parameters to ``using python``.
Python Configuration Parameters
-------------------------------
version
the version of Python to use. Should be in Major.Minor
format, for example, ``2.3``. Do not include the subminor
version (i.e. *not* ``2.5.1``). If you have multiple Python
versions installed, the version will usually be the only
additional argument required.
cmd-or-prefix
preferably, a command that invokes a Python
interpreter. Alternatively, the installation prefix for Python
libraries and header files. Use the alternative formulation if
there is no appropriate Python executable available.
includes
the ``#include`` path for Python headers.
libraries
the path to Python library binaries. On MacOS/Darwin,
you can also pass the path of the Python framework.
condition
if specified, should be a set of Boost.Build
properties that are matched against the build configuration when
Boost.Build selects a Python configuration to use.
extension-suffix
A string to append to the name of extension
modules before the true filename extension. You almost certainly
don't need to use this. Usually this suffix is only used when
targeting a Windows debug build of Python, and will be set
automatically for you based on the value of the
``<python-debugging>`` feature. However, at least one Linux
distribution (Ubuntu Feisty Fawn) has a specially configured
`python-dbg`__ package that claims to use such a suffix.
__ https://wiki.ubuntu.com/PyDbgBuilds
Examples
--------
Note that in the examples below, case and *especially whitespace* are
significant.
- If you have both python 2.5 and python 2.4 installed,
``user-config.jam`` might contain::
using python : 2.5 ; # Make both versions of Python available
using python : 2.4 ; # To build with python 2.4, add python=2.4
# to your command line.
The first version configured (2.5) becomes the default. To build
against python 2.4, add ``python=2.4`` to the ``bjam`` command line.
- If you have python installed in an unusual location, you might
supply the path to the interpreter in the ``cmd-or-prefix``
parameter::
using python : : /usr/local/python-2.6-beta/bin/python ;
- If you have a separate build of Python for use with a particular
toolset, you might supply that toolset in the ``condition``
parameter::
using python ; # use for most toolsets
# Use with Intel C++ toolset
using python
: # version
: c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
: # includes
: # libraries
: <toolset>intel # condition
;
- You can set up your user-config.jam so a bjam built under Windows
can build/test both Windows and Cygwin_ python extensions. Just pass
``<target-os>cygwin`` in the ``condition`` parameter
for the cygwin python installation::
# windows installation
using python ;
# cygwin installation
using python : : c:\\cygwin\\bin\\python2.5 : : : <target-os>cygwin ;
when you put target-os=cygwin in your build request, it should build
with the cygwin version of python: [#flavor]_
bjam target-os=cygwin toolset=gcc
This is supposed to work the other way, too (targeting windows
python with a Cygwin_ bjam) but it seems as though the support in
Boost.Build's toolsets for building that way is broken at the
time of this writing.
- Note that because of `the way Boost.Build currently selects target
alternatives`__, you might have be very explicit in your build
requests. For example, given::
using python : 2.5 ; # a regular windows build
using python : 2.4 : : : : <target-os>cygwin ;
building with ::
bjam target-os=cygwin
will yield an error. Instead, you'll need to write::
bjam target-os=cygwin/python=2.4
.. _Cygwin: http://cygwin.com
__ http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection
Choosing a Boost.Python Library Binary
======================================
If—instead of letting Boost.Build construct and link withthe right
libraries automatically—you choose to use a pre-built Boost.Python
library, you'll need to think about which one to link with. The
Boost.Python binary comes in both static and dynamic flavors. Take
care to choose the right flavor for your application. [#naming]_
The Dynamic Binary
------------------
The dynamic library is the safest and most-versatile choice:
- A single copy of the library code is used by all extension
modules built with a given toolset. [#toolset-specific]_
- The library contains a type conversion registry. Because one
registry is shared among all extension modules, instances of a
class exposed to Python in one dynamically-loaded extension
module can be passed to functions exposed in another such module.
The Static Binary
-----------------
It might be appropriate to use the static Boost.Python library in
any of the following cases:
- You are extending_ python and the types exposed in your
dynamically-loaded extension module don't need to be used by any
other Boost.Python extension modules, and you don't care if the
core library code is duplicated among them.
- You are embedding_ python in your application and either:
- You are targeting a Unix variant OS other than MacOS or AIX,
where the dynamically-loaded extension modules can “see” the
Boost.Python library symbols that are part of the executable.
- Or, you have statically linked some Boost.Python extension
modules into your application and you don't care if any
dynamically-loaded Boost.Python extension modules are able to
use the types exposed by your statically-linked extension
modules (and vice-versa).
Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users
=======================================================
If you are using a version of Python prior to 2.4.1 with a MinGW
prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will need to
create a MinGW-compatible version of the Python library; the one
shipped with Python will only work with a Microsoft-compatible
linker. Follow the instructions in the “Non-Microsoft” section of
the “Building Extensions: Tips And Tricks” chapter in `Installing
Python Modules`__ to create ``libpythonXX.a``, where ``XX``
corresponds to the major and minor version numbers of your Python
installation.
__ http://www.python.org/doc/current/inst/index.html
-----------------------------
.. [#2.2] Note that although we tested earlier versions of
Boost.Python with Python 2.2, and we don't *think* we've done
anything to break compatibility, this release of Boost.Python
may not have been tested with versions of Python earlier than
2.4, so we're not 100% sure that python 2.2 and 2.3 are
supported.
.. [#naming] Information about how to identify the
static and dynamic builds of Boost.Python:
* `on Windows`__
* `on Unix variants`__
__ ../../../more/getting_started/windows.html#library-naming
__ ../../../more/getting_started/unix-variants.html#library-naming
Be sure to read this section even if your compiler supports
auto-linking, as Boost.Python does not yet take advantage of
that feature.
.. [#toolset-specific] Because of the way most \*nix platforms
share symbols among dynamically-loaded objects, I'm not
certainextension modules built with different compiler toolsets
will always use different copies of the Boost.Python library
when loaded into the same Python instance. Not using different
libraries could be a good thing if the compilers have compatible
ABIs, because extension modules built with the two libraries
would be interoperable. Otherwise, it could spell disaster,
since an extension module and the Boost.Python library would
have different ideas of such things as class layout. I would
appreciate someone doing the experiment to find out what
happens.
.. [#overwrite] ``configure`` overwrites the existing
``user-config.jam`` in your home directory
(if any) after making a backup of the old version.
.. [#flavor] Note that the ``<target-os>cygwin`` feature is
different from the ``<flavor>cygwin`` subfeature of the ``gcc``
toolset, and you might need handle both explicitly if you also
have a MinGW GCC installed.
.. [#user-config.jam] Create the ``user-config.jam`` file if you don't
already have one.
.. [#home-dir] Windows users, your home directory can be
found by typing::
ECHO %HOMEDRIVE%%HOMEPATH%
into a `Windows command prompt`__
__ ../../../more/getting_started/windows.html#or-build-from-the-command-prompt

View File

@@ -32,43 +32,7 @@
<hr>
<dl class="page-index">
<dt>Current SVN</dt>
<dd>
<ul>
<li>Pythonic signatures are now automatically appended to the
docstrings.
<li>Use <a href="v2/docstring_options.html"
><code>docstring_options.hpp</code></a> header
control the content of docstrings.
<li>This new feature increases the size of the modules by about 14%.
If this is not acceptable it can be turned off by defining the macro
BOOST_PYTHON_NO_PY_SIGNATURES. Modules compiled with and without the macro
defined are compatible.
</li>
<li> If BOOST_PYTHON_NO_PY_SIGNATURES is undefined, this version defines the
macro BOOST_PYTHON_SUPPORTS_PY_SIGNATURES. This allows writing code that will compile
with older version of Boost.Python (see <a href="v2/pytype_function.html#examples">here</a>).
</li>
<li>By defining BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE, and at a cost
of another 14% size increase, proper pythonic type is generated for the "self"
parameter of the __init__ methods.
</li>
<li> To support this new feature changes were made to the
<a href="v2/to_python_converter.html"><code>to_python_converter.hpp</code></a>,
<a href="v2/default_call_policies.html"><code>default_call_policies</code></a>,
<a href="v2/ResultConverter.html"><code>ResultConverter</code></a>,
<a href="v2/CallPolicies.html"><code>CallPolicies</code></a> and some others.
Efforts were made not to have interface breaking changes.
</li>
</ul>
</dd>
<dt>12 May 2007 - 1.34.0 release</dt>
<dt>Current CVS</dt>
<dd>
<ul>

View File

@@ -1,11 +1,14 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter 1. python 1.0</title>
<link rel="stylesheet" href="boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="index.html" title="Chapter 1. python 1.0">
<link rel="next" href="python/hello.html" title="Building Hello World">
<link rel="next" href="python/hello.html" title=" Building Hello World">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
@@ -31,7 +34,7 @@
<div><p class="copyright">Copyright © 2002-2005 Joel
de Guzman, David Abrahams</p></div>
<div><div class="legalnotice">
<a name="id2632684"></a><p>
<a name="id376848"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
http://www.boost.org/LICENSE_1_0.txt </a>)
@@ -93,10 +96,10 @@
code takes on the look of a kind of declarative interface definition language
(IDL).
</p>
<a name="quickstart.hello_world"></a><h3>
<a name="id2595112"></a>
<a name="quickstart.hello_world"></a><h2>
<a name="id447173"></a>
Hello World
</h3>
</h2>
<p>
Following C/C++ tradition, let's start with the "hello, world". A
C++ Function:
@@ -132,20 +135,14 @@
</pre>
<p>
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World
module from start to finish...</strong></span></em></span>
</p>
<p>
</p>
</blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World module
from start to finish...</b></span></em></span>
</p></blockquote></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><small><p>Last revised: May 18, 2007 at 15:46:01 GMT</p></small></td>
<td align="left"><small><p>Last revised: August 31, 2006 at 05:59:58 GMT</p></small></td>
<td align="right"><small></small></td>
</tr></table>
<hr>

View File

@@ -1,12 +1,15 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Embedding</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="object.html" title="Object Interface">
<link rel="prev" href="object.html" title=" Object Interface">
<link rel="next" href="iterators.html" title="Iterators">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -39,28 +42,30 @@
a lot easier and, in a future version, it may become unnecessary to touch the
Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
</p>
<a name="embedding.building_embedded_programs"></a><h3>
<a name="id2654982"></a>
<a name="embedding.building_embedded_programs"></a><h2>
<a name="id462650"></a>
Building embedded programs
</h3>
</h2>
<p>
To be able to embed python into your programs, you have to link to both Boost.Python's
as well as Python's own runtime library.
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.
</p>
<p>
Boost.Python's library comes in two variants. Both are located in Boost's
<code class="literal">/libs/python/build/bin-stage</code> subdirectory. On Windows, the
variants are called <code class="literal">boost_python.lib</code> (for release builds)
and <code class="literal">boost_python_debug.lib</code> (for debugging). If you can't
find the libraries, you probably haven't built Boost.Python yet. See <a href="../../../../building.html" target="_top">Building and Testing</a> on how to do this.
Boost.Python's static link library comes in two variants. Both are located
in Boost's <tt class="literal">/libs/python/build/bin-stage</tt> subdirectory. On
Windows, the variants are called <tt class="literal">boost_python.lib</tt> (for release
builds) and <tt class="literal">boost_python_debug.lib</tt> (for debugging). If you
can't find the libraries, you probably haven't built Boost.Python yet. See
<a href="../../../../building.html" target="_top">Building and Testing</a> on how to
do this.
</p>
<p>
Python's library can be found in the <code class="literal">/libs</code> subdirectory
Python's static link library can be found in the <tt class="literal">/libs</tt> subdirectory
of your Python directory. On Windows it is called pythonXY.lib where X.Y is
your major Python version number.
</p>
<p>
Additionally, Python's <code class="literal">/include</code> subdirectory has to be added
Additionally, Python's <tt class="literal">/include</tt> subdirectory has to be added
to your include path.
</p>
<p>
@@ -81,171 +86,295 @@ exe embedded_program # name of the executable
&lt;library-path&gt;$(PYTHON_LIB_PATH)
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</pre>
<a name="embedding.getting_started"></a><h3>
<a name="id2655076"></a>
<a name="embedding.getting_started"></a><h2>
<a name="id462747"></a>
Getting started
</h3>
</h2>
<p>
Being able to build is nice, but there is nothing to build yet. Embedding the
Python interpreter into one of your C++ programs requires these 4 steps:
</p>
<div class="orderedlist"><ol type="1">
<li>
#include <code class="literal">&lt;boost/python.hpp&gt;</code><br><br>
#include <tt class="literal">&lt;boost/python.hpp&gt;</tt><br><br>
</li>
<li>
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
to start the interpreter and create the <code class="literal"><span class="underline">_main</span>_</code>
to start the interpreter and create the <tt class="literal"><span class="underline">_main</span>_</tt>
module.<br><br>
</li>
<li>
Call other Python C API routines to use the interpreter.<br><br>
</li>
<li>
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
to stop the interpreter and release its resources.
</li>
</ol></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Note that at this time you must
not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
to stop the interpreter. This may be fixed in a future version of boost.python.</strong></span>
</p>
</div>
<p>
(Of course, there can be other C++ code between all of these steps.)
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="emphasis"><em><span class="bold"><strong>Now that we can embed the interpreter in
our programs, lets see how to put it to use...</strong></span></em></span>
</p>
<p>
</p>
</blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em><span class="bold"><b>Now that we can embed the interpreter in
our programs, lets see how to put it to use...</b></span></em></span>
</p></blockquote></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
<p>
As you probably already know, objects in Python are reference-counted. Naturally,
the <code class="literal">PyObject</code>s of the Python/C API are also reference-counted.
the <tt class="literal">PyObject</tt>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<span class="emphasis"><em>C API requires you to do it [@http:</em></span>/www.python.org/doc/current/api/refcounts.html
by hand]. This is messy and especially hard to get right in the presence
in Python, the Python/C API requires you to do it <a href="http://www.python.org/doc/current/api/refcounts.html" target="_top">by
hand</a>. This is messy and especially hard to get right in the presence
of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
automate the process.
</p>
<a name="using_the_interpreter.running_python_code"></a><h3>
<a name="id2655255"></a>
Running Python code
</h3>
<a name="using_the_interpreter.reference_counting_handles_and_objects"></a><h2>
<a name="id462914"></a>
Reference-counting handles and objects
</h2>
<p>
Boost.python provides three related functions to run Python code from C++.
There are two ways in which a function in the Python/C API can return a
<tt class="literal">PyObject*</tt>: as a <span class="emphasis"><em>borrowed reference</em></span>
or as a <span class="emphasis"><em>new reference</em></span>. 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.
</p>
<p>
For a function returning a <span class="emphasis"><em>borrowed reference</em></span> we'll
have to tell the <tt class="literal">handle</tt> that the <tt class="literal">PyObject*</tt>
is borrowed with the aptly named <a href="../../../../v2/handle.html#borrowed-spec" target="_top">borrowed</a>
function. Two functions returning borrowed references are <a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a>
and <a href="http://www.python.org/doc/current/api/moduleObjects.html#l2h-594" target="_top">PyModule_GetDict</a>.
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 <tt class="literal"><span class="underline">_main</span>_</tt>
module:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
<span class="identifier">object</span> <span class="identifier">exec</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">code</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
<span class="identifier">object</span> <span class="identifier">exec_file</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">filename</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
<span class="identifier">object</span> <span class="identifier">main_module</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><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span>
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
</pre>
<p>
eval evaluates the given expression and returns the resulting value. exec
executes the given code (typically a set of statements) returning the result,
and exec_file executes the code contained in the given file.
For a function returning a <span class="emphasis"><em>new reference</em></span> we can just
create a <tt class="literal">handle</tt> out of the raw <tt class="literal">PyObject*</tt>
without wrapping it in a call to borrowed. One such function that returns
a new reference is <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
which we'll discuss in the next section.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Handle is a class <span class="emphasis"><em>template</em></span>,
so why haven't we been using any template parameters?</b></span><br> <br>
<tt class="literal">handle</tt> has a single template parameter specifying the
type of the managed object. This type is <tt class="literal">PyObject</tt> 99%
of the time, so the parameter was defaulted to <tt class="literal">PyObject</tt>
for convenience. Therefore we can use the shorthand <tt class="literal">handle&lt;&gt;</tt>
instead of the longer, but equivalent, <tt class="literal">handle&lt;PyObject&gt;</tt>.
</p>
<a name="using_the_interpreter.running_python_code"></a><h2>
<a name="id463241"></a>
Running Python code
</h2>
<p>
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 <a href="http://www.python.org/doc/current/api/veryhigh.html" target="_top">here</a>. They
all work similarly so we will look at only one of them, namely:
</p>
<pre class="programlisting">
<span class="identifier">PyObject</span><span class="special">*</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">globals</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">locals</span><span class="special">)</span>
</pre>
<p>
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
takes the code to execute as a null-terminated (C-style) string in its <tt class="literal">str</tt>
parameter. The function returns a new reference to a Python object. Which
object is returned depends on the <tt class="literal">start</tt> paramater.
</p>
<p>
The <code class="literal">globals</code> and <code class="literal">locals</code> parameters are
Python dictionaries containing the globals and locals of the context in which
to run the code. For most intents and purposes you can use the namespace
dictionary of the <code class="literal"><span class="underline">_main</span>_</code>
The <tt class="literal">start</tt> parameter is the start symbol from the Python
grammar to use for interpreting the code. The possible values are:
</p>
<div class="informaltable">
<h4>
<a name="id463420"></a>
<span class="table-title">Start symbols</span>
</h4>
<table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a></th>
<th>for
interpreting isolated expressions</th>
</tr></thead>
<tbody>
<tr>
<td><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a></td>
<td>for
interpreting sequences of statements</td>
</tr>
<tr>
<td><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60" target="_top">Py_single_input</a></td>
<td>for
interpreting a single statement</td>
</tr>
</tbody>
</table>
</div>
<p>
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>,
the input string must contain a single expression and its result is returned.
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>,
the string can contain an abitrary number of statements and None is returned.
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60" target="_top">Py_single_input</a>
works in the same way as <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
but only accepts a single statement.
</p>
<p>
Lastly, the <tt class="literal">globals</tt> and <tt class="literal">locals</tt> 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 <tt class="literal"><span class="underline">_main</span>_</tt>
module for both parameters.
</p>
<p>
Boost.python provides a function to import a module:
We have already seen how to get the <tt class="literal"><span class="underline">_main</span>_</tt>
module's namespace so let's run some Python code in it:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
</pre>
<p>
import imports a python module (potentially loading it into the running process
first), and returns it.
</p>
<p>
Let's import the <code class="literal"><span class="underline">_main</span>_</code>
module and run some Python code in its namespace:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">main_module</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><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span>
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"hello = file('hello.txt', 'w')\n"</span>
<span class="string">"hello.write('Hello world!')\n"</span>
<span class="string">"hello.close()"</span><span class="special">,</span>
<span class="identifier">main_namespace</span><span class="special">);</span>
<span class="identifier">handle</span><span class="special">&lt;&gt;</span> <span class="identifier">ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
<span class="string">"hello = file('hello.txt', 'w')\n"</span>
<span class="string">"hello.write('Hello world!')\n"</span>
<span class="string">"hello.close()"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
<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="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</span>
<span class="special">));</span>
</pre>
<p>
Because the Python/C API doesn't know anything about <tt class="literal">object</tt>s,
we used the object's <tt class="literal">ptr</tt> member function to retrieve the
<tt class="literal">PyObject*</tt>.
</p>
<p>
This should create a file called 'hello.txt' in the current directory containing
a phrase that is well-known in programming circles.
</p>
<a name="using_the_interpreter.manipulating_python_objects"></a><h3>
<a name="id2655783"></a>
Manipulating Python objects
</h3>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that we wrap
the return value of <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
in a (nameless) <tt class="literal">handle</tt> 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 <tt class="literal">PyObject*</tt>s
in <tt class="literal">handle</tt>s.
</p>
<a name="using_the_interpreter.beyond_handles"></a><h2>
<a name="id463926"></a>
Beyond handles
</h2>
<p>
Often we'd like to have a class to manipulate Python objects. But we have
already seen such a class above, and in the <a href="object.html" target="_top">previous
section</a>: the aptly named <code class="literal">object</code> class and its
derivatives. We've already seen that they can be constructed from a <code class="literal">handle</code>.
It's nice that <tt class="literal">handle</tt> 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 above, and in the <a href="object.html" target="_top">previous section</a>:
the aptly named <tt class="literal">object</tt> class and it's derivatives. We've
already seen that they can be constructed from a <tt class="literal">handle</tt>.
The following examples should further illustrate this fact:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">main_module</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><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span>
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"result = 5 ** 2"</span><span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">);</span>
<span class="identifier">handle</span><span class="special">&lt;&gt;</span> <span class="identifier">ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
<span class="string">"result = 5 ** 2"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
<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="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</span>
<span class="special">));</span>
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">main_namespace</span><span class="special">[</span><span class="string">"result"</span><span class="special">]);</span>
</pre>
<p>
Here we create a dictionary object for the <code class="literal"><span class="underline">_main</span>_</code>
Here we create a dictionary object for the <tt class="literal"><span class="underline">_main</span>_</tt>
module's namespace. Then we assign 5 squared to the result variable and read
this variable from the dictionary. Another way to achieve the same result
is to use eval instead, which returns the result directly:
is to let <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
return the result directly with <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span>
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">"5 ** 2"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
<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="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</span>
<span class="special">));</span>
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
</pre>
<a name="using_the_interpreter.exception_handling"></a><h3>
<a name="id2656116"></a>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that <tt class="literal">object</tt>'s
member function to return the wrapped <tt class="literal">PyObject*</tt> is called
<tt class="literal">ptr</tt> instead of <tt class="literal">get</tt>. This makes sense
if you take into account the different functions that <tt class="literal">object</tt>
and <tt class="literal">handle</tt> perform.
</p>
<a name="using_the_interpreter.exception_handling"></a><h2>
<a name="id464549"></a>
Exception handling
</h3>
</h2>
<p>
If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
is thrown:
If an exception occurs in the execution of some Python code, the <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
function returns a null pointer. Constructing a <tt class="literal">handle</tt>
out of this null pointer throws <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>,
so basically, the Python exception is automatically translated into a C++
exception when using <tt class="literal">handle</tt>:
</p>
<pre class="programlisting">
<span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
<span class="string">"5/0"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
<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="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</span>
<span class="special">));</span>
<span class="comment">// execution will never get here:
</span> <span class="keyword">int</span> <span class="identifier">five_divided_by_zero</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// handle the exception in some way
</span><span class="special">}</span>
</pre>
<p>
The <code class="literal">error_already_set</code> exception class doesn't carry any
The <tt class="literal">error_already_set</tt> exception class doesn't carry any
information in itself. To find out more about the Python exception that occurred,
you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
handling functions</a> of the Python<span class="emphasis"><em>C API in your catch-statement.
This can be as simple as calling [@http:</em></span>/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 <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
handling functions</a> of the Python/C API in your catch-statement. This
can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
to print the exception's traceback to the console, or comparing the type
of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
exceptions</a>:
</p>
<pre class="programlisting">
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span>
<span class="special">{</span>
@@ -262,6 +391,23 @@ exe embedded_program # name of the executable
(To retrieve even more information from the exception you can use some of
the other exception handling functions listed <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">here</a>.)
</p>
<p>
If you'd rather not have <tt class="literal">handle</tt> throw a C++ exception
when it is constructed, you can use the <a href="../../../../v2/handle.html#allow_null-spec" target="_top">allow_null</a>
function in the same way you'd use borrowed:
</p>
<pre class="programlisting">
<span class="identifier">handle</span><span class="special">&lt;&gt;</span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">allow_null</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
<span class="string">"5/0"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
<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="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))));</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">result</span><span class="special">)</span>
<span class="comment">// Python exception occurred
</span><span class="keyword">else</span>
<span class="comment">// everything went okay, it's safe to use the result
</span></pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>

View File

@@ -1,13 +1,16 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Exception Translation</title>
<title> Exception Translation</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="iterators.html" title="Iterators">
<link rel="next" href="techniques.html" title="General Techniques">
<link rel="next" href="techniques.html" title=" General Techniques">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">

View File

@@ -1,12 +1,15 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Exposing Classes</title>
<title> Exposing Classes</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="hello.html" title="Building Hello World">
<link rel="prev" href="hello.html" title=" Building Hello World">
<link rel="next" href="functions.html" title="Functions">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -64,9 +67,9 @@
<span class="special">}</span>
</pre>
<p>
Here, we wrote a C++ class wrapper that exposes the member functions <code class="literal">greet</code>
and <code class="literal">set</code>. Now, after building our module as a shared library,
we may use our class <code class="literal">World</code> in Python. Here's a sample Python
Here, we wrote a C++ class wrapper that exposes the member functions <tt class="literal">greet</tt>
and <tt class="literal">set</tt>. Now, after building our module as a shared library,
we may use our class <tt class="literal">World</tt> in Python. Here's a sample Python
session:
</p>
<p>
@@ -82,7 +85,7 @@
<div class="titlepage"><div><div><h3 class="title">
<a name="python.constructors"></a>Constructors</h3></div></div></div>
<p>
Our previous example didn't have any explicit constructors. Since <code class="literal">World</code>
Our previous example didn't have any explicit constructors. Since <tt class="literal">World</tt>
is declared as a plain struct, it has an implicit default constructor. Boost.Python
exposes the default constructor by default, which is why we were able to
write
@@ -106,9 +109,9 @@
<span class="special">};</span>
</pre>
<p>
This time <code class="literal">World</code> has no default constructor; our previous
This time <tt class="literal">World</tt> has no default constructor; our previous
wrapping code would fail to compile when the library tried to expose it.
We have to tell <code class="literal">class_&lt;World&gt;</code> about the constructor
We have to tell <tt class="literal">class_&lt;World&gt;</tt> about the constructor
we want to expose instead.
</p>
<pre class="programlisting">
@@ -124,13 +127,13 @@
<span class="special">}</span>
</pre>
<p>
<code class="literal">init&lt;std::string&gt;()</code> exposes the constructor taking
in a <code class="literal">std::string</code> (in Python, constructors are spelled
"<code class="literal">"<span class="underline">_init</span>_"</code>").
<tt class="literal">init&lt;std::string&gt;()</tt> exposes the constructor taking
in a <tt class="literal">std::string</tt> (in Python, constructors are spelled
"<tt class="literal">"<span class="underline">_init</span>_"</tt>").
</p>
<p>
We can expose additional constructors by passing more <code class="literal">init&lt;...&gt;</code>s
to the <code class="literal">def()</code> member function. Say for example we have
We can expose additional constructors by passing more <tt class="literal">init&lt;...&gt;</tt>s
to the <tt class="literal">def()</tt> member function. Say for example we have
another World constructor taking in two doubles:
</p>
<pre class="programlisting">
@@ -142,13 +145,13 @@
</pre>
<p>
On the other hand, if we do not wish to expose any constructors at all, we
may use <code class="literal">no_init</code> instead:
may use <tt class="literal">no_init</tt> instead:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Abstract</span><span class="special">&gt;(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
</pre>
<p>
This actually adds an <code class="literal"><span class="underline">_init</span>_</code>
This actually adds an <tt class="literal"><span class="underline">_init</span>_</tt>
method which always raises a Python RuntimeError exception.
</p>
</div>
@@ -158,8 +161,8 @@
<p>
Data members may also be exposed to Python so that they can be accessed as
attributes of the corresponding Python class. Each data member that we wish
to be exposed may be regarded as <span class="bold"><strong>read-only</strong></span>
or <span class="bold"><strong>read-write</strong></span>. Consider this class <code class="literal">Var</code>:
to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
or <span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Var</span>
@@ -170,7 +173,7 @@
<span class="special">};</span>
</pre>
<p>
Our C++ <code class="literal">Var</code> class and its data members can be exposed
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
to Python:
</p>
<pre class="programlisting">
@@ -191,8 +194,8 @@
<span class="identifier">pi</span> <span class="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
</pre>
<p>
Note that <code class="literal">name</code> is exposed as <span class="bold"><strong>read-only</strong></span>
while <code class="literal">value</code> is exposed as <span class="bold"><strong>read-write</strong></span>.
Note that <tt class="literal">name</tt> is exposed as <span class="bold"><b>read-only</b></span>
while <tt class="literal">value</tt> is exposed as <span class="bold"><b>read-write</b></span>.
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
@@ -224,7 +227,7 @@
<p>
However, in Python attribute access is fine; it doesn't neccessarily break
encapsulation to let users handle attributes directly, because the attributes
can just be a different syntax for a method call. Wrapping our <code class="literal">Num</code>
can just be a different syntax for a method call. Wrapping our <tt class="literal">Num</tt>
class using Boost.Python:
</p>
<pre class="programlisting">
@@ -245,8 +248,8 @@
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span> <span class="special">=</span> <span class="number">2.17</span> <span class="comment"># error!
</span></pre>
<p>
Take note that the class property <code class="literal">rovalue</code> is exposed as
<span class="bold"><strong>read-only</strong></span> since the <code class="literal">rovalue</code>
Take note that the class property <tt class="literal">rovalue</tt> is exposed as
<span class="bold"><b>read-only</b></span> since the <tt class="literal">rovalue</tt>
setter member function is not passed in:
</p>
<p>
@@ -273,7 +276,7 @@
<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
</pre>
<p>
And a set of C++ functions operating on <code class="literal">Base</code> and <code class="literal">Derived</code>
And a set of C++ functions operating on <tt class="literal">Base</tt> and <tt class="literal">Derived</tt>
object instances:
</p>
<pre class="programlisting">
@@ -282,7 +285,7 @@
<span class="identifier">Base</span><span class="special">*</span> <span class="identifier">factory</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">Derived</span><span class="special">;</span> <span class="special">}</span>
</pre>
<p>
We've seen how we can wrap the base class <code class="literal">Base</code>:
We've seen how we can wrap the base class <tt class="literal">Base</tt>:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
@@ -290,8 +293,8 @@
<span class="special">;</span>
</pre>
<p>
Now we can inform Boost.Python of the inheritance relationship between <code class="literal">Derived</code>
and its base class <code class="literal">Base</code>. Thus:
Now we can inform Boost.Python of the inheritance relationship between <tt class="literal">Derived</tt>
and its base class <tt class="literal">Base</tt>. Thus:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"Derived"</span><span class="special">)</span>
@@ -307,15 +310,15 @@
member functions)
</li>
<li>
<span class="bold"><strong>If</strong></span> Base is polymorphic, <code class="literal">Derived</code>
<span class="bold"><b>If</b></span> Base is polymorphic, <tt class="literal">Derived</tt>
objects which have been passed to Python via a pointer or reference to
<code class="literal">Base</code> can be passed where a pointer or reference to
<code class="literal">Derived</code> is expected.
<tt class="literal">Base</tt> can be passed where a pointer or reference to
<tt class="literal">Derived</tt> is expected.
</li>
</ol></div>
<p>
Now, we shall expose the C++ free functions <code class="literal">b</code> and <code class="literal">d</code>
and <code class="literal">factory</code>:
Now, we shall expose the C++ free functions <tt class="literal">b</tt> and <tt class="literal">d</tt>
and <tt class="literal">factory</tt>:
</p>
<pre class="programlisting">
<span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
@@ -323,11 +326,11 @@
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
</pre>
<p>
Note that free function <code class="literal">factory</code> is being used to generate
new instances of class <code class="literal">Derived</code>. In such cases, we use
<code class="literal">return_value_policy&lt;manage_new_object&gt;</code> to instruct
Python to adopt the pointer to <code class="literal">Base</code> and hold the instance
in a new Python <code class="literal">Base</code> object until the the Python object
Note that free function <tt class="literal">factory</tt> is being used to generate
new instances of class <tt class="literal">Derived</tt>. In such cases, we use
<tt class="literal">return_value_policy&lt;manage_new_object&gt;</tt> to instruct
Python to adopt the pointer to <tt class="literal">Base</tt> and hold the instance
in a new Python <tt class="literal">Base</tt> object until the the Python object
is destroyed. We shall see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
policies</a> later.
</p>
@@ -343,7 +346,7 @@
<p>
In this section, we shall learn how to make functions behave polymorphically
through virtual functions. Continuing our example, let us add a virtual function
to our <code class="literal">Base</code> class:
to our <tt class="literal">Base</tt> class:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
@@ -356,11 +359,11 @@
One of the goals of Boost.Python is to be minimally intrusive on an existing
C++ design. In principle, it should be possible to expose the interface for
a 3rd party library without changing it. It is not ideal to add anything
to our class <code class="computeroutput"><span class="identifier">Base</span></code>. Yet, when
to our class <tt class="computeroutput"><span class="identifier">Base</span></tt>. Yet, when
you have a virtual function that's going to be overridden in Python and called
polymorphically <span class="bold"><strong>from C++</strong></span>, we'll need to
polymorphically <span class="bold"><b>from C++</b></span>, we'll need to
add some scaffoldings to make things work properly. What we'll do is write
a class wrapper that derives from <code class="computeroutput"><span class="identifier">Base</span></code>
a class wrapper that derives from <tt class="computeroutput"><span class="identifier">Base</span></tt>
that will unintrusively hook into the virtual functions so that a Python
override may be called:
</p>
@@ -374,25 +377,21 @@
<span class="special">};</span>
</pre>
<p>
Notice too that in addition to inheriting from <code class="computeroutput"><span class="identifier">Base</span></code>,
we also multiply- inherited <code class="computeroutput"><span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span></code> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
The <code class="computeroutput"><span class="identifier">wrapper</span></code> template makes
Notice too that in addition to inheriting from <tt class="computeroutput"><span class="identifier">Base</span></tt>,
we also multiply- inherited <tt class="computeroutput"><span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span></tt> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
The <tt class="computeroutput"><span class="identifier">wrapper</span></tt> template makes
the job of wrapping classes that are meant to overridden in Python, easier.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write <code class="computeroutput"><span class="identifier">f</span></code> as:<br> <br> <code class="computeroutput"><span class="keyword">return</span>
<span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></code>.
</p>
</div>
<p>
BaseWrap's overridden virtual member function <code class="computeroutput"><span class="identifier">f</span></code>
in effect calls the corresponding method of the Python object through <code class="computeroutput"><span class="identifier">get_override</span></code>.
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write <tt class="computeroutput"><span class="identifier">f</span></tt> as:<br> <br> <tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></tt>.
</p>
<p>
Finally, exposing <code class="computeroutput"><span class="identifier">Base</span></code>:
BaseWrap's overridden virtual member function <tt class="computeroutput"><span class="identifier">f</span></tt>
in effect calls the corresponding method of the Python object through <tt class="computeroutput"><span class="identifier">get_override</span></tt>.
</p>
<p>
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
@@ -400,25 +399,22 @@
<span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">pure_virtual</span></code> signals Boost.Python
that the function <code class="computeroutput"><span class="identifier">f</span></code> is a
<tt class="computeroutput"><span class="identifier">pure_virtual</span></tt> signals Boost.Python
that the function <tt class="computeroutput"><span class="identifier">f</span></tt> is a
pure virtual function.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>member function and methods</strong></span><br>
<br> Python, like many object oriented languages uses the term <span class="bold"><strong>methods</strong></span>. Methods correspond roughly to C++'s <span class="bold"><strong>member functions</strong></span>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>member function and methods</b></span><br>
<br> Python, like many object oriented languages uses the term <span class="bold"><b>methods</b></span>. Methods correspond roughly to C++'s <span class="bold"><b>member functions</b></span>
</p>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.virtual_functions_with_default_implementations"></a>Virtual Functions with Default Implementations</h3></div></div></div>
<p>
We've seen in the previous section how classes with pure virtual functions
are wrapped using Boost.Python's <a href="../../../../v2/wrapper.html" target="_top">class
wrapper</a> facilities. If we wish to wrap <span class="bold"><strong>non</strong></span>-pure-virtual
wrapper</a> facilities. If we wish to wrap <span class="bold"><b>non</b></span>-pure-virtual
functions instead, the mechanism is a bit different.
</p>
<p>
@@ -433,8 +429,8 @@
<span class="special">};</span>
</pre>
<p>
had a pure virtual function <code class="literal">f</code>. If, however, its member
function <code class="literal">f</code> was not declared as pure virtual:
had a pure virtual function <tt class="literal">f</tt>. If, however, its member
function <tt class="literal">f</tt> was not declared as pure virtual:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
@@ -460,19 +456,15 @@
<span class="special">};</span>
</pre>
<p>
Notice how we implemented <code class="computeroutput"><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">f</span></code>. Now,
we have to check if there is an override for <code class="computeroutput"><span class="identifier">f</span></code>.
If none, then we call <code class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></code>.
Notice how we implemented <tt class="computeroutput"><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">f</span></tt>. Now,
we have to check if there is an override for <tt class="computeroutput"><span class="identifier">f</span></tt>.
If none, then we call <tt class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></tt>.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to rewrite
the line with the <code class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></code> as:<br> <br> <code class="computeroutput"><span class="keyword">return</span>
<span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></code>.
the line with the <tt class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></tt> as:<br> <br> <tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></tt>.
</p>
</div>
<p>
Finally, exposing:
</p>
@@ -482,10 +474,10 @@
<span class="special">;</span>
</pre>
<p>
Take note that we expose both <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></code> and <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span></code>. Boost.Python needs to keep track
of 1) the dispatch function <code class="literal">f</code> and 2) the forwarding function
to its default implementation <code class="literal">default_f</code>. There's a special
<code class="literal">def</code> function for this purpose.
Take note that we expose both <tt class="computeroutput"><span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></tt> and <tt class="computeroutput"><span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span></tt>. Boost.Python needs to keep track
of 1) the dispatch function <tt class="literal">f</tt> and 2) the forwarding function
to its default implementation <tt class="literal">default_f</tt>. There's a special
<tt class="literal">def</tt> function for this purpose.
</p>
<p>
In Python, the results would be as expected:
@@ -501,14 +493,14 @@
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span> <span class="special">=</span> <span class="identifier">Derived</span><span class="special">()</span>
</pre>
<p>
Calling <code class="literal">base.f()</code>:
Calling <tt class="literal">base.f()</tt>:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
<span class="number">0</span>
</pre>
<p>
Calling <code class="literal">derived.f()</code>:
Calling <tt class="literal">derived.f()</tt>:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
@@ -518,17 +510,17 @@
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
<a name="class_operators_special_functions.python_operators"></a><h3>
<a name="id2646169"></a>
<a name="class_operators_special_functions.python_operators"></a><h2>
<a name="id453009"></a>
Python Operators
</h3>
</h2>
<p>
C is well known for the abundance of operators. C++ extends this to the extremes
by allowing operator overloading. Boost.Python takes advantage of this and
makes it easy to wrap C++ operator-powered classes.
</p>
<p>
Consider a file position class <code class="literal">FilePos</code> and a set of operators
Consider a file position class <tt class="literal">FilePos</tt> and a set of operators
that take on FilePos instances:
</p>
<p>
@@ -561,16 +553,16 @@
<p>
The code snippet above is very clear and needs almost no explanation at all.
It is virtually the same as the operators' signatures. Just take note that
<code class="literal">self</code> refers to FilePos object. Also, not every class
<code class="literal">T</code> that you might need to interact with in an operator
expression is (cheaply) default-constructible. You can use <code class="literal">other&lt;T&gt;()</code>
in place of an actual <code class="literal">T</code> instance when writing "self
<tt class="literal">self</tt> refers to FilePos object. Also, not every class
<tt class="literal">T</tt> that you might need to interact with in an operator
expression is (cheaply) default-constructible. You can use <tt class="literal">other&lt;T&gt;()</tt>
in place of an actual <tt class="literal">T</tt> instance when writing "self
expressions".
</p>
<a name="class_operators_special_functions.special_methods"></a><h3>
<a name="id2646853"></a>
<a name="class_operators_special_functions.special_methods"></a><h2>
<a name="id453761"></a>
Special Methods
</h3>
</h2>
<p>
Python has a few more <span class="emphasis"><em>Special Methods</em></span>. Boost.Python
supports all of the standard special method names supported by real Python
@@ -596,17 +588,14 @@
<p>
Need we say more?
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> What is the business of <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>? Well, the method <code class="computeroutput"><span class="identifier">str</span></code>
requires the <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>
to do its work (i.e. <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code> is used by the method defined by
<code class="computeroutput"><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span></code>.
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> What is the business of <tt class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>? Well, the method <tt class="computeroutput"><span class="identifier">str</span></tt>
requires the <tt class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>
to do its work (i.e. <tt class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt> is used by the method defined by
<tt class="computeroutput"><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span></tt>.
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel

View File

@@ -1,13 +1,16 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Functions</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="exposing.html" title="Exposing Classes">
<link rel="next" href="object.html" title="Object Interface">
<link rel="prev" href="exposing.html" title=" Exposing Classes">
<link rel="next" href="object.html" title=" Object Interface">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
@@ -38,18 +41,12 @@
see facilities that will make it even easier for us to expose C++ functions
that take advantage of C++ features such as overloading and default arguments.
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="emphasis"><em>Read on...</em></span>
</p>
<p>
</p>
</blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em>Read on...</em></span>
</p></blockquote></div>
<p>
But before you do, you might want to fire up Python 2.2 or later and type
<code class="literal">&gt;&gt;&gt; import this</code>.
<tt class="literal">&gt;&gt;&gt; import this</tt>.
</p>
<pre class="programlisting">&gt;&gt;&gt; import this
The Zen of Python, by Tim Peters
@@ -68,7 +65,7 @@ In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than <span class="bold"><strong>right</strong></span> now.
Although never is often better than <span class="bold"><b>right</b></span> now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
@@ -96,9 +93,9 @@ Namespaces are one honking great idea -- let's do more of those!
Here's an example where it didn't
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> # <span class="identifier">x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">y</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> # <span class="identifier">CRASH</span><span class="special">!</span>
</pre>
<p>
What's the problem?
@@ -126,19 +123,19 @@ Namespaces are one honking great idea -- let's do more of those!
</p>
<div class="orderedlist"><ol type="1">
<li>
<code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
and a pointer to <code class="literal">z</code>
<tt class="literal">f</tt> is called passing in a reference to <tt class="literal">y</tt>
and a pointer to <tt class="literal">z</tt>
</li>
<li>
A reference to <code class="literal">y.x</code> is returned
A reference to <tt class="literal">y.x</tt> is returned
</li>
<li>
<code class="literal">y</code> is deleted. <code class="literal">x</code> is a dangling reference
<tt class="literal">y</tt> is deleted. <tt class="literal">x</tt> is a dangling reference
</li>
<li>
<code class="literal">x.some_method()</code> is called
<tt class="literal">x.some_method()</tt> is called
</li>
<li><span class="bold"><strong>BOOM!</strong></span></li>
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<p>
We could copy result into a new object:
@@ -168,16 +165,16 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="special">};</span>
</pre>
<p>
Notice that the data member <code class="literal">z</code> is held by class Y using
Notice that the data member <tt class="literal">z</tt> is held by class Y using
a raw pointer. Now we have a potential dangling pointer problem inside Y:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">z</span> <span class="preprocessor"># Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> # <span class="identifier">y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">z</span> # <span class="identifier">Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> # <span class="identifier">CRASH</span><span class="special">!</span>
</pre>
<p>
For reference, here's the implementation of <code class="literal">f</code> again:
For reference, here's the implementation of <tt class="literal">f</tt> again:
</p>
<pre class="programlisting">
<span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
@@ -191,33 +188,33 @@ Namespaces are one honking great idea -- let's do more of those!
</p>
<div class="orderedlist"><ol type="1">
<li>
<code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
and a pointer to <code class="literal">z</code>
<tt class="literal">f</tt> is called passing in a reference to <tt class="literal">y</tt>
and a pointer to <tt class="literal">z</tt>
</li>
<li>
A pointer to <code class="literal">z</code> is held by <code class="literal">y</code>
A pointer to <tt class="literal">z</tt> is held by <tt class="literal">y</tt>
</li>
<li>
A reference to <code class="literal">y.x</code> is returned
A reference to <tt class="literal">y.x</tt> is returned
</li>
<li>
<code class="literal">z</code> is deleted. <code class="literal">y.z</code> is a dangling pointer
<tt class="literal">z</tt> is deleted. <tt class="literal">y.z</tt> is a dangling pointer
</li>
<li>
<code class="literal">y.z_value()</code> is called
<tt class="literal">y.z_value()</tt> is called
</li>
<li>
<code class="literal">z-&gt;value()</code> is called
<tt class="literal">z-&gt;value()</tt> is called
</li>
<li><span class="bold"><strong>BOOM!</strong></span></li>
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<a name="call_policies.call_policies"></a><h3>
<a name="id2648560"></a>
<a name="call_policies.call_policies"></a><h2>
<a name="id455614"></a>
Call Policies
</h3>
</h2>
<p>
Call Policies may be used in situations such as the example detailed above.
In our example, <code class="literal">return_internal_reference</code> and <code class="literal">with_custodian_and_ward</code>
In our example, <tt class="literal">return_internal_reference</tt> and <tt class="literal">with_custodian_and_ward</tt>
are our friends:
</p>
<pre class="programlisting">
@@ -226,27 +223,27 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="special">&gt;());</span>
</pre>
<p>
What are the <code class="literal">1</code> and <code class="literal">2</code> parameters, you
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you
ask?
</p>
<pre class="programlisting">
<span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span>
</pre>
<p>
Informs Boost.Python that the first argument, in our case <code class="literal">Y&amp;
y</code>, is the owner of the returned reference: <code class="literal">X&amp;</code>.
The "<code class="literal">1</code>" simply specifies the first argument.
In short: "return an internal reference <code class="literal">X&amp;</code> owned
by the 1st argument <code class="literal">Y&amp; y</code>".
Informs Boost.Python that the first argument, in our case <tt class="literal">Y&amp;
y</tt>, is the owner of the returned reference: <tt class="literal">X&amp;</tt>.
The "<tt class="literal">1</tt>" simply specifies the first argument.
In short: "return an internal reference <tt class="literal">X&amp;</tt> owned
by the 1st argument <tt class="literal">Y&amp; y</tt>".
</p>
<pre class="programlisting">
<span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span>
</pre>
<p>
Informs Boost.Python that the lifetime of the argument indicated by ward
(i.e. the 2nd argument: <code class="literal">Z* z</code>) is dependent on the lifetime
of the argument indicated by custodian (i.e. the 1st argument: <code class="literal">Y&amp;
y</code>).
(i.e. the 2nd argument: <tt class="literal">Z* z</tt>) is dependent on the lifetime
of the argument indicated by custodian (i.e. the 1st argument: <tt class="literal">Y&amp;
y</tt>).
</p>
<p>
It is also important to note that we have defined two policies above. Two
@@ -263,45 +260,42 @@ Namespaces are one honking great idea -- let's do more of those!
</p>
<div class="itemizedlist"><ul type="disc">
<li>
<span class="bold"><strong>with_custodian_and_ward</strong></span><br> Ties lifetimes
<span class="bold"><b>with_custodian_and_ward</b></span><br> Ties lifetimes
of the arguments
</li>
<li>
<span class="bold"><strong>with_custodian_and_ward_postcall</strong></span><br>
<span class="bold"><b>with_custodian_and_ward_postcall</b></span><br>
Ties lifetimes of the arguments and results
</li>
<li>
<span class="bold"><strong>return_internal_reference</strong></span><br> Ties lifetime
<span class="bold"><b>return_internal_reference</b></span><br> Ties lifetime
of one argument to that of result
</li>
<li>
<span class="bold"><strong>return_value_policy&lt;T&gt; with T one of:</strong></span><br>
<span class="bold"><b>return_value_policy&lt;T&gt; with T one of:</b></span><br>
</li>
<li>
<span class="bold"><strong>reference_existing_object</strong></span><br> naive
<span class="bold"><b>reference_existing_object</b></span><br> naive
(dangerous) approach
</li>
<li>
<span class="bold"><strong>copy_const_reference</strong></span><br> Boost.Python
<span class="bold"><b>copy_const_reference</b></span><br> Boost.Python
v1 approach
</li>
<li>
<span class="bold"><strong>copy_non_const_reference</strong></span><br>
<span class="bold"><b>copy_non_const_reference</b></span><br>
</li>
<li>
<span class="bold"><strong>manage_new_object</strong></span><br> Adopt a pointer
<span class="bold"><b>manage_new_object</b></span><br> Adopt a pointer
and hold the instance
</li>
</ul></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><strong>Remember the Zen, Luke:</strong></span><br>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span><br>
<br> "Explicit is better than implicit"<br> "In the face
of ambiguity, refuse the temptation to guess"<br>
</p>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.overloading"></a>Overloading</h3></div></div></div>
@@ -362,21 +356,21 @@ Namespaces are one honking great idea -- let's do more of those!
<a name="python.default_arguments"></a>Default Arguments</h3></div></div></div>
<p>
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
pointers carry no default argument info. Take a function <code class="literal">f</code>
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
with default arguments:
</p>
<pre class="programlisting">
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
</pre>
<p>
But the type of a pointer to the function <code class="literal">f</code> has no information
But the type of a pointer to the function <tt class="literal">f</tt> has no information
about its default arguments:
</p>
<pre class="programlisting">
<span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
</span></pre>
<p>
When we pass this function pointer to the <code class="literal">def</code> function,
When we pass this function pointer to the <tt class="literal">def</tt> function,
there is no way to retrieve the default arguments:
</p>
<pre class="programlisting">
@@ -410,10 +404,10 @@ Namespaces are one honking great idea -- let's do more of those!
are overloaded with a common sequence of initial arguments
</li>
</ul></div>
<a name="default_arguments.boost_python_function_overloads"></a><h3>
<a name="id2650414"></a>
<a name="default_arguments.boost_python_function_overloads"></a><h2>
<a name="id457647"></a>
BOOST_PYTHON_FUNCTION_OVERLOADS
</h3>
</h2>
<p>
Boost.Python now has a way to make it easier. For instance, given a function:
</p>
@@ -431,19 +425,19 @@ Namespaces are one honking great idea -- let's do more of those!
</pre>
<p>
will automatically create the thin wrappers for us. This macro will create
a class <code class="literal">foo_overloads</code> that can be passed on to <code class="literal">def(...)</code>.
a class <tt class="literal">foo_overloads</tt> that can be passed on to <tt class="literal">def(...)</tt>.
The third and fourth macro argument are the minimum arguments and maximum
arguments, respectively. In our <code class="literal">foo</code> function the minimum
number of arguments is 1 and the maximum number of arguments is 4. The <code class="literal">def(...)</code>
arguments, respectively. In our <tt class="literal">foo</tt> function the minimum
number of arguments is 1 and the maximum number of arguments is 4. The <tt class="literal">def(...)</tt>
function will automatically add all the foo variants for us:
</p>
<pre class="programlisting">
<span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
</pre>
<a name="default_arguments.boost_python_member_function_overloads"></a><h3>
<a name="id2650701"></a>
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
<a name="id457963"></a>
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
</h3>
</h2>
<p>
Objects here, objects there, objects here there everywhere. More frequently
than anything else, we need to expose member functions of our classes to
@@ -452,7 +446,7 @@ Namespaces are one honking great idea -- let's do more of those!
play. Another macro is provided to make this a breeze.
</p>
<p>
Like <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>, <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
Like <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>, <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
may be used to automatically create the thin wrappers for wrapping member
functions. Let's have an example:
</p>
@@ -473,11 +467,11 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
</pre>
<p>
will generate a set of thin wrappers for george's <code class="literal">wack_em</code>
will generate a set of thin wrappers for george's <tt class="literal">wack_em</tt>
member function accepting a minimum of 1 and a maximum of 3 arguments (i.e.
the third and fourth macro argument). The thin wrappers are all enclosed
in a class named <code class="literal">george_overloads</code> that can then be used
as an argument to <code class="literal">def(...)</code>:
in a class named <tt class="literal">george_overloads</tt> that can then be used
as an argument to <tt class="literal">def(...)</tt>:
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
@@ -486,13 +480,13 @@ Namespaces are one honking great idea -- let's do more of those!
See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
reference</a> for details.
</p>
<a name="default_arguments.init_and_optional"></a><h3>
<a name="id2651031"></a>
<a name="default_arguments.init_and_optional"></a><h2>
<a name="id458323"></a>
init and optional
</h3>
</h2>
<p>
A similar facility is provided for class constructors, again, with default
arguments or a sequence of overloads. Remember <code class="literal">init&lt;...&gt;</code>?
arguments or a sequence of overloads. Remember <tt class="literal">init&lt;...&gt;</tt>?
For example, given a class X with a constructor:
</p>
<pre class="programlisting">
@@ -509,7 +503,7 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
</pre>
<p>
Notice the use of <code class="literal">init&lt;...&gt;</code> and <code class="literal">optional&lt;...&gt;</code>
Notice the use of <tt class="literal">init&lt;...&gt;</tt> and <tt class="literal">optional&lt;...&gt;</tt>
to signify the default (optional arguments).
</p>
</div>
@@ -517,8 +511,8 @@ Namespaces are one honking great idea -- let's do more of those!
<div class="titlepage"><div><div><h3 class="title">
<a name="python.auto_overloading"></a>Auto-Overloading</h3></div></div></div>
<p>
It was mentioned in passing in the previous section that <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>
and <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code> can also be
It was mentioned in passing in the previous section that <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
and <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> can also be
used for overloaded functions and member functions with a common sequence
of initial arguments. Here is an example:
</p>
@@ -560,24 +554,24 @@ Namespaces are one honking great idea -- let's do more of those!
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.
</p>
<a name="auto_overloading.manual_wrapping"></a><h3>
<a name="id2651734"></a>
<a name="auto_overloading.manual_wrapping"></a><h2>
<a name="id459095"></a>
Manual Wrapping
</h3>
</h2>
<p>
It is important to emphasize however that <span class="bold"><strong>the overloaded
functions must have a common sequence of initial arguments</strong></span>. Otherwise,
It is important to emphasize however that <span class="bold"><b>the overloaded
functions must have a common sequence of initial arguments</b></span>. Otherwise,
our scheme above will not work. If this is not the case, we have to wrap
our functions <a href="functions.html#python.overloading" title="Overloading">manually</a>.
</p>
<p>
Actually, we can mix and match manual wrapping of overloaded functions and
automatic wrapping through <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
and its sister, <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>. Following
automatic wrapping through <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
and its sister, <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>. Following
up on our example presented in the section <a href="functions.html#python.overloading" title="Overloading">on
overloading</a>, since the first 4 overload functins have a common sequence
of initial arguments, we can use <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
to automatically wrap the first three of the <code class="literal">def</code>s and
of initial arguments, we can use <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
to automatically wrap the first three of the <tt class="literal">def</tt>s and
manually wrap just the last. Here's how we'll do this:
</p>
<pre class="programlisting">

View File

@@ -1,13 +1,16 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Building Hello World</title>
<title> Building Hello World</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="../index.html" title="Chapter 1. python 1.0">
<link rel="next" href="exposing.html" title="Exposing Classes">
<link rel="next" href="exposing.html" title=" Exposing Classes">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
@@ -25,29 +28,26 @@
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.hello"></a> Building Hello World</h2></div></div></div>
<a name="hello.from_start_to_finish"></a><h3>
<a name="id2595436"></a>
<a name="hello.from_start_to_finish"></a><h2>
<a name="id377427"></a>
From Start To Finish
</h3>
</h2>
<p>
Now the first thing you'd want to do is to build the Hello World module and
try it for yourself in Python. In this section, we shall outline the steps
necessary to achieve that. We shall use the build tool that comes bundled with
every boost distribution: <span class="bold"><strong>bjam</strong></span>.
every boost distribution: <span class="bold"><b>bjam</b></span>.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Building without bjam</strong></span><br>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Building without bjam</b></span><br>
<br> Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as "the one and only way".
There are of course other build tools apart from <code class="literal">bjam</code>.<br>
There are of course other build tools apart from <tt class="literal">bjam</tt>.<br>
<br> Take note however that the preferred build tool for Boost.Python is
bjam. There are so many ways to set up the build incorrectly. Experience shows
that 90% of the "I can't build Boost.Python" problems come from people
who had to use a different tool.
</p>
</div>
<p>
We shall skip over the details. Our objective will be to simply create the
hello world module and run it in Python. For a complete reference to building
@@ -78,7 +78,7 @@
if you are on Unix.
</p>
<p>
The tutorial example can be found in the directory: <code class="literal">libs/python/example/tutorial</code>.
The tutorial example can be found in the directory: <tt class="literal">libs/python/example/tutorial</tt>.
There, you can find:
</p>
<div class="itemizedlist"><ul type="disc">
@@ -90,20 +90,20 @@
</li>
</ul></div>
<p>
The <code class="literal">hello.cpp</code> file is our C++ hello world example. The
<code class="literal">Jamfile</code> is a minimalist <span class="emphasis"><em>bjam</em></span> script
The <tt class="literal">hello.cpp</tt> file is our C++ hello world example. The
<tt class="literal">Jamfile</tt> is a minimalist <span class="emphasis"><em>bjam</em></span> script
that builds the DLLs for us.
</p>
<p>
Before anything else, you should have the bjam executable in your boost directory
or somewhere in your path such that <code class="literal">bjam</code> can be executed
or somewhere in your path such that <tt class="literal">bjam</tt> can be executed
in the command line. Pre-built Boost.Jam executables are available for most
platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
</p>
<a name="hello.let_s_jam_"></a><h3>
<a name="id2595623"></a>
<a name="hello.let_s_jam_"></a><h2>
<a name="id377613"></a>
Let's Jam!
</h3>
</h2>
<p>
<span class="inlinemediaobject"><img src="../images/jam.png" alt="jam"></span>
</p>
@@ -123,13 +123,13 @@ extension hello # Declare a Python extension called hello
</pre>
<p>
First, we need to specify our location. You may place your project anywhere.
<code class="literal">project-root</code> allows you to do that.
<tt class="literal">project-root</tt> allows you to do that.
</p>
<pre class="programlisting">project-root ;
</pre>
<p>
By doing so, you'll need a Jamrules file. Simply copy the one in the <a href="../../../../../example/tutorial/Jamrules" target="_top">example/tutorial directory</a>
and tweak the <code class="literal">path-global BOOST_ROOT</code> to where your boost
and tweak the <tt class="literal">path-global BOOST_ROOT</tt> to where your boost
root directory is. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
instructions</a> you can follow.
</p>
@@ -139,7 +139,7 @@ extension hello # Declare a Python extension called hello
<pre class="programlisting">import python ;
</pre>
<p>
Finally we declare our <code class="literal">hello</code> extension:
Finally we declare our <tt class="literal">hello</tt> extension:
</p>
<pre class="programlisting">extension hello # Declare a Python extension called hello
: hello.cpp # source
@@ -151,26 +151,20 @@ extension hello # Declare a Python extension called hello
<p>
The last part tells BJam that we are depending on the Boost Python Library.
</p>
<a name="hello.running_bjam"></a><h3>
<a name="id2595752"></a>
<a name="hello.running_bjam"></a><h2>
<a name="id377751"></a>
Running bjam
</h3>
</h2>
<p>
<span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
interpreter.
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
Start it up.
</p>
<p>
</p>
</blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
Start it up.
</p></blockquote></div>
<p>
Make sure that the environment is set so that we can invoke the C++ compiler.
With MSVC, that would mean running the <code class="literal">Vcvars32.bat</code> batch
With MSVC, that would mean running the <tt class="literal">Vcvars32.bat</tt> batch
file. For instance:
</p>
<pre class="programlisting">C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
@@ -183,24 +177,21 @@ extension hello # Declare a Python extension called hello
set PYTHON_VERSION=2.2
</pre>
<p>
The above assumes that the Python installation is in <code class="literal">c:/dev/tools/python</code>
The above assumes that the Python installation is in <tt class="literal">c:/dev/tools/python</tt>
and that we are using Python version 2.2. You'll have to tweak these appropriately.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><strong>not</strong></span> "2.2.1", even if that's the version you
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><b>not</b></span> "2.2.1", even if that's the version you
have.
</p>
</div>
<p>
Take note that you may also do that through the Jamrules file we put in our
project as detailed above. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
instructions</a> you can follow.
</p>
<p>
Now we are ready... Be sure to <code class="literal">cd</code> to <code class="literal">libs/python/example/tutorial</code>
where the tutorial <code class="literal">"hello.cpp"</code> and the <code class="literal">"Jamfile"</code>
Now we are ready... Be sure to <tt class="literal">cd</tt> to <tt class="literal">libs/python/example/tutorial</tt>
where the tutorial <tt class="literal">"hello.cpp"</tt> and the <tt class="literal">"Jamfile"</tt>
is situated.
</p>
<p>
@@ -263,8 +254,8 @@ b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
if you are on Unix.
</p>
<p>
<code class="literal">boost_python.dll</code> and <code class="literal">hello.pyd</code> can be
found somewhere in your project's <code class="literal">bin</code> directory. After a
<tt class="literal">boost_python.dll</tt> and <tt class="literal">hello.pyd</tt> can be
found somewhere in your project's <tt class="literal">bin</tt> directory. After a
successful build, you make it possible for the system to find boost_python.dll
or libboost_python.so (usually done with LD_LIBRARY_PATH, DYLD_LIBRARY_PATH,
or some other variable on *nix and with PATH on Windows) and for Python to
@@ -282,15 +273,9 @@ b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
</pre>
<p>
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="bold"><strong>There you go... Have fun!</strong></span>
</p>
<p>
</p>
</blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="bold"><b>There you go... Have fun!</b></span>
</p></blockquote></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>

View File

@@ -1,13 +1,16 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Iterators</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="embedding.html" title="Embedding">
<link rel="next" href="exception.html" title="Exception Translation">
<link rel="next" href="exception.html" title=" Exception Translation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
@@ -30,7 +33,7 @@
iterators, but these are two very different beasts.
</p>
<p>
<span class="bold"><strong>C++ iterators:</strong></span>
<span class="bold"><b>C++ iterators:</b></span>
</p>
<div class="itemizedlist"><ul type="disc">
<li>
@@ -45,7 +48,7 @@
</li>
</ul></div>
<p>
<span class="bold"><strong>Python Iterators:</strong></span>
<span class="bold"><b>Python Iterators:</b></span>
</p>
<div class="itemizedlist"><ul type="disc">
<li>
@@ -59,8 +62,8 @@
</li>
</ul></div>
<p>
The typical Python iteration protocol: <code class="literal"><span class="bold"><strong>for y
in x...</strong></span></code> is as follows:
The typical Python iteration protocol: <tt class="literal"><span class="bold"><b>for y
in x...</b></span></tt> is as follows:
</p>
<p>
</p>
@@ -74,7 +77,7 @@
</span></pre>
<p>
Boost.Python provides some mechanisms to make C++ iterators play along nicely
as Python iterators. What we need to do is to produce appropriate <code class="computeroutput"><span class="identifier">__iter__</span></code> function from C++ iterators that
as Python iterators. What we need to do is to produce appropriate <tt class="computeroutput"><span class="identifier">__iter__</span></tt> function from C++ iterators that
is compatible with the Python iteration protocol. For example:
</p>
<p>
@@ -91,7 +94,7 @@
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
</pre>
<p>
<span class="bold"><strong>range</strong></span>
<span class="bold"><b>range</b></span>
</p>
<p>
We can create a Python savvy iterator using the range function:
@@ -119,14 +122,14 @@
</li>
</ul></div>
<p>
<span class="bold"><strong>iterator</strong></span>
<span class="bold"><b>iterator</b></span>
</p>
<div class="itemizedlist"><ul type="disc"><li>
iterator&lt;T, Policies&gt;()
</li></ul></div>
<p>
Given a container <code class="literal">T</code>, iterator is a shortcut that simply
calls <code class="literal">range</code> with &amp;T::begin, &amp;T::end.
Given a container <tt class="literal">T</tt>, iterator is a shortcut that simply
calls <tt class="literal">range</tt> with &amp;T::begin, &amp;T::end.
</p>
<p>
Let's put this into action... Here's an example from some hypothetical bogon
@@ -152,14 +155,14 @@
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
</pre>
<p>
<span class="bold"><strong>stl_input_iterator</strong></span>
<span class="bold"><b>stl_input_iterator</b></span>
</p>
<p>
So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes
we wish to go the other way, though: we'd like to pass a Python sequence to
an STL algorithm or use it to initialize an STL container. We need to make
a Python iterator look like an STL iterator. For that, we use <code class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special">&lt;&gt;</span></code>.
Consider how we might implement a function that exposes <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">assign</span><span class="special">()</span></code> to Python:
a Python iterator look like an STL iterator. For that, we use <tt class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special">&lt;&gt;</span></tt>.
Consider how we might implement a function that exposes <tt class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">assign</span><span class="special">()</span></tt> to Python:
</p>
<p>
</p>
@@ -178,7 +181,7 @@
</span> <span class="special">;</span>
</pre>
<p>
Now in Python, we can assign any integer sequence to <code class="computeroutput"><span class="identifier">list_int</span></code>
Now in Python, we can assign any integer sequence to <tt class="computeroutput"><span class="identifier">list_int</span></tt>
objects:
</p>
<p>

View File

@@ -1,9 +1,12 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Object Interface</title>
<title> Object Interface</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="functions.html" title="Functions">
@@ -35,13 +38,13 @@
Python is dynamically typed, unlike C++ which is statically typed. Python variables
may hold an integer, a float, list, dict, tuple, str, long etc., among other
things. In the viewpoint of Boost.Python and C++, these Pythonic variables
are just instances of class <code class="literal">object</code>. We shall see in this
are just instances of class <tt class="literal">object</tt>. We shall see in this
chapter how to deal with Python objects.
</p>
<p>
As mentioned, one of the goals of Boost.Python is to provide a bidirectional
mapping between C++ and Python while maintaining the Python feel. Boost.Python
C++ <code class="literal">object</code>s are as close as possible to Python. This should
C++ <tt class="literal">object</tt>s are as close as possible to Python. This should
minimize the learning curve significantly.
</p>
<p>
@@ -51,10 +54,10 @@
<div class="titlepage"><div><div><h3 class="title">
<a name="python.basic_interface"></a>Basic Interface</h3></div></div></div>
<p>
Class <code class="literal">object</code> wraps <code class="literal">PyObject*</code>. All the
intricacies of dealing with <code class="literal">PyObject</code>s such as managing
reference counting are handled by the <code class="literal">object</code> class. C++
object interoperability is seamless. Boost.Python C++ <code class="literal">object</code>s
Class <tt class="literal">object</tt> wraps <tt class="literal">PyObject*</tt>. All the
intricacies of dealing with <tt class="literal">PyObject</tt>s such as managing
reference counting are handled by the <tt class="literal">object</tt> class. C++
object interoperability is seamless. Boost.Python C++ <tt class="literal">object</tt>s
can in fact be explicitly constructed from any C++ object.
</p>
<p>
@@ -99,7 +102,7 @@
<div class="titlepage"><div><div><h3 class="title">
<a name="python.derived_object_types"></a>Derived Object types</h3></div></div></div>
<p>
Boost.Python comes with a set of derived <code class="literal">object</code> types
Boost.Python comes with a set of derived <tt class="literal">object</tt> types
corresponding to that of Python's:
</p>
<div class="itemizedlist"><ul type="disc">
@@ -123,32 +126,32 @@
</li>
</ul></div>
<p>
These derived <code class="literal">object</code> types act like real Python types.
These derived <tt class="literal">object</tt> types act like real Python types.
For instance:
</p>
<pre class="programlisting">
<span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==&gt;</span> <span class="string">"1"</span>
</pre>
<p>
Wherever appropriate, a particular derived <code class="literal">object</code> has
corresponding Python type's methods. For instance, <code class="literal">dict</code>
has a <code class="literal">keys()</code> method:
Wherever appropriate, a particular derived <tt class="literal">object</tt> has
corresponding Python type's methods. For instance, <tt class="literal">dict</tt>
has a <tt class="literal">keys()</tt> method:
</p>
<pre class="programlisting">
<span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
</pre>
<p>
<code class="literal">make_tuple</code> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
Example:
</p>
<pre class="programlisting">
<span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
</pre>
<p>
In C++, when Boost.Python <code class="literal">object</code>s are used as arguments
In C++, when Boost.Python <tt class="literal">object</tt>s are used as arguments
to functions, subtype matching is required. For example, when a function
<code class="literal">f</code>, as declared below, is wrapped, it will only accept
instances of Python's <code class="literal">str</code> type and subtypes.
<tt class="literal">f</tt>, as declared below, is wrapped, it will only accept
instances of Python's <tt class="literal">str</tt> type and subtypes.
</p>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
@@ -172,18 +175,15 @@
<span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
</pre>
<p>
Demonstrates that you can write the C++ equivalent of <code class="literal">"format"
% x,y,z</code> in Python, which is useful since there's no easy way to
Demonstrates that you can write the C++ equivalent of <tt class="literal">"format"
% x,y,z</tt> in Python, which is useful since there's no easy way to
do that in std C++.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>Beware</strong></span> the common pitfall
of forgetting that the constructors of most of Python's mutable types make
copies, just as in Python.
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>Beware</b></span> the common
pitfall of forgetting that the constructors of most of Python's mutable types
make copies, just as in Python.
</p>
</div>
<p>
Python:
</p>
@@ -198,12 +198,12 @@
<span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
</span><span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy
</span></pre>
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h3>
<a name="id2653534"></a>
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
<a name="id461067"></a>
class_&lt;T&gt; as objects
</h3>
</h2>
<p>
Due to the dynamic nature of Boost.Python objects, any <code class="literal">class_&lt;T&gt;</code>
Due to the dynamic nature of Boost.Python objects, any <tt class="literal">class_&lt;T&gt;</tt>
may also be one of these types! The following code snippet wraps the class
(type) object.
</p>
@@ -225,15 +225,15 @@
<a name="python.extracting_c___objects"></a>Extracting C++ objects</h3></div></div></div>
<p>
At some point, we will need to get C++ values out of object instances. This
can be achieved with the <code class="literal">extract&lt;T&gt;</code> function. Consider
can be achieved with the <tt class="literal">extract&lt;T&gt;</tt> function. Consider
the following:
</p>
<pre class="programlisting">
<span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
</span></pre>
<p>
In the code above, we got a compiler error because Boost.Python <code class="literal">object</code>
can't be implicitly converted to <code class="literal">double</code>s. Instead, what
In the code above, we got a compiler error because Boost.Python <tt class="literal">object</tt>
can't be implicitly converted to <tt class="literal">double</tt>s. Instead, what
we wanted to do above can be achieved by writing:
</p>
<pre class="programlisting">
@@ -243,14 +243,14 @@
</pre>
<p>
The first line attempts to extract the "length" attribute of the
Boost.Python <code class="literal">object</code>. The second line attempts to <span class="emphasis"><em>extract</em></span>
the <code class="literal">Vec2</code> object from held by the Boost.Python <code class="literal">object</code>.
Boost.Python <tt class="literal">object</tt>. The second line attempts to <span class="emphasis"><em>extract</em></span>
the <tt class="literal">Vec2</tt> object from held by the Boost.Python <tt class="literal">object</tt>.
</p>
<p>
Take note that we said "attempt to" above. What if the Boost.Python
<code class="literal">object</code> does not really hold a <code class="literal">Vec2</code>
<tt class="literal">object</tt> does not really hold a <tt class="literal">Vec2</tt>
type? This is certainly a possibility considering the dynamic nature of Python
<code class="literal">object</code>s. To be on the safe side, if the C++ type can't
<tt class="literal">object</tt>s. To be on the safe side, if the C++ type can't
be extracted, an appropriate exception is thrown. To avoid an exception,
we need to test for extractibility:
</p>
@@ -260,7 +260,7 @@
<span class="identifier">Vec2</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">();</span> <span class="special">...</span>
</pre>
<p>
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <code class="literal">extract&lt;T&gt;</code>
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <tt class="literal">extract&lt;T&gt;</tt>
facility in fact solves the mutable copying problem:
</p>
<pre class="programlisting">
@@ -273,8 +273,8 @@
<a name="python.enums"></a>Enums</h3></div></div></div>
<p>
Boost.Python has a nifty facility to capture and wrap C++ enums. While Python
has no <code class="literal">enum</code> type, we'll often want to expose our C++ enums
to Python as an <code class="literal">int</code>. Boost.Python's enum facility makes
has no <tt class="literal">enum</tt> type, we'll often want to expose our C++ enums
to Python as an <tt class="literal">int</tt>. Boost.Python's enum facility makes
this easy while taking care of the proper conversions from Python's dynamic
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
to enums). To illustrate, given a C++ enum:
@@ -293,19 +293,16 @@
</pre>
<p>
can be used to expose to Python. The new enum type is created in the current
<code class="literal">scope()</code>, which is usually the current module. The snippet
above creates a Python class derived from Python's <code class="literal">int</code>
<tt class="literal">scope()</tt>, which is usually the current module. The snippet
above creates a Python class derived from Python's <tt class="literal">int</tt>
type which is associated with the C++ type passed as its first parameter.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>what is a scope?</strong></span><br>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>what is a scope?</b></span><br>
<br> The scope is a class that has an associated global Python object which
controls the Python namespace in which new extension classes and wrapped
functions will be defined as attributes. Details can be found <a href="../../../../v2/scope.html" target="_top">here</a>.
</p>
</div>
<p>
You can access those values in Python as
</p>

View File

@@ -1,12 +1,15 @@
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>General Techniques</title>
<title> General Techniques</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="exception.html" title="Exception Translation">
<link rel="prev" href="exception.html" title=" Exception Translation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
@@ -50,7 +53,7 @@
<p>
We have a C++ library that works with sounds: reading and writing various
formats, applying filters to the sound data, etc. It is named (conveniently)
<code class="literal">sounds</code>. Our library already has a neat C++ namespace hierarchy,
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
like so:
</p>
<pre class="programlisting">
@@ -93,18 +96,15 @@
<span class="special">}</span>
</pre>
<p>
Compiling these files will generate the following Python extensions: <code class="literal">core.pyd</code>,
<code class="literal">io.pyd</code> and <code class="literal">filters.pyd</code>.
Compiling these files will generate the following Python extensions: <tt class="literal">core.pyd</tt>,
<tt class="literal">io.pyd</tt> and <tt class="literal">filters.pyd</tt>.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> The extension <code class="literal">.pyd</code> is used for python
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> The extension <tt class="literal">.pyd</tt> is used for python
extension modules, which are just shared libraries. Using the default for
your system, like <code class="literal">.so</code> for Unix and <code class="literal">.dll</code>
your system, like <tt class="literal">.so</tt> for Unix and <tt class="literal">.dll</tt>
for Windows, works just as well.
</p>
</div>
<p>
Now, we create this directory structure for our Python package:
</p>
@@ -115,12 +115,12 @@
io.pyd
</pre>
<p>
The file <code class="literal">__init__.py</code> is what tells Python that the directory
<code class="literal">sounds/</code> is actually a Python package. It can be a empty
The file <tt class="literal">__init__.py</tt> is what tells Python that the directory
<tt class="literal">sounds/</tt> is actually a Python package. It can be a empty
file, but can also perform some magic, that will be shown later.
</p>
<p>
Now our package is ready. All the user has to do is put <code class="literal">sounds</code>
Now our package is ready. All the user has to do is put <tt class="literal">sounds</tt>
into his <a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000" target="_top">PYTHONPATH</a>
and fire up the interpreter:
</p>
@@ -159,7 +159,7 @@
</pre>
<p>
Note that we added an underscore to the module name. The filename will have
to be changed to <code class="literal">_core.pyd</code> as well, and we do the same
to be changed to <tt class="literal">_core.pyd</tt> as well, and we do the same
to the other extension modules. Now, we change our package hierarchy like
so:
</p>
@@ -167,12 +167,12 @@
__init__.py
core/
__init__.py
<span class="underline">core.pyd
_core.pyd
filters/
\</span>_init__.py
<span class="underline">filters.pyd
__init__.py
_filters.pyd
io/
\</span>_init__.py
__init__.py
_io.pyd
</pre>
<p>
@@ -187,11 +187,11 @@
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span><span class="special">.</span><span class="identifier">foo</span><span class="special">(...)</span>
</pre>
<p>
which is not what we want. But here enters the <code class="literal">__init__.py</code>
magic: everything that is brought to the <code class="literal">__init__.py</code> namespace
which is not what we want. But here enters the <tt class="literal">__init__.py</tt>
magic: everything that is brought to the <tt class="literal">__init__.py</tt> namespace
can be accessed directly by the user. So, all we have to do is bring the
entire namespace from <code class="literal">_core.pyd</code> to <code class="literal">core/__init__.py</code>.
So add this line of code to <code class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</code>:
entire namespace from <tt class="literal">_core.pyd</tt> to <tt class="literal">core/__init__.py</tt>.
So add this line of code to <tt class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</tt>:
</p>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
@@ -208,10 +208,10 @@
with the additional benefit that we can easily add pure Python functions
to any module, in a way that the user can't tell the difference between a
C++ function and a Python function. Let's add a <span class="emphasis"><em>pure</em></span>
Python function, <code class="literal">echo_noise</code>, to the <code class="literal">filters</code>
package. This function applies both the <code class="literal">echo</code> and <code class="literal">noise</code>
filters in sequence in the given <code class="literal">sound</code> object. We create
a file named <code class="literal">sounds/filters/echo_noise.py</code> and code our
Python function, <tt class="literal">echo_noise</tt>, to the <tt class="literal">filters</tt>
package. This function applies both the <tt class="literal">echo</tt> and <tt class="literal">noise</tt>
filters in sequence in the given <tt class="literal">sound</tt> object. We create
a file named <tt class="literal">sounds/filters/echo_noise.py</tt> and code our
function:
</p>
<pre class="programlisting">
@@ -222,14 +222,14 @@
<span class="keyword">return</span> <span class="identifier">s</span>
</pre>
<p>
Next, we add this line to <code class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</code>:
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</tt>:
</p>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
</pre>
<p>
And that's it. The user now accesses this function like any other function
from the <code class="literal">filters</code> package:
from the <tt class="literal">filters</tt> package:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
@@ -263,7 +263,7 @@
</p>
<p>
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class <code class="literal">point</code> in C++:
we have a class <tt class="literal">point</tt> in C++:
</p>
<p>
</p>
@@ -277,7 +277,7 @@
</pre>
<p>
If we are using the technique from the previous session, <a href="techniques.html#python.creating_packages" title="Creating Packages">Creating
Packages</a>, we can code directly into <code class="literal">geom/__init__.py</code>:
Packages</a>, we can code directly into <tt class="literal">geom/__init__.py</tt>:
</p>
<p>
</p>
@@ -292,7 +292,7 @@
</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
</pre>
<p>
<span class="bold"><strong>All</strong></span> point instances created from C++ will
<span class="bold"><b>All</b></span> point instances created from C++ will
also have this member function! This technique has several advantages:
</p>
<div class="itemizedlist"><ul type="disc">
@@ -391,7 +391,7 @@
<span class="special">}</span>
</pre>
<p>
Now you create a file <code class="literal">main.cpp</code>, which contains the <code class="literal">BOOST_PYTHON_MODULE</code>
Now you create a file <tt class="literal">main.cpp</tt>, which contains the <tt class="literal">BOOST_PYTHON_MODULE</tt>
macro, and call the various export functions inside it.
</p>
<pre class="programlisting">
@@ -427,17 +427,12 @@
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
take a look at the <code class="literal">--multiple</code> option, that generates the
take a look at the <tt class="literal">--multiple</tt> option, that generates the
wrappers in various files as demonstrated here.
</p>
</div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> This method is useful too if you are getting the error
message <span class="emphasis"><em>"fatal error C1204:Compiler limit:internal structure
overflow"</em></span> when compiling a large source file, as explained
@@ -445,7 +440,6 @@
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel

View File

@@ -1365,6 +1365,11 @@ create a new scope around a class:
[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]]
@@ -1391,17 +1396,17 @@ all. So stay tuned... :-)
[h2 Building embedded programs]
To be able to embed python into your programs, you have to link to
both Boost.Python's as well as Python's own runtime library.
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 library comes in two variants. Both are located
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 library can be found in the [^/libs] subdirectory of
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.
@@ -1439,11 +1444,7 @@ steps:
# Call other Python C API routines to use the interpreter.\n\n
[/ # Call Py_Finalize() to stop the interpreter and release its resources.]
[blurb __note__ [*Note that at this time you must not call Py_Finalize() to stop the
interpreter. This may be fixed in a future version of boost.python.]
]
# Call Py_Finalize() to stop the interpreter and release its resources.
(Of course, there can be other C++ code between all of these steps.)
@@ -1460,76 +1461,171 @@ messy and especially hard to get right in the presence of C++ exceptions.
Fortunately Boost.Python provides the [@../../../v2/handle.html handle] and
[@../../../v2/object.html object] class templates to automate the process.
[h2 Reference-counting handles and objects]
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:
object main_module((
handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
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 __note__ [*Handle is a class ['template], so why haven't we been using any template parameters?]\n
\n
[^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]
Boost.python provides three related functions to run Python code from C++.
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:
object eval(str expression, object globals = object(), object locals = object())
object exec(str code, object globals = object(), object locals = object())
object exec_file(str filename, object globals = object(), object locals = object())
PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
eval evaluates the given expression and returns the resulting value.
exec executes the given code (typically a set of statements) returning the result,
and exec_file executes the code contained in the given file.
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 [^globals] and [^locals] parameters are Python dictionaries
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.
Boost.python provides a function to import a module:
We have already seen how to get the [^__main__] module's namespace so let's
run some Python code in it:
object import(str name)
object main_module((
handle<>(borrowed(PyImport_AddModule("__main__")))));
import imports a python module (potentially loading it into the running process
first), and returns it.
Let's import the [^__main__] module and run some Python code in its namespace:
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
object ignored = exec("hello = file('hello.txt', 'w')\n"
"hello.write('Hello world!')\n"
"hello.close()",
main_namespace);
handle<> ignored((PyRun_String(
"hello = file('hello.txt', 'w')\n"
"hello.write('Hello world!')\n"
"hello.close()"
, Py_file_input
, main_namespace.ptr()
, main_namespace.ptr())
));
Because the Python/C API doesn't know anything about [^object]s, we used
the object's [^ptr] member function to retrieve the [^PyObject*].
This should create a file called 'hello.txt' in the current directory
containing a phrase that is well-known in programming circles.
[h2 Manipulating Python objects]
[blurb
__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.
]
Often we'd like to have a class to manipulate Python objects.
But we have already seen such a class above, and in the
[@python/object.html previous section]: the aptly named [^object] class
and its derivatives. We've already seen that they can be constructed from
a [^handle]. The following examples should further illustrate this fact:
[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
above, and in the [@python/object.html previous section]: the aptly
named [^object] class and it's derivatives. We've already seen that they
can be constructed from a [^handle]. The following examples should further
illustrate this fact:
object main_module((
handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
object ignored = exec("result = 5 ** 2", main_namespace);
handle<> ignored((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 use eval instead,
which returns the result directly:
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()))
));
object result = eval("5 ** 2");
int five_squared = extract<int>(result);
[blurb
__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 evaluation of the python expression,
[@../../../v2/errors.html#error_already_set-spec error_already_set] is thrown:
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 = eval("5/0");
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 const &)
catch(error_already_set)
{
// handle the exception in some way
}
@@ -1543,7 +1639,7 @@ print the exception's traceback to the console, or comparing the type of the
exception with those of the [@http://www.python.org/doc/api/standardExceptions.html
standard exceptions]:
catch(error_already_set const &)
catch(error_already_set)
{
if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
{
@@ -1559,6 +1655,21 @@ standard exceptions]:
(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
[endsect]
[endsect] [/ Embedding]

View File

@@ -8,7 +8,7 @@
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - CallPolicies Concept</title>
</head>
@@ -60,7 +60,6 @@
<li><code>postcall</code> - Python argument tuple and result management
after the wrapped object is invoked</li>
<li><code>extract_return_type</code> - metafunction for extracting the return type from a given signature type sequence</li>
</ol>
<h2><a name="composition"></a>CallPolicies Composition</h2>
@@ -133,16 +132,7 @@
reference count must be decremented; if another existing object is
returned, its reference count must be incremented.</td>
</tr>
<tr>
<td valign="top"><code>P::extract_return_type</code></td>
<td>A model of <a href=
"../../../doc/refmanual/metafunction.html">Metafunction</a>.</td>
<td>An MPL unary <a href=
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a> used extract the return type from a given signature. By default it is derived from mpl::front.</td>
</tr>
</table>
</table>
Models of CallPolicies are required to be <a href=
"../../../utility/CopyConstructible.html">CopyConstructible</a>.
<hr>

View File

@@ -1,12 +1,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - ResultConverter Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
@@ -26,12 +24,10 @@
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
</dl>
</dd>
<dl class="page-index">
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
</dl>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
@@ -83,13 +79,6 @@ denotes an object of type <code><b>R</b></code>.
href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
should return non-zero.</td>
</tr>
<tr>
<td valign="top"><code>c.get_pytype()</code></td>
<td><code>PyTypeObject const*</code></td>
<td>A pointer to a Python Type object corresponding to result of the conversion,
or <code>0</code>. Used for documentation generation. If <code>0</code> is returned
the generated type in the documentation will be <b>object</b> .</td>
</tr>
</table>
<h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>

View File

@@ -139,41 +139,6 @@
compares <code>typeid(T).name()</code> instead of using and comparing
the <code>std::type_info</code> objects directly.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_NO_PY_SIGNATURES</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined for a module no pythonic signatures are generated
for the docstrings of the module functions, and no python type is associated with any
of the converters registered by the module. This also reduces the binary size of the
module by about 14% (gcc compiled).<br>
If defined for the boost_python runtime library, the default for the
<code>docstring_options.enable_py_signatures()</code> is set to <code>false</code>.
</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code></td>
<td valign="top" align="center"><i>defined if <code>BOOST_PYTHON_NO_PY_SIGNATURES</code> is undefined</i></td>
<td valign="top">This macro is defined to enable a smooth transition from older Boost.Python versions
which do not support pythonic signatures. For example usage see
<a href="pytype_function.html#examples">here</a>.
</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined the python type of <code>__init__</code> method "self" parameters
is properly generated, otherwise <code><b>object</b></code> is used. It is undefined
by default because it increases the binary size of the module by about 14% (gcc compiled).</td>
</tr>
</table>
<hr>

View File

@@ -82,7 +82,6 @@ namespace boost { namespace python
static PyObject* postcall(PyObject*, PyObject* result);
typedef <a href=
"#default_result_converter-spec">default_result_converter</a> result_converter;
template &lt;class Sig&gt; struct extract_return_type : mpl::front&lt;Sig&gt;{};
};
}}
</pre>
@@ -162,7 +161,7 @@ struct return_value_policy : Base
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
11 June, 2007
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->

View File

@@ -103,8 +103,6 @@ namespace boost { namespace python {
docstring_options(bool show_user_defined, bool show_signatures);
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
~docstring_options();
void
@@ -119,18 +117,6 @@ namespace boost { namespace python {
void
enable_signatures();
void
disable_py_signatures();
void
enable_py_signatures();
void
disable_cpp_signatures();
void
enable_cpp_signatures();
void
disable_all();
@@ -153,7 +139,7 @@ docstring_options(bool show_all=true);
object which controls the appearance of function and
member-function docstrings defined in the code that follows. If
<code>show_all</code> is <code>true</code>, both the
user-defined docstrings and the automatically generated Python and C++
user-defined docstrings and the automatically generated C++
signatures are shown. If <code>show_all</code> is
<code>false</code> the <code>__doc__</code> attributes are
<code>None</code>.</dt>
@@ -168,29 +154,12 @@ docstring_options(bool show_user_defined, bool show_signatures);
member-function docstrings defined in the code that follows.
Iff <code>show_user_defined</code> is <code>true</code>, the
user-defined docstrings are shown. Iff
<code>show_signatures</code> is <code>true</code>, Python and C++
<code>show_signatures</code> is <code>true</code>, C++
signatures are automatically added. If both
<code>show_user_defined</code> and <code>show_signatures</code>
are <code>false</code>, the <code>__doc__</code> attributes are
<code>None</code>.</dt>
</dl>
<pre>
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
object which controls the appearance of function and
member-function docstrings defined in the code that follows.
Iff <code>show_user_defined</code> is <code>true</code>, the
user-defined docstrings are shown. Iff
<code>show_py_signatures</code> is <code>true</code>, Python
signatures are automatically added. Iff
<code>show_cpp_signatures</code> is <code>true</code>, C++
signatures are automatically added. If all parameters are
<code>false</code>, the <code>__doc__</code> attributes are
<code>None</code>.</dt>
</dl>
<h4><a name="docstring_options-spec-dtors" id=
"docstring_options-spec-dtors"></a>Class
@@ -217,10 +186,6 @@ void disable_user_defined();
void enable_user_defined();
void disable_signatures();
void enable_signatures();
void disable_py_signatures();
void enable_py_signatures();
void disable_cpp_signatures();
void enable_cpp_signatures();
void disable_all();
void enable_all();
</pre>
@@ -231,7 +196,7 @@ void enable_all();
<code>*_user_defined()</code> and <code>*_signatures()</code>
member functions are provided for fine-grained control. The
<code>*_all()</code> member functions are convenient shortcuts
to manipulate all settings simultaneously.</dt>
to manipulate both settings simultaneously.</dt>
</dl>
<h2><a name="examples" id="examples"></a>Examples</h2>
@@ -254,7 +219,7 @@ BOOST_PYTHON_MODULE(demo)
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo.__doc__
foo() -&gt; None : foo doc
foo doc
C++ signature:
foo(void) -&gt; void
</pre>If compiled with
@@ -288,33 +253,21 @@ BOOST_PYTHON_MODULE(demo)
def("foo3", foo3, arg("f"), "foo3 doc");
doc_options.enable_user_defined();
def("foo4", foo4, arg("d"), "foo4 doc");
doc_options.enable_py_signatures();
def("foo5", foo4, arg("d"), "foo5 doc");
doc_options.disable_py_signatures();
doc_options.enable_cpp_signatures();
def("foo6", foo4, arg("d"), "foo6 doc");
}
</pre>Python code:
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo1.__doc__
foo1( (int)i) -&gt; int : foo1 doc
foo1 doc
C++ signature:
foo1(int i) -&gt; int
&gt;&gt;&gt; print demo.foo2.__doc__
foo2( (int)l) -&gt; int :
C++ signature:
foo2(long l) -&gt; int
&gt;&gt;&gt; print demo.foo3.__doc__
None
&gt;&gt;&gt; print demo.foo4.__doc__
foo4 doc
&gt;&gt;&gt; print demo.foo5.__doc__
foo5( (float)d) -&gt; int : foo5 doc
&gt;&gt;&gt; print demo.foo6.__doc__
foo6 doc
C++ signature:
foo6(double d) -&gt; int
</pre>
<h4>Wrapping from multiple C++ scopes</h4>

View File

@@ -89,7 +89,7 @@ namespace boost { namespace python
template &lt;class T&gt;
class enum_ : public <a href="object.html#object-spec">object</a>
{
enum_(char const* name, char const* doc = 0);
enum_(char const* name);
enum_&lt;T&gt;&amp; value(char const* name, T);
enum_&lt;T&gt;&amp; export_values();
};
@@ -99,7 +99,7 @@ namespace boost { namespace python
<h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
constructors</h4>
<pre>
enum_(char const* name, char const* doc=0);
enum_(char const* name);
</pre>
<dl class="function-semantics">
@@ -131,7 +131,7 @@ inline enum_&lt;T&gt;&amp; value(char const* name, T x);
<dt><b>Effects:</b> adds an instance of the wrapped enumeration
type with value <code>x</code> to the type's dictionary as the
<code>name</code>d attribute.</dt>
<code>name</code>d attribute</dt>.
<dt><b>Returns:</b> <code>*this</code></dt>
@@ -146,7 +146,7 @@ inline enum_&lt;T&gt;&amp; export_values();
<dt><b>Effects:</b> sets attributes in the current <a
href="scope.html#scope-spec"><code>scope</code></a> with the
same names and values as all enumeration values exposed so far
by calling <code>value()</code>.</dt>
by calling <code>value()</code></dt>.
<dt><b>Returns:</b> <code>*this</code></dt>

View File

@@ -38,7 +38,6 @@
<dd>
<dl class="page-index">
<dt><a href="#eval-spec"><code>eval</code></a></dt>
<dt><a href="#exec-spec"><code>exec</code></a></dt>
<dt><a href="#exec_file-spec"><code>exec_file</code></a></dt>
</dl>
@@ -53,23 +52,6 @@
<h2><a name="functions"></a>Functions</h2>
<h3><a name="eval-spec"></a><code>eval</code></h3>
<pre>
object eval(str expression,
object globals = object(),
object locals = object());
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
Evaluate Python expression from <code>expression</code> in the context
specified by the dictionaries <code>globals</code> and <code>locals</code>.
</dt>
<dt><b>Returns:</b>
An instance of <a href="object.html#object-spec">object</a>
which holds the value of the expression.
</dt>
</dl>
<h3><a name="exec-spec"></a><code>exec</code></h3>
<pre>
object exec(str code,
@@ -127,7 +109,7 @@ void greet()
// Define greet function in Python.
object result = exec(
"def greet(): \n"
"def greet(self): \n"
" return 'Hello from Python!' \n",
global, global);
@@ -144,7 +126,7 @@ void greet()
we could also store it in an a file...</para>
<pre>
def greet():
def greet(self):
return 'Hello from Python!'
</pre>
<para>... and execute that instead.</para>

View File

@@ -1,216 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright Nikolay Mladenov 2007. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/doobject/function_doc_signature.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width=
"277" alt="C++ Boost" src="../../../../boost.png" border=
"0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href=
"../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/object/function_doc_signature.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#function_doc_signature_generator-spec">Class
<code>function_doc_signature_generator</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#function_doc_signature_generator-spec-synopsis">Class
<code>function_doc_signature_generator</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction" id=
"introduction"></a>Introduction</h2>
<p>Boost.Python supports docstrings with automatic
appending of Pythonic and C++ signatures. This feature is implemented
by <code>class function_doc_signature_generator</code>
The class uses all of the overloads, supplied arg names and default values, as well as
the user-defined docstrings, to generate documentation for a given function.</p>
<h2><a name="classes" id="classes"></a>Classes</h2>
<h3><a name="function_doc_signature_generator-spec" id=
"function_doc_signature_generator-spec"></a>Class
<code>function_doc_signature_generator</code></h3>
<p>
The class has only one public function which returns a list of strings documenting the
overloads of a function.
</p>
<h4><a name="function_doc_signature_generator-spec-synopsis" id=
"function_doc_signature_generator-spec-synopsis"></a>Class
<code>function_doc_signature_generator</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace objects {
class function_doc_signature_generator
{
public:
static list function_doc_signatures(function const *f);
};
}}}
</pre>
<h2><a name="examples" id="examples"></a>Examples</h2>
<h4>Docstrings generated with <code>function_doc_signature_generator</code></h4>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/args.hpp&gt;
#include &lt;boost/python/tuple.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/overloads.hpp&gt;
#include &lt;boost/python/raw_function.hpp&gt;
using namespace boost::python;
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
{
return make_tuple(x, y, z);
}
BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
struct X
{
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
{
return make_tuple(x, y, z);
}
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
tuple raw_func(tuple args, dict kw)
{
return make_tuple(args, kw);
}
BOOST_PYTHON_MODULE(args_ext)
{
def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
, "This is f's docstring"
);
def("raw", raw_function(raw_func));
def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
class_&lt;X&gt;("X", "This is X's docstring", init&lt;&gt;(args("self")))
.def("f", &amp;X::f
, "This is X.f's docstring"
, args("self","x", "y", "z"))
;
}
</pre>
Python code:
<pre>
&gt;&gt;&gt; import args_ext
&gt;&gt;&gt; help(args_ext)
Help on module args_ext:
NAME
args_ext
FILE
args_ext.pyd
CLASSES
Boost.Python.instance(__builtin__.object)
X
class X(Boost.Python.instance)
| This is X's docstring
|
| Method resolution order:
| X
| Boost.Python.instance
| __builtin__.object
|
| Methods defined here:
|
| __init__(...)
| __init__( (object)self) -> None :
| C++ signature:
| void __init__(struct _object *)
|
| f(...)
| f( (X)self, (int)x, (float)y, (str)z) -> tuple : This is X.f's docstring
| C++ signature:
| class boost::python::tuple f(struct X {lvalue},int,double,char const *)
|
| .................
|
FUNCTIONS
f(...)
f([ (int)x=1 [, (float)y=4.25 [, (str)z='wow']]]) -> tuple : This is f's docstring
C++ signature:
class boost::python::tuple f([ int=1 [,double=4.25 [,char const *='wow']]])
f1(...)
f1([ (int)x [, (float)y [, (str)z]]]) -> tuple : f1's docstring
C++ signature:
class boost::python::tuple f1([ int [,double [,char const *]]])
raw(...)
object raw(tuple args, dict kwds) :
C++ signature:
object raw(tuple args, dict kwds)
</pre>
<p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
</body>
</html>

View File

@@ -214,9 +214,6 @@ namespace boost { namespace python { namespace self_ns {
<a href=
"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; str(self_t);
<a href=
"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; repr(self_t);
}}};
</pre>
The tables below describe the methods generated when the results of the
@@ -768,15 +765,6 @@ namespace boost { namespace python { namespace self_ns {
<td><code><a href=
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</code></td>
</tr>
<tr>
<td><code>repr</code></td>
<td><code>__repr__</code></td>
<td><code><a href=
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</code></td>
</tr>
</table>
<h3><a name="other-spec"></a>Class Template <code>other</code></h3>

View File

@@ -1,370 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright Nikolay Mladenov 2007. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/doobject/pytype_function.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width=
"277" alt="C++ Boost" src="../../../../boost.png" border=
"0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href=
"../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/converter/pytype_function.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#wrap_pytype-spec">Class
<code>wrap_pytype</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#wrap_pytype-spec-synopsis">Class
<code>wrap_pytype</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dd>
<dl class="page-index">
<dt><a href="#registered_pytype-spec">Class
<code>registered_pytype</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#registered_pytype-spec-synopsis">Class
<code>registered_pytype</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dd>
<dl class="page-index">
<dt><a href="#expected_from_python_type-spec">Class
<code>expected_from_python_type</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#expected_from_python_type-spec-synopsis">Class
<code>expected_from_python_type</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dd>
<dl class="page-index">
<dt><a href="#to_python_target_type-spec">Class
<code>to_python_target_type</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#to_python_target_type-spec-synopsis">Class
<code>to_python_target_type</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction" id=
"introduction"></a>Introduction</h2>
<p>To support Pythonic signatures the converters should supply a <code>get_pytype</code> function
returning a pointer to the associated <code>PyTypeObject</code>. See for example
<a href="ResultConverter.html#ResultConverter-concept">ResultConverter</a> or
<a href="to_python_converter.html#to_python_converter-spec">to_python_converter</a>.
The classes in this header file are meant to be used when implmenting <code>get_pytype</code>.
There are also <code>_direct</code> versions of the templates of <code>class T</code> which
should be used with undecorated type parameter, expected to be in the conversion registry when the module loads.
</p>
<h2><a name="classes" id="classes"></a>Classes</h2>
<h3><a name="wrap_pytype-spec" id=
"wrap_pytype-spec"></a>Class
<code>wrap_pytype</code></h3>
<p>
This template generates a static <code>get_pytype</code> member returning the template parameter.
</p>
<h4><a name="wrap_pytype-spec-synopsis" id=
"wrap_pytype-spec-synopsis"></a>Class
<code>wrap_pytype</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; PyTypeObject const *pytype &gt;
class wrap_pytype
{
public:
static PyTypeObject const *get_pytype(){return pytype; }
};
}}}
</pre>
<h3><a name="registered_pytype-spec" id=
"registered_pytype-spec"></a>Class
<code>registered_pytype</code></h3>
<p>
This template should be used with template parameters which are (possibly decorated)
types exported to python using <a href="class.html"><code>class_</code></a>.
The generated a static <code>get_pytype</code> member
returns the corresponding python type.
</p>
<h4><a name="registered_pytype-spec-synopsis" id=
"registered_pytype-spec-synopsis"></a>Class
<code>registered_pytype</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; class T &gt;
class registered_pytype
{
public:
static PyTypeObject const *get_pytype();
};
}}}
</pre>
<h3><a name="expected_from_python_type-spec" id=
"expected_from_python_type-spec"></a>Class
<code>expected_from_python_type</code></h3>
<p>
This template generates a static <code>get_pytype</code> member which inspects the registered
<code>from_python</code> converters for the type <code>T</code> and returns a matching python type.
</p>
<h4><a name="expected_from_python_type-spec-synopsis" id=
"expected_from_python_type-spec-synopsis"></a>Class
<code>expected_from_python_type</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; class T &gt;
class expected_from_python_type
{
public:
static PyTypeObject const *get_pytype();
};
}}}
</pre>
<h3><a name="to_python_target_type-spec" id=
"to_python_target_type-spec"></a>Class
<code>to_python_target_type</code></h3>
<p>
This template generates a static <code>get_pytype</code> member returning the
python type to which T can be converted.
</p>
<h4><a name="to_python_target_type-spec-synopsis" id=
"to_python_target_type-spec-synopsis"></a>Class
<code>to_python_target_type</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace converter{
template &lt; class T &gt;
class to_python_target_type
{
public:
static PyTypeObject const *get_pytype();
};
}}}
</pre>
<h2><a name="examples" id="examples"></a>Examples</h2>
This example presumes that someone has implemented the standard <a href=
"http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
module</a> from the Python documentation, and placed the corresponding
declarations in <code>"noddy.h"</code>. Because
<code>noddy_NoddyObject</code> is the ultimate trivial extension type,
the example is a bit contrived: it wraps a function for which all
information is contained in the <i>type</i> of its return value.
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/reference.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include "noddy.h"
struct tag {};
tag make_tag() { return tag(); }
using namespace boost::python;
struct tag_to_noddy
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
: wrap_pytype<&amp;noddy_NoddyType> //inherits get_pytype from wrap_pytype
#endif
{
static PyObject* convert(tag const&amp; x)
{
return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
}
};
BOOST_PYTHON_MODULE(to_python_converter)
{
def("make_tag", make_tag);
to_python_converter&lt;tag, tag_to_noddy
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
, true
#endif
&gt;(); //"true" because tag_to_noddy has member get_pytype
}
</pre>
<p>The following example registers to and from python converters using the templates
<code>expected_from_python_type</code> and <code>to_pyhton_target_type</code>.
</p>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/extract.hpp&gt;
#include &lt;boost/python/to_python_converter.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
using namespace boost::python;
struct A
{
};
struct B
{
A a;
B(const A& a_):a(a_){}
};
// Converter from A to python int
struct BToPython
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
: converter::to_python_target_type&lt;A&gt; //inherits get_pytype
#endif
{
static PyObject* convert(const B& b)
{
return incref(object(b.a).ptr());
}
};
// Conversion from python int to A
struct BFromPython
{
BFromPython()
{
boost::python::converter::registry::push_back
( &amp;convertible
, &amp;construct
, type_id&lt; B &gt;()
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
, &amp;converter::expected_from_python_type&lt;A&gt;::get_pytype//convertible to A can be converted to B
#endif
);
}
static void* convertible(PyObject* obj_ptr)
{
extract&lt;const A&&gt; ex(obj_ptr);
if (!ex.check()) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
void* storage = (
(converter::rvalue_from_python_storage&lt; B &gt;*)data)-&gt; storage.bytes;
extract&lt;const A&&gt; ex(obj_ptr);
new (storage) B(ex());
data->convertible = storage;
}
};
B func(const B& b) { return b ; }
BOOST_PYTHON_MODULE(pytype_function_ext)
{
to_python_converter&lt; B , BToPython
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
,true
#endif
&gt;(); //has get_pytype
BFromPython();
class_&lt;A&gt;("A") ;
def("func", &amp;func);
}
&gt;&gt;&gt; from pytype_function_ext import *
&gt;&gt;&gt; print func.__doc__
func( (A)arg1) -> A :
C++ signature:
struct B func(struct B)
</pre>
<p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
</body>
</html>

View File

@@ -609,66 +609,6 @@
</dl>
</dd>
<dd>
<a name="function_documentation"></a>
<h3>Function documentation</h3>
<dl class="index">
<dt><a href=
"function_doc_signature.html">function_doc_signature.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"function_doc_signature.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"function_doc_signature.html#function_doc_signature_generator-spec">function_doc_signature_generator</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html">pytype_function.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"pytype_function.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"pytype_function.html#wrap_pytype-spec">wrap_pytype</a></dt>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html#expected_from_python_type-spec">expected_from_python_type</a></dt>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html#to_python_target_type-spec">to_python_target_type</a></dt>
</dl>
<dl class="index">
<dt><a href=
"pytype_function.html#registered_pytype-spec">registered_pytype</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</dd>
<dd>
<a name="models_of_call_policies"></a>
@@ -1037,7 +977,6 @@
<dd>
<dl class="index">
<dt><a href="exec.html#eval-spec">eval</a></dt>
<dt><a href="exec.html#exec-spec">exec</a></dt>
<dt><a href="exec.html#exec_file-spec">exec_file</a></dt>
</dl>

View File

@@ -125,8 +125,6 @@ namespace boost { namespace python
{
static PyObject* postcall(PyObject*, PyObject* result);
struct result_converter{ template &lt;class T&gt; struct apply; };
template &lt;class Sig&gt; struct extract_return_type : mpl::at_c&lt;Sig, arg_pos&gt;{};
};
}}
</pre>

View File

@@ -108,23 +108,6 @@
<td>A class type whose static member function <code>convert</code>
does the real work of the conversion.</td>
</tr>
<tr>
<td><code>bool has_get_pytype = false</code></td>
<td>
<code>PyTypeObject const * p = Conversion::get_pytype() </code>.</td>
<td><b>Optional member</b> - if <code>Conversion</code> has <code>get_pytype</code> member supply
<code>true</code> for this parameters.
If present <code>get_pytype</code> is used to document the return type
of functions using this conversion. The <code>get_pytype</code> may be implemented
using the classes and functions
from <a href="pytype_function.html"><code>pytype_function.hpp</code></a>
<b>NOTE :</b> For backward compatibility this parameter may be passed after
checking if <code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code> is defined (see
<a href="pytype_function.html#examples">here</a>).
</td>
</tr>
</table>
<h4><a name="to_python_converter-spec-synopsis"></a>Class template
@@ -132,7 +115,7 @@
<pre>
namespace boost { namespace python
{
template &lt;class T, class Conversion, bool convertion_has_get_pytype_member=false&gt;
template &lt;class T, class Conversion&gt;
struct to_python_converter
{
to_python_converter();
@@ -177,16 +160,12 @@ struct tag_to_noddy
{
return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
}
static PyTypeObject const* get_pytype()
{
return &amp;noddy_NoddyType;
}
};
BOOST_PYTHON_MODULE(to_python_converter)
{
def("make_tag", make_tag);
to_python_converter&lt;tag, tag_to_noddy, true&gt;(); //"true" because tag_to_noddy has member get_pytype
to_python_converter&lt;tag, tag_to_noddy&gt;();
}
</pre>
@@ -216,7 +195,7 @@ BOOST_PYTHON_MODULE(to_python_converter)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
11 June, 2007
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

BIN
example/Attic/project.zip Normal file

Binary file not shown.

36
example/Jamfile.v2 Normal file
View File

@@ -0,0 +1,36 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
project : requirements <library>/boost/python//boost_python ;
python-extension getting_started1 : getting_started1.cpp ;
bpl-test test1
: # Python test driver
test_getting_started1.py
# extension modules to use
getting_started1 ;
python-extension getting_started2 : getting_started2.cpp ;
bpl-test test2
: # Python test driver
test_getting_started2.py
# extension modules to use
getting_started2 ;
python-extension std_pair : std_pair.cpp ;
bpl-test test3
: # Python test driver
test_std_pair.py
# extension modules to use
std_pair_ext ;
# Don't run tests by default
explicit test1 test2 test3 ;
alias test : test1 test2 test3 ;
explicit test ;

View File

@@ -35,6 +35,6 @@ run-test test3 : std_pair_ext test_std_pair.py ;
# A target that runs all the tests
alias test : test1 test2 test3 ;
# Only run tests when explicitly requested
# Don't run tests by default
explicit test test1 test2 test3 ;

36
example/Jamrules Executable file
View File

@@ -0,0 +1,36 @@
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
# and conditions of use.
# If you move this example from its place in the Boost tree, edit this
# path to point at the root directory of your Boost installation (the
# one containing a subdirectory called "boost/" and a sub-subdirectory
# "boost/python/" full of .hpp files). Absolute paths work, too.
#
path-global BOOST_ROOT : ../../.. ;
# Boost.Python configuration variables, as described in
# http://www.boost.org/libs/python/doc/building.html#configuration.
# Usually you don't need to set these; the defaults will work. If you
# do set them, try to change as few of them as possible, starting with
# the first ones.
# PYTHON_VERSION = <the two-part Major.Minor version number, e.g. 2.2> ;
# PYTHON_ROOT = <root directory of your Python installation, e.g. /usr> ;
# PYTHON_INCLUDES = <path to Python #include directories> ;
# PYTHON_LIB_PATH = <path to Python library object> ;
# You may need to configure your compiler toolset, especially if you
# want to build with a compiler that is not the "system default" or if
# it is installed in a nonstandard place; see
# http://www.boost.org/more/getting_started.html#Configuring for
# details.
# Makes a project id for boost so that other Boost.Build projects can
# refer to it by name.
#
project boost : $(BOOST_ROOT) ;
# Change this setting to have all your built products placed under a
# single directory:
#
# ALL_LOCATE_TARGET = <root directory for all built products>

View File

@@ -18,7 +18,6 @@ namespace { // Avoid cluttering the global namespace.
return boost::python::incref(
boost::python::make_tuple(p.first, p.second).ptr());
}
static PyTypeObject const *get_pytype () {return &PyTuple_Type; }
};
// Helper for convenience.
@@ -29,9 +28,7 @@ namespace { // Avoid cluttering the global namespace.
{
boost::python::to_python_converter<
std::pair<T1, T2>,
std_pair_to_tuple<T1, T2>,
true //std_pair_to_tuple has get_pytype
>();
std_pair_to_tuple<T1, T2> >();
}
};

View File

@@ -1,73 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// 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/docstring_options.hpp>
# include <boost/python/enum.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/exception_translator.hpp>
# include <boost/python/exec.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/import.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_constructor.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/opaque_pointer_converter.hpp>
# include <boost/python/operators.hpp>
# include <boost/python/other.hpp>
# include <boost/python/overloads.hpp>
# include <boost/python/pointee.hpp>
# include <boost/python/pure_virtual.hpp>
# include <boost/python/ptr.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/register_ptr_to_python.hpp>
# include <boost/python/return_arg.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/return_opaque_pointer.hpp>
# include <boost/python/return_value_policy.hpp>
# 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

@@ -1,76 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ARG_FROM_PYTHON_DWA2002128_HPP
# define ARG_FROM_PYTHON_DWA2002128_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/converter/arg_from_python.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
# include <boost/type_traits/remove_cv.hpp>
#endif
namespace boost { namespace python {
template <class T>
struct arg_from_python
: converter::select_arg_from_python<
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
typename boost::remove_cv<T>::type
# else
T
# endif
>::type
{
typedef typename converter::select_arg_from_python<
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
typename boost::remove_cv<T>::type
# else
T
# endif
>::type base;
arg_from_python(PyObject*);
};
// specialization for PyObject*
template <>
struct arg_from_python<PyObject*>
{
typedef PyObject* result_type;
arg_from_python(PyObject* p) : m_source(p) {}
bool convertible() const { return true; }
PyObject* operator()() const { return m_source; }
private:
PyObject* m_source;
};
template <>
struct arg_from_python<PyObject* const&>
{
typedef PyObject* const& result_type;
arg_from_python(PyObject* p) : m_source(p) {}
bool convertible() const { return true; }
PyObject*const& operator()() const { return m_source; }
private:
PyObject* m_source;
};
//
// 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

@@ -1,175 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef KEYWORDS_DWA2002323_HPP
# define KEYWORDS_DWA2002323_HPP
# include <boost/python/detail/prefix.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/python/object_core.hpp>
# include <boost/mpl/bool.hpp>
# include <cstddef>
# include <algorithm>
namespace boost { namespace python {
typedef detail::keywords<1> arg;
typedef arg arg_; // gcc 2.96 workaround
namespace detail
{
template <std::size_t nkeywords>
struct keywords_base
{
BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
keyword_range range() const
{
return keyword_range(elements, elements + nkeywords);
}
keyword elements[nkeywords];
keywords<nkeywords+1>
operator,(python::arg const &k) const;
keywords<nkeywords + 1>
operator,(char const *name) const;
};
template <std::size_t nkeywords>
struct keywords : keywords_base<nkeywords>
{
};
template <>
struct keywords<1> : keywords_base<1>
{
explicit keywords(char const *name)
{
elements[0].name = name;
}
template <class T>
python::arg& operator=(T const& value)
{
object z(value);
elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
return *this;
}
operator detail::keyword const&() const
{
return elements[0];
}
};
template <std::size_t nkeywords>
inline
keywords<nkeywords+1>
keywords_base<nkeywords>::operator,(python::arg const &k) const
{
keywords<nkeywords> const& l = *static_cast<keywords<nkeywords> const*>(this);
python::detail::keywords<nkeywords+1> res;
std::copy(l.elements, l.elements+nkeywords, res.elements);
res.elements[nkeywords] = k.elements[0];
return res;
}
template <std::size_t nkeywords>
inline
keywords<nkeywords + 1>
keywords_base<nkeywords>::operator,(char const *name) const
{
return this->operator,(python::arg(name));
}
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
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
}
inline detail::keywords<1> args(char const* name)
{
return detail::keywords<1>(name);
}
# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
# 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 (2, BOOST_PYTHON_MAX_ARITY)
# include BOOST_PP_LOCAL_ITERATE()
}} // namespace boost::python
# endif // KEYWORDS_DWA2002323_HPP

View File

@@ -1,52 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ARGS_FWD_DWA2002927_HPP
# define ARGS_FWD_DWA2002927_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/handle.hpp>
# include <boost/config.hpp>
# include <cstddef>
# include <utility>
namespace boost { namespace python {
namespace detail
{
struct keyword
{
keyword(char const* name_=0)
: name(name_)
{}
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

@@ -1,102 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BACK_REFERENCE_DWA2002510_HPP
# define BACK_REFERENCE_DWA2002510_HPP
# include <boost/python/detail/prefix.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

@@ -1,43 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BASE_TYPE_TRAITS_DWA2002614_HPP
# define BASE_TYPE_TRAITS_DWA2002614_HPP
# include <boost/python/detail/prefix.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;
};
template <>
struct base_type_traits<PyMethodObject>
{
typedef PyObject type;
};
}} // namespace boost::python
#endif // BASE_TYPE_TRAITS_DWA2002614_HPP

View File

@@ -1,68 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BASES_DWA2002321_HPP
# define BASES_DWA2002321_HPP
# include <boost/python/detail/prefix.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

@@ -1,21 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BORROWED_DWA2002614_HPP
# define BORROWED_DWA2002614_HPP
# include <boost/python/detail/prefix.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

@@ -1,79 +0,0 @@
#if !defined(BOOST_PP_IS_ITERATING)
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# ifndef CALL_DWA2002411_HPP
# define CALL_DWA2002411_HPP
# include <boost/python/detail/prefix.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
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, call.hpp)
# endif
# define N BOOST_PP_ITERATION()
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
)
{
PyObject* const result =
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)
);
// This conversion *must not* be done in the same expression as
// the call, because, in the special case where the result is a
// reference a Python object which was created by converting a C++
// argument for passing to PyEval_CallFunction, its reference
// count will be 2 until the end of the full expression containing
// the conversion, and that interferes with dangling
// pointer/reference detection.
converter::return_from_python<R> converter;
return converter(result);
}
# undef N
#endif

View File

@@ -1,79 +0,0 @@
#if !defined(BOOST_PP_IS_ITERATING)
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# ifndef CALL_METHOD_DWA2002411_HPP
# define CALL_METHOD_DWA2002411_HPP
# include <boost/python/detail/prefix.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
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
# endif
# define N BOOST_PP_ITERATION()
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
)
{
PyObject* const result =
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)
);
// This conversion *must not* be done in the same expression as
// the call, because, in the special case where the result is a
// reference a Python object which was created by converting a C++
// argument for passing to PyEval_CallFunction, its reference
// count will be 2 until the end of the full expression containing
// the conversion, and that interferes with dangling
// pointer/reference detection.
converter::return_from_python<R> converter;
return converter(result);
}
# undef N
#endif // BOOST_PP_IS_ITERATING

View File

@@ -1,106 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef CAST_DWA200269_HPP
# define CAST_DWA200269_HPP
# include <boost/python/detail/prefix.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;
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

@@ -1,654 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef CLASS_DWA200216_HPP
# define CLASS_DWA200216_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/noncopyable.hpp>
# include <boost/python/class_fwd.hpp>
# include <boost/python/object/class.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/python/object/class_metadata.hpp>
# include <boost/python/object/pickle_support.hpp>
# include <boost/python/object/add_to_namespace.hpp>
# include <boost/python/detail/overloads_fwd.hpp>
# include <boost/python/detail/operator_id.hpp>
# include <boost/python/detail/def_helper.hpp>
# include <boost/python/detail/force_instantiate.hpp>
# include <boost/python/detail/unwrap_type_id.hpp>
# include <boost/python/detail/unwrap_wrapper.hpp>
# include <boost/type_traits/is_same.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/detail/workaround.hpp>
# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) \
/* pro9 reintroduced the bug */ \
|| (BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) \
|| BOOST_WORKAROUND(__GNUC__, < 3)
# define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1
# endif
# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
# include <boost/mpl/and.hpp>
# include <boost/type_traits/is_member_pointer.hpp>
# endif
namespace boost { namespace python {
template <class DerivedVisitor> class def_visitor;
enum no_init_t { no_init };
namespace detail
{
// This function object is used with mpl::for_each to write the id
// of the type a pointer to which is passed as its 2nd compile-time
// argument. into the iterator pointed to by its runtime argument
struct write_type_id
{
write_type_id(type_info**p) : p(p) {}
// Here's the runtime behavior
template <class T>
void operator()(T*) const
{
*(*p)++ = type_id<T>();
}
type_info** p;
};
template <class T>
struct is_data_member_pointer
: mpl::and_<
is_member_pointer<T>
, mpl::not_<is_member_function_pointer<T> >
>
{};
# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
# define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , detail::is_data_member_pointer<D>()
# define BOOST_PYTHON_YES_DATA_MEMBER , mpl::true_
# define BOOST_PYTHON_NO_DATA_MEMBER , mpl::false_
# elif defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
# define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , 0
# define BOOST_PYTHON_YES_DATA_MEMBER , int
# define BOOST_PYTHON_NO_DATA_MEMBER , ...
# else
# define BOOST_PYTHON_DATA_MEMBER_HELPER(D)
# define BOOST_PYTHON_YES_DATA_MEMBER
# define BOOST_PYTHON_NO_DATA_MEMBER
# endif
namespace error
{
//
// A meta-assertion mechanism which prints nice error messages and
// backtraces on lots of compilers. Usage:
//
// assertion<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 W // 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 class_<W,X1,X2,X3> self;
typedef typename objects::class_metadata<W,X1,X2,X3> metadata;
typedef W wrapped_type;
private: // types
// A helper class which will contain an array of id objects to be
// passed to the base class constructor
struct id_vector
{
typedef typename metadata::bases bases;
id_vector()
{
// Stick the derived class id into the first element of the array
ids[0] = detail::unwrap_type_id((W*)0, (W*)0);
// 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->initialize(i);
}
// 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->initialize(i);
}
public: // member functions
// Generic visitation
template <class Derived>
self& def(def_visitor<Derived> const& visitor)
{
visitor.visit(*this);
return *this;
}
// Wrap a member function or a non-member function which can take
// a T, T cv&, or T cv* as its first parameter, a callable
// python object, or a generic visitor.
template <class F>
self& def(char const* name, F f)
{
this->def_impl(
detail::unwrap_wrapper((W*)0)
, 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(
detail::unwrap_wrapper((W*)0)
, 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(
detail::unwrap_wrapper((W*)0)
, name, fn
, detail::def_helper<A1,A2,A3>(a1,a2,a3)
, &fn);
return *this;
}
//
// Data member access
//
template <class D>
self& def_readonly(char const* name, D const& d, char const* doc=0)
{
return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
template <class D>
self& def_readwrite(char const* name, D const& d, char const* doc=0)
{
return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
template <class D>
self& def_readonly(char const* name, D& d, char const* doc=0)
{
return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
template <class D>
self& def_readwrite(char const* name, D& d, char const* doc=0)
{
return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
// Property creation
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template <class Get>
self& add_property(char const* name, Get fget, char const* docstr = 0)
{
base::add_property(name, this->make_getter(fget), docstr);
return *this;
}
template <class Get, class Set>
self& add_property(char const* name, Get fget, Set fset, char const* docstr = 0)
{
base::add_property(
name, this->make_getter(fget), this->make_setter(fset), docstr);
return *this;
}
# else
private:
template <class Get>
self& add_property_impl(char const* name, Get fget, char const* docstr, int)
{
base::add_property(name, this->make_getter(fget), docstr);
return *this;
}
template <class Get, class Set>
self& add_property_impl(char const* name, Get fget, Set fset, ...)
{
base::add_property(
name, this->make_getter(fget), this->make_setter(fset), 0);
return *this;
}
public:
template <class Get>
self& add_property(char const* name, Get fget)
{
base::add_property(name, this->make_getter(fget), 0);
return *this;
}
template <class Get, class DocStrOrSet>
self& add_property(char const* name, Get fget, DocStrOrSet docstr_or_set)
{
this->add_property_impl(name, this->make_getter(fget), docstr_or_set, 0);
return *this;
}
template <class Get, class Set>
self&
add_property(char const* name, Get fget, Set fset, char const* docstr)
{
base::add_property(
name, this->make_getter(fget), this->make_setter(fset), docstr);
return *this;
}
# endif
template <class Get>
self& add_static_property(char const* name, Get fget)
{
base::add_static_property(name, object(fget));
return *this;
}
template <class Get, class Set>
self& add_static_property(char const* name, Get fget, Set fset)
{
base::add_static_property(name, object(fget), object(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& enable_pickling()
{
this->base::enable_pickling_(false);
return *this;
}
self& staticmethod(char const* name)
{
this->make_method_static(name);
return *this;
}
private: // helper functions
// Builds a method for this class around the given [member]
// function pointer or object, appropriately adjusting the type of
// the first signature argument so that if f is a member of a
// (possibly not wrapped) base class of T, an lvalue argument of
// type T will be required.
//
// @group PropertyHelpers {
template <class F>
object make_getter(F f)
{
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
return this->make_fn_impl(
detail::unwrap_wrapper((W*)0)
, f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
);
}
template <class F>
object make_setter(F f)
{
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
return this->make_fn_impl(
detail::unwrap_wrapper((W*)0)
, f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
);
}
template <class T, class F>
object make_fn_impl(T*, F const& f, mpl::false_, void*, mpl::false_)
{
return python::make_function(f, default_call_policies(), detail::get_signature(f, (T*)0));
}
template <class T, class D, class B>
object make_fn_impl(T*, D B::*pm_, mpl::false_, char*, mpl::true_)
{
D T::*pm = pm_;
return python::make_getter(pm);
}
template <class T, class D, class B>
object make_fn_impl(T*, D B::*pm_, mpl::false_, int*, mpl::true_)
{
D T::*pm = pm_;
return python::make_setter(pm);
}
template <class T, class F>
object make_fn_impl(T*, F const& x, mpl::true_, void*, mpl::false_)
{
return x;
}
// }
template <class D, class B>
self& def_readonly_impl(
char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
{
return this->add_property(name, pm_, doc);
}
template <class D, class B>
self& def_readwrite_impl(
char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
{
return this->add_property(name, pm_, pm_, doc);
}
template <class D>
self& def_readonly_impl(
char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
{
return this->add_static_property(name, python::make_getter(d));
}
template <class D>
self& def_readwrite_impl(
char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
{
return this->add_static_property(name, python::make_getter(d), python::make_setter(d));
}
template <class DefVisitor>
inline void initialize(DefVisitor const& i)
{
metadata::register_(); // set up runtime metadata/conversions
typedef typename metadata::holder holder;
this->set_instance_size( objects::additional_instance_size<holder>::value );
this->def(i);
}
inline void initialize(no_init_t)
{
metadata::register_(); // set up runtime metadata/conversions
this->def_no_init();
}
//
// These two overloads discriminate between def() as applied to a
// generic visitor and everything else.
//
// @group def_impl {
template <class T, class Helper, class LeafVisitor, class Visitor>
inline void def_impl(
T*
, char const* name
, LeafVisitor
, Helper const& helper
, def_visitor<Visitor> const* v
)
{
v->visit(*this, name, helper);
}
template <class T, class Fn, class Helper>
inline void def_impl(
T*
, char const* name
, Fn fn
, Helper const& helper
, ...
)
{
objects::add_to_namespace(
*this
, name
, make_function(
fn
, helper.policies()
, helper.keywords()
, detail::get_signature(fn, (T*)0)
)
, helper.doc()
);
this->def_default(name, fn, helper, mpl::bool_<Helper::has_default_implementation>());
}
// }
//
// These two overloads handle the definition of default
// implementation overloads for virtual functions. The second one
// handles the case where no default implementation was specified.
//
// @group def_default {
template <class Fn, class Helper>
inline void def_default(
char const* name
, Fn
, Helper const& helper
, mpl::bool_<true>)
{
detail::error::virtual_function_default<W,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.
//
// @group def_maybe_overloads {
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(
detail::unwrap_wrapper((W*)0)
, name
, fn
, detail::def_helper<A1>(a1)
, &fn
);
}
// }
};
//
// implementations
//
template <class W, class X1, class X2, class X3>
inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc)
: base(name, id_vector::size, id_vector().ids, doc)
{
this->initialize(init<>());
// select_holder::assert_default_constructible();
}
template <class W, class X1, class X2, class X3>
inline class_<W,X1,X2,X3>::class_(char const* name, no_init_t)
: base(name, id_vector::size, id_vector().ids)
{
this->initialize(no_init);
}
template <class W, class X1, class X2, class X3>
inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
: base(name, id_vector::size, id_vector().ids, doc)
{
this->initialize(no_init);
}
}} // namespace boost::python
# undef BOOST_PYTHON_DATA_MEMBER_HELPER
# undef BOOST_PYTHON_YES_DATA_MEMBER
# undef BOOST_PYTHON_NO_DATA_MEMBER
# undef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
#endif // CLASS_DWA200216_HPP

View File

@@ -1,24 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef CLASS_FWD_DWA200222_HPP
# define CLASS_FWD_DWA200222_HPP
# include <boost/python/detail/prefix.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

@@ -1,336 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ARG_FROM_PYTHON_DWA2002127_HPP
# define ARG_FROM_PYTHON_DWA2002127_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/converter/from_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/eval_if.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/and.hpp>
# include <boost/mpl/or.hpp>
# include <boost/mpl/not.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()() 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()() 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()() 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()();
private:
rvalue_from_python_data<result_type> m_data;
PyObject* m_source;
};
// ==================
// 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()();
private:
typedef boost::python::arg_from_python<typename T::type> base;
PyObject* m_source;
};
// ==================
template <class C, class T, class F>
struct if_2
{
typedef typename mpl::eval_if<C, mpl::identity<T>, F>::type type;
};
// This metafunction selects the appropriate arg_from_python converter
// type for an argument of type T.
template <class T>
struct select_arg_from_python
{
typedef typename if_2<
is_object_manager<T>
, object_manager_value_arg_from_python<T>
, if_2<
is_reference_to_object_manager<T>
, object_manager_ref_arg_from_python<T>
, if_2<
is_pointer<T>
, pointer_arg_from_python<T>
, if_2<
mpl::and_<
indirect_traits::is_reference_to_pointer<T>
, indirect_traits::is_reference_to_const<T>
, mpl::not_<indirect_traits::is_reference_to_volatile<T> >
>
, pointer_cref_arg_from_python<T>
, if_2<
mpl::or_<
indirect_traits::is_reference_to_non_const<T>
, indirect_traits::is_reference_to_volatile<T>
>
, reference_arg_from_python<T>
, mpl::if_<
boost::python::is_back_reference<T>
, back_reference_arg_from_python<T>
, arg_rvalue_from_python<T>
>
>
>
>
>
>::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()() const
{
return (*(void**)m_result.bytes == Py_None) // None ==> 0
? detail::null_ptr_reference((T(*)())0)
// Otherwise, return a U*const& to the m_result storage.
: python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
}
// 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()() const
{
return (result() == 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()() 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))
, m_source(obj)
{
}
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()()
{
if (m_data.stage1.construct != 0)
m_data.stage1.construct(m_source, &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), m_source(x)
{
}
template <class T>
inline T
back_reference_arg_from_python<T>::operator()()
{
return T(m_source, base::operator()());
}
}}} // namespace boost::python::converter
#endif // ARG_FROM_PYTHON_DWA2002127_HPP

View File

@@ -1,261 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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>
, indirect_traits::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

@@ -1,32 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ARG_TO_PYTHON_BASE_DWA200237_HPP
# define ARG_TO_PYTHON_BASE_DWA200237_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

@@ -1,49 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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 void convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0) {}
template <class U>
static void convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...) {}
static PyObject* convert(void const* x)
{
convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L);
// Yes, the const_cast below opens a hole in const-correctness,
// but it's needed to convert auto_ptr<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)));
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const * get_pytype() { return ToPython::get_pytype(); }
#endif
};
}}} // namespace boost::python::converter
#endif // AS_TO_PYTHON_FUNCTION_DWA2002121_HPP

View File

@@ -1,153 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP
# define BUILTIN_CONVERTERS_DWA2002124_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/ssize_t.hpp>
# include <boost/implicit_cast.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, pytype)\
template <> struct to_python_value<T&> \
: detail::builtin_to_python \
{ \
inline PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
inline PyTypeObject const* get_pytype() const \
{ \
return (pytype); \
} \
}; \
template <> struct to_python_value<T const&> \
: detail::builtin_to_python \
{ \
inline PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
inline PyTypeObject const* get_pytype() const \
{ \
return (pytype); \
} \
};
# 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, pytype) \
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr, pytype) \
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), &PyInt_Type) \
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), &PyInt_Type)
// Bool is not signed.
#if PY_VERSION_HEX >= 0x02030000
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type)
#else
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x), &PyInt_Type)
#endif
// note: handles signed char and unsigned char, but not char (see below)
BOOST_PYTHON_TO_INT(char)
BOOST_PYTHON_TO_INT(short)
BOOST_PYTHON_TO_INT(int)
BOOST_PYTHON_TO_INT(long)
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
# ifdef HAVE_LONG_LONG
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
# endif
# undef BOOST_TO_PYTHON_INT
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
# endif
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x), 0)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE
# undef BOOST_PYTHON_TO_PYTHON_BY_VALUE
# undef BOOST_PYTHON_TO_INT
namespace converter
{
void initialize_builtin_converters();
}
}} // namespace boost::python::converter
#endif // BUILTIN_CONVERTERS_DWA2002124_HPP

View File

@@ -1,17 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,17 +0,0 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
# define CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
namespace boost { namespace python { namespace converter {
// A ResultConverter base class used to indicate that this result
// converter should be constructed with the original Python argument
// list.
struct context_result_converter {};
}}} // namespace boost::python::converter
#endif // CONTEXT_RESULT_CONVERTER_DWA2003917_HPP

View File

@@ -1,14 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,41 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FIND_FROM_PYTHON_DWA2002223_HPP
# define FIND_FROM_PYTHON_DWA2002223_HPP
# include <boost/python/detail/prefix.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

@@ -1,46 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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;
arg_from_python<Source> get_source(obj);
bool convertible = get_source.convertible();
BOOST_ASSERT(convertible);
new (storage) Target(get_source());
// record successful construction
data->convertible = storage;
}
};
}}} // namespace boost::python::converter
#endif // IMPLICIT_DWA2002326_HPP

View File

@@ -1,121 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
# include <boost/python/detail/prefix.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()() 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()() 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()() const
{
return T(python::detail::borrowed_reference(m_source));
}
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()() 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

@@ -1,230 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,68 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,44 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef PYOBJECT_TRAITS_DWA2002720_HPP
# define PYOBJECT_TRAITS_DWA2002720_HPP
# include <boost/python/detail/prefix.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; }
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const* get_pytype() { return 0; }
#endif
};
//
// 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

@@ -1,37 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef PYOBJECT_TYPE_DWA2002720_HPP
# define PYOBJECT_TYPE_DWA2002720_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)
);
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const* get_pytype() { return pytype; }
#endif
};
}}} // namespace boost::python::converter
#endif // PYOBJECT_TYPE_DWA2002720_HPP

View File

@@ -1,132 +0,0 @@
// Copyright David Abrahams 2002, Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef WRAP_PYTYPE_NM20070606_HPP
# define WRAP_PYTYPE_NM20070606_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/unwind_type.hpp>
namespace boost { namespace python {
namespace converter
{
template <PyTypeObject const* python_type>
struct wrap_pytype
{
static PyTypeObject const* get_pytype()
{
return python_type;
}
};
typedef PyTypeObject const* (*pytype_function)();
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
namespace detail
{
struct unwind_type_id_helper{
typedef python::type_info result_type;
template <class U>
static result_type execute(U* ){
return python::type_id<U>();
}
};
template <class T>
inline python::type_info unwind_type_id_(boost::type<T>* = 0, mpl::false_ * =0)
{
return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
}
inline python::type_info unwind_type_id_(boost::type<void>* = 0, mpl::true_* =0)
{
return type_id<void>();
}
template <class T>
inline python::type_info unwind_type_id(boost::type<T>* p= 0)
{
return unwind_type_id_(p, (mpl::bool_<boost::is_void<T>::value >*)0 );
}
}
template <class T>
struct expected_pytype_for_arg
{
static PyTypeObject const *get_pytype()
{
const converter::registration *r=converter::registry::query(
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
);
return r ? r->expected_from_python_type(): 0;
}
};
template <class T>
struct registered_pytype
{
static PyTypeObject const *get_pytype()
{
const converter::registration *r=converter::registry::query(
detail::unwind_type_id_((boost::type<T>*) 0, (mpl::bool_<boost::is_void<T>::value >*)0 )
);
return r ? r->m_class_object: 0;
}
};
template <class T>
struct registered_pytype_direct
{
static PyTypeObject const* get_pytype()
{
return registered<T>::converters.m_class_object;
}
};
template <class T>
struct expected_from_python_type : expected_pytype_for_arg<T>{};
template <class T>
struct expected_from_python_type_direct
{
static PyTypeObject const* get_pytype()
{
return registered<T>::converters.expected_from_python_type();
}
};
template <class T>
struct to_python_target_type
{
static PyTypeObject const *get_pytype()
{
const converter::registration *r=converter::registry::query(
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
);
return r ? r->to_python_target_type(): 0;
}
};
template <class T>
struct to_python_target_type_direct
{
static PyTypeObject const *get_pytype()
{
return registered<T>::converters.to_python_target_type();
}
};
#endif
}}} // namespace boost::python
#endif // WRAP_PYTYPE_NM20070606_HPP

View File

@@ -1,42 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
# define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/detail/raw_pyobject.hpp>
# include <boost/python/cast.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

@@ -1,111 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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>
# include <boost/type_traits/is_void.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/python/type_id.hpp>
# include <boost/type.hpp>
namespace boost {
// You'll see shared_ptr mentioned in this header because we need to
// note which types are shared_ptrs in their registrations, to
// implement special shared_ptr handling for rvalue conversions.
template <class T> class shared_ptr;
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
>
{
};
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
// collapses a few more types to the same static instance. MSVC7.1
// fails to strip cv-qualification from array types in typeid. For
// some reason we can't use this collapse there or array converters
// will not be found.
template <class T>
struct registered<T&>
: registered<T> {};
# endif
//
// implementations
//
namespace detail
{
inline void
register_shared_ptr0(...)
{
}
template <class T>
inline void
register_shared_ptr0(shared_ptr<T>*)
{
registry::lookup_shared_ptr(type_id<shared_ptr<T> >());
}
template <class T>
inline void
register_shared_ptr1(T const volatile*)
{
detail::register_shared_ptr0((T*)0);
}
template <class T>
inline registration const&
registry_lookup2(T&(*)())
{
detail::register_shared_ptr1((T*)0);
return registry::lookup(type_id<T&>());
}
template <class T>
inline registration const&
registry_lookup1(type<T>)
{
return registry_lookup2((T(*)())0);
}
inline registration const&
registry_lookup1(type<const volatile void>)
{
detail::register_shared_ptr1((void*)0);
return registry::lookup(type_id<void>());
}
template <class T>
registration const& registered_base<T>::converters = detail::registry_lookup1(type<T>());
}
}}} // namespace boost::python::converter
#endif // REGISTERED_DWA2002710_HPP

View File

@@ -1,62 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,99 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef REGISTRATIONS_DWA2002223_HPP
# define REGISTRATIONS_DWA2002223_HPP
# include <boost/python/detail/prefix.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/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;
PyTypeObject const* (*expected_pytype)();
rvalue_from_python_chain* next;
};
struct BOOST_PYTHON_DECL registration
{
public: // member functions
explicit registration(type_info target, bool is_shared_ptr = false);
~registration();
// 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;
// Return common denominator of the python class objects,
// convertable to target. Inspects the m_class_object and the value_chains.
PyTypeObject const* expected_from_python_type() const;
PyTypeObject const* to_python_target_type() 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;
PyTypeObject const* (*m_to_python_target_type)();
// True iff this type is a shared_ptr. Needed for special rvalue
// from_python handling.
const bool is_shared_ptr;
# 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, bool is_shared_ptr)
: target_type(target_type)
, lvalue_chain(0)
, rvalue_chain(0)
, m_class_object(0)
, m_to_python(0)
, m_to_python_target_type(0)
, is_shared_ptr(is_shared_ptr)
{}
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

@@ -1,55 +0,0 @@
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef REGISTRY_DWA20011127_HPP
# define REGISTRY_DWA20011127_HPP
# include <boost/python/type_id.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 necessary
BOOST_PYTHON_DECL registration const& lookup(type_info);
// Get the registration corresponding to the type, creating it if
// necessary. Use this first when the type is a shared_ptr.
BOOST_PYTHON_DECL registration const& lookup_shared_ptr(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, PyTypeObject const* (*to_python_target_type)() = 0);
// Insert an lvalue from_python converter
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info, PyTypeObject const* (*expected_pytype)() = 0);
// Insert an rvalue from_python converter
BOOST_PYTHON_DECL void insert(
convertible_function
, constructor_function
, type_info
, PyTypeObject const* (*expected_pytype)() = 0
);
// 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
, PyTypeObject const* (*expected_pytype)() = 0
);
}
}}} // namespace boost::python::converter
#endif // REGISTRY_DWA20011127_HPP

View File

@@ -1,162 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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/converter/object_manager.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/python/detail/void_return.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/handle.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

@@ -1,140 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,22 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,59 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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>
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/registered.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/shared_ptr.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> >()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &converter::expected_from_python_type_direct<T>::get_pytype
#endif
);
}
private:
static void* convertible(PyObject* p)
{
if (p == Py_None)
return p;
return converter::get_lvalue_from_python(p, registered<T>::converters);
}
static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
{
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;
}
};
}}} // namespace boost::python::converter
#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP

View File

@@ -1,28 +0,0 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#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>
# include <boost/get_pointer.hpp>
namespace boost { namespace python { namespace converter {
template <class T>
PyObject* shared_ptr_to_python(shared_ptr<T> const& x)
{
if (!x)
return python::detail::none();
else if (shared_ptr_deleter* d = boost::get_deleter<shared_ptr_deleter>(x))
return incref( get_pointer( d->owner ) );
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

@@ -1,19 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
# include <boost/python/detail/prefix.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

@@ -1,43 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef COPY_CONST_REFERENCE_DWA2002131_HPP
# define COPY_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/prefix.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<
indirect_traits::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

@@ -1,43 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef COPY_NON_CONST_REFERENCE_DWA2002131_HPP
# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/prefix.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<
indirect_traits::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

@@ -1,316 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DATA_MEMBERS_DWA2002328_HPP
# define DATA_MEMBERS_DWA2002328_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/return_by_value.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/python/detail/not_specified.hpp>
# include <boost/python/detail/value_arg.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/is_member_pointer.hpp>
# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
# include <boost/type_traits/remove_cv.hpp>
# endif
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/vector/vector10.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python {
//
// This file defines the make_getter and make_setter function
// families, which are responsible for turning pointers, references,
// and pointers-to-data-members into callable Python objects which
// can be used for attribute access on wrapped classes.
//
namespace detail
{
// A small function object which handles the getting and setting of
// data members.
template <class Data, class Class>
struct member
{
public:
member(Data Class::*which) : m_which(which) {}
Data& operator()(Class& c) const
{
return c.*m_which;
}
void operator()(Class& c, typename value_arg<Data>::type d) const
{
c.*m_which = d;
}
private:
Data Class::*m_which;
};
// A small function object which handles the getting and setting of
// non-member objects.
template <class Data>
struct datum
{
public:
datum(Data *which) : m_which(which) {}
Data& operator()() const
{
return *m_which;
}
void operator()(typename value_arg<Data>::type d) const
{
*m_which = d;
}
private:
Data *m_which;
};
//
// Helper metafunction for determining the default CallPolicy to use
// for attribute access. If T is a [reference to a] class type X
// whose conversion to python would normally produce a new copy of X
// in a wrapped X class instance (as opposed to types such as
// std::string, which are converted to native Python types, and
// smart pointer types which produce a wrapped class instance of the
// pointee type), to-python conversions will attempt to produce an
// object which refers to the original C++ object, rather than a
// copy. See default_member_getter_policy for rationale.
//
template <class T>
struct default_getter_by_ref
: mpl::and_<
mpl::bool_<
to_python_value<
typename value_arg<T>::type
>::uses_registry
>
, indirect_traits::is_reference_to_class<
typename value_arg<T>::type
>
>
{
};
// Metafunction computing the default CallPolicy to use for reading
// data members
//
// If it's a regular class type (not an object manager or other
// type for which we have to_python specializations, use
// return_internal_reference so that we can do things like
// x.y.z = 1
// and get the right result.
template <class T>
struct default_member_getter_policy
: mpl::if_<
default_getter_by_ref<T>
, return_internal_reference<>
, return_value_policy<return_by_value>
>
{};
// Metafunction computing the default CallPolicy to use for reading
// non-member data.
template <class T>
struct default_datum_getter_policy
: mpl::if_<
default_getter_by_ref<T>
, return_value_policy<reference_existing_object>
, return_value_policy<return_by_value>
>
{};
//
// make_getter helper function family -- These helpers to
// boost::python::make_getter are used to dispatch behavior. The
// third argument is a workaround for a CWPro8 partial ordering bug
// with pointers to data members. It should be convertible to
// mpl::true_ iff the first argument is a pointer-to-member, and
// mpl::false_ otherwise. The fourth argument is for compilers
// which don't support partial ordering at all and should always be
// passed 0L.
//
#if BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
template <class D, class P>
inline object make_getter(D& d, P& p, mpl::false_, ...);
#endif
// Handle non-member pointers with policies
template <class D, class Policies>
inline object make_getter(D* d, Policies const& policies, mpl::false_, int)
{
return python::make_function(
detail::datum<D>(d), policies, mpl::vector1<D&>()
);
}
// Handle non-member pointers without policies
template <class D>
inline object make_getter(D* d, not_specified, mpl::false_, long)
{
typedef typename default_datum_getter_policy<D>::type policies;
return detail::make_getter(d, policies(), mpl::false_(), 0);
}
// Handle pointers-to-members with policies
template <class C, class D, class Policies>
inline object make_getter(D C::*pm, Policies const& policies, mpl::true_, int)
{
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
typedef typename remove_cv<C>::type Class;
#else
typedef C Class;
#endif
return python::make_function(
detail::member<D,Class>(pm)
, policies
, mpl::vector2<D&,Class&>()
);
}
// Handle pointers-to-members without policies
template <class C, class D>
inline object make_getter(D C::*pm, not_specified, mpl::true_, long)
{
typedef typename default_member_getter_policy<D>::type policies;
return detail::make_getter(pm, policies(), mpl::true_(), 0);
}
// Handle references
template <class D, class P>
inline object make_getter(D& d, P& p, mpl::false_, ...)
{
// Just dispatch to the handler for pointer types.
return detail::make_getter(&d, p, mpl::false_(), 0L);
}
//
// make_setter helper function family -- These helpers to
// boost::python::make_setter are used to dispatch behavior. The
// third argument is for compilers which don't support partial
// ordering at all and should always be passed 0.
//
// Handle non-member pointers
template <class D, class Policies>
inline object make_setter(D* p, Policies const& policies, mpl::false_, int)
{
return python::make_function(
detail::datum<D>(p), policies, mpl::vector2<void,D const&>()
);
}
// Handle pointers-to-members
template <class C, class D, class Policies>
inline object make_setter(D C::*pm, Policies const& policies, mpl::true_, int)
{
return python::make_function(
detail::member<D,C>(pm)
, policies
, mpl::vector3<void, C&, D const&>()
);
}
// Handle references
template <class D, class Policies>
inline object make_setter(D& x, Policies const& policies, mpl::false_, ...)
{
return detail::make_setter(&x, policies, mpl::false_(), 0L);
}
}
//
// make_getter function family -- build a callable object which
// retrieves data through the first argument and is appropriate for
// use as the `get' function in Python properties . The second,
// policies argument, is optional. We need both D& and D const&
// overloads in order be able to handle rvalues.
//
template <class D, class Policies>
inline object make_getter(D& d, Policies const& policies)
{
return detail::make_getter(d, policies, is_member_pointer<D>(), 0L);
}
template <class D, class Policies>
inline object make_getter(D const& d, Policies const& policies)
{
return detail::make_getter(d, policies, is_member_pointer<D>(), 0L);
}
template <class D>
inline object make_getter(D& x)
{
detail::not_specified policy;
return detail::make_getter(x, policy, is_member_pointer<D>(), 0L);
}
# if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template <class D>
inline object make_getter(D const& d)
{
detail::not_specified policy;
return detail::make_getter(d, policy, is_member_pointer<D>(), 0L);
}
# endif
//
// make_setter function family -- build a callable object which
// writes data through the first argument and is appropriate for
// use as the `set' function in Python properties . The second,
// policies argument, is optional. We need both D& and D const&
// overloads in order be able to handle rvalues.
//
template <class D, class Policies>
inline object make_setter(D& x, Policies const& policies)
{
return detail::make_setter(x, policies, is_member_pointer<D>(), 0);
}
template <class D, class Policies>
inline object make_setter(D const& x, Policies const& policies)
{
return detail::make_setter(x, policies, is_member_pointer<D>(), 0);
}
template <class D>
inline object make_setter(D& x)
{
return detail::make_setter(x, default_call_policies(), is_member_pointer<D>(), 0);
}
# if !(BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__EDG_VERSION__, <= 238))
template <class D>
inline object make_setter(D const& x)
{
return detail::make_setter(x, default_call_policies(), is_member_pointer<D>(), 0);
}
# endif
}} // namespace boost::python
#endif // DATA_MEMBERS_DWA2002328_HPP

View File

@@ -1,114 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DEF_DWA200292_HPP
# define DEF_DWA200292_HPP
# include <boost/python/detail/prefix.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

@@ -1,86 +0,0 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DEF_VISITOR_DWA2003810_HPP
# define DEF_VISITOR_DWA2003810_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python {
template <class DerivedVisitor> class def_visitor;
template <class T, class X1, class X2, class X3> class class_;
class def_visitor_access
{
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends.
public:
# else
template <class Derived> friend class def_visitor;
# endif
// unnamed visit, c.f. init<...>, container suites
template <class V, class classT>
static void visit(V const& v, classT& c)
{
v.derived_visitor().visit(c);
}
// named visit, c.f. object, pure_virtual
template <class V, class classT, class OptionalArgs>
static void visit(
V const& v
, classT& c
, char const* name
, OptionalArgs const& options
)
{
v.derived_visitor().visit(c, name, options);
}
};
template <class DerivedVisitor>
class def_visitor
{
friend class def_visitor_access;
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends.
public:
# else
template <class T, class X1, class X2, class X3> friend class class_;
# endif
// unnamed visit, c.f. init<...>, container suites
template <class classT>
void visit(classT& c) const
{
def_visitor_access::visit(*this, c);
}
// named visit, c.f. object, pure_virtual
template <class classT, class OptionalArgs>
void visit(classT& c, char const* name, OptionalArgs const& options) const
{
def_visitor_access::visit(*this, c, name, options);
}
protected:
DerivedVisitor const& derived_visitor() const
{
return static_cast<DerivedVisitor const&>(*this);
}
};
}} // namespace boost::python
#endif // DEF_VISITOR_DWA2003810_HPP

View File

@@ -1,91 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP
# define DEFAULT_CALL_POLICIES_DWA2002131_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/to_python_value.hpp>
# include <boost/python/detail/value_arg.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/mpl/or.hpp>
# include <boost/mpl/front.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
{
// Ownership of this argument tuple will ultimately be adopted by
// the caller.
template <class ArgumentPackage>
static bool precall(ArgumentPackage const&)
{
return true;
}
// Pass the result through
template <class ArgumentPackage>
static PyObject* postcall(ArgumentPackage const&, PyObject* result)
{
return result;
}
typedef default_result_converter result_converter;
typedef PyObject* argument_package;
template <class Sig>
struct extract_return_type : mpl::front<Sig>
{
};
};
struct default_result_converter
{
template <class R>
struct apply
{
typedef typename mpl::if_<
mpl::or_<is_pointer<R>, is_reference<R> >
, detail::specify_a_return_value_policy_to_wrap_functions_returning<R>
, boost::python::to_python_value<
typename detail::value_arg<R>::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

@@ -1,26 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef AIX_INIT_MODULE_DWA2002529_HPP
# define AIX_INIT_MODULE_DWA2002529_HPP
# ifdef _AIX
# include <boost/python/detail/prefix.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

@@ -1,15 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// DEPRECATED HEADER (2006 Jan 12)
// Provided only for backward compatibility.
// The boost::python::len() function is now defined in object.hpp.
#ifndef BOOST_PYTHON_API_PLACE_HOLDER_HPP
#define BOOST_PYTHON_API_PLACE_HOLDER_HPP
#include <boost/python/object.hpp>
#endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP

View File

@@ -1,111 +0,0 @@
#ifndef BORROWED_PTR_DWA20020601_HPP
# define BORROWED_PTR_DWA20020601_HPP
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# include <boost/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

@@ -1,259 +0,0 @@
#if !defined(BOOST_PP_IS_ITERATING)
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# ifndef CALLER_DWA20021121_HPP
# define CALLER_DWA20021121_HPP
# include <boost/python/type_id.hpp>
# include <boost/python/handle.hpp>
# include <boost/detail/indirect_traits.hpp>
# include <boost/python/detail/invoke.hpp>
# include <boost/python/detail/signature.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/python/converter/context_result_converter.hpp>
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/dec.hpp>
# include <boost/preprocessor/if.hpp>
# include <boost/preprocessor/iteration/local.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/preprocessor/repetition/repeat.hpp>
# include <boost/compressed_pair.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/mpl/apply.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/at.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/next.hpp>
namespace boost { namespace python { namespace detail {
template <int N>
inline PyObject* get(mpl::int_<N>, PyObject* const& args_)
{
return PyTuple_GET_ITEM(args_,N);
}
inline unsigned arity(PyObject* const& args_)
{
return PyTuple_GET_SIZE(args_);
}
// This "result converter" is really just used as
// a dispatch tag to invoke(...), selecting the appropriate
// implementation
typedef int void_result_to_python;
// 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::eval_if<
is_same<Result,void>
, mpl::identity<void_result_to_python>
, mpl::apply1<typename Policies::result_converter,Result>
>
{
};
template <class ArgPackage, class ResultConverter>
inline ResultConverter create_result_converter(
ArgPackage const& args_
, ResultConverter*
, converter::context_result_converter*
)
{
return ResultConverter(args_);
}
template <class ArgPackage, class ResultConverter>
inline ResultConverter create_result_converter(
ArgPackage const&
, ResultConverter*
, ...
)
{
return ResultConverter();
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
template <class ResultConverter>
struct converter_target_type
{
static PyTypeObject const *get_pytype()
{
return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
}
};
template < >
struct converter_target_type <void_result_to_python >
{
static PyTypeObject const *get_pytype()
{
return 0;
}
};
#endif
template <unsigned> struct caller_arity;
template <class F, class CallPolicies, class Sig>
struct caller;
# define BOOST_PYTHON_NEXT(init,name,n) \
typedef BOOST_PP_IF(n,typename mpl::next< BOOST_PP_CAT(name,BOOST_PP_DEC(n)) >::type, init) name##n;
# define BOOST_PYTHON_ARG_CONVERTER(n) \
BOOST_PYTHON_NEXT(typename mpl::next<first>::type, arg_iter,n) \
typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \
c_t##n c##n(get(mpl::int_<n>(), inner_args)); \
if (!c##n.convertible()) \
return 0;
# define BOOST_PP_ITERATION_PARAMS_1 \
(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 CallPolicies, class Sig>
struct caller_base_select
{
enum { arity = mpl::size<Sig>::value - 1 };
typedef typename caller_arity<arity>::template impl<F,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.
//
// 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 CallPolicies, class Sig>
struct caller
: caller_base_select<F,CallPolicies,Sig>::type
{
typedef typename caller_base_select<
F,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 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;
typedef typename Policies::argument_package argument_package;
argument_package inner_args(args_);
# if N
# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
# define BOOST_PP_LOCAL_LIMITS (0, N-1)
# 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(inner_args))
return 0;
PyObject* result = detail::invoke(
detail::invoke_tag<result_t,F>()
, create_result_converter(args_, (result_converter*)0, (result_converter*)0)
, m_data.first()
BOOST_PP_ENUM_TRAILING_PARAMS(N, c)
);
return m_data.second().postcall(inner_args, result);
}
static unsigned min_arity() { return N; }
static py_func_sig_info signature()
{
const signature_element * sig = detail::signature<Sig>::elements();
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
typedef typename select_result_converter<Policies, rtype>::type result_converter;
static const signature_element ret = {
(boost::is_void<rtype>::value ? "void" : type_id<rtype>().name())
, &detail::converter_target_type<result_converter>::get_pytype
, boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
};
py_func_sig_info res = {sig, &ret };
#else
py_func_sig_info res = {sig, sig };
#endif
return res;
}
private:
compressed_pair<F,Policies> m_data;
};
};
#endif // BOOST_PP_IS_ITERATING

View File

@@ -1,141 +0,0 @@
// (C) Copyright David Abrahams 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
// Revision History:
// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams)
#ifndef CONFIG_DWA052200_H_
# define CONFIG_DWA052200_H_
# include <boost/config.hpp>
# include <boost/detail/workaround.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 < 1300
# 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_NO_STDC_NAMESPACE)
# 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(BOOST_PYTHON_DYNAMIC_LIB)
# if !defined(_WIN32) && !defined(__CYGWIN__) \
&& !defined(BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY) \
&& BOOST_WORKAROUND(__GNUC__, >= 3) && (__GNUC_MINOR__ >=5 || __GNUC__ > 3)
# define BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY 1
# endif
# if BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_DECL __attribute__ ((visibility("default")))
# define BOOST_PYTHON_BUILD_DLL
# else
# define BOOST_PYTHON_DECL
# endif
# define BOOST_PYTHON_DECL_FORWARD
# define BOOST_PYTHON_DECL_EXCEPTION __attribute__ ((visibility("default")))
# elif (defined(_WIN32) || defined(__CYGWIN__))
# if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_DECL __declspec(dllexport)
# define BOOST_PYTHON_BUILD_DLL
# else
# define BOOST_PYTHON_DECL __declspec(dllimport)
# endif
# endif
#endif
#ifndef BOOST_PYTHON_DECL
# define BOOST_PYTHON_DECL
#endif
#ifndef BOOST_PYTHON_DECL_FORWARD
# define BOOST_PYTHON_DECL_FORWARD BOOST_PYTHON_DECL
#endif
#ifndef BOOST_PYTHON_DECL_EXCEPTION
# define BOOST_PYTHON_DECL_EXCEPTION BOOST_PYTHON_DECL
#endif
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
// 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
// enable automatic library variant selection ------------------------------//
#if !defined(BOOST_PYTHON_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_PYTHON_NO_LIB)
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_python
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
#ifdef BOOST_PYTHON_DYNAMIC_LIB
# define BOOST_DYN_LINK
#endif
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
#define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition
#endif
#endif // CONFIG_DWA052200_H_

View File

@@ -1,42 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,38 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,21 +0,0 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#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

@@ -1,36 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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<
::boost::is_const<T>::value
, ::boost::is_volatile<T>::value
> type;
};
}}} // namespace boost::python::detail
#endif // CV_CATEGORY_DWA200222_HPP

View File

@@ -1,17 +0,0 @@
// Copyright Gottfried Ganßauge 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# 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

@@ -1,76 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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 || indirect_traits::is_reference_to_const<T>::value
? decorated_type_info::const_ : 0)
| (is_volatile<T>::value || indirect_traits::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

@@ -1,21 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

@@ -1,212 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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>
# include <boost/python/detail/def_helper_fwd.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_<
indirect_traits::is_reference_to_class<mpl::_1>
, indirect_traits::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> >
, indirect_traits::is_reference_to_class<mpl::_1 >
, mpl::not_<is_reference_to_keywords<mpl::_1 > >
>
>
{
};
template <class Tuple>
struct default_implementation_extract
: tuple_extract<
Tuple
, indirect_traits::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, class T3, class T4>
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
, detail::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

@@ -1,17 +0,0 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DEF_HELPER_FWD_DWA2003810_HPP
# define DEF_HELPER_FWD_DWA2003810_HPP
# include <boost/python/detail/not_specified.hpp>
namespace boost { namespace python { namespace detail {
template <class T1, class T2 = not_specified, class T3 = not_specified, class T4 = not_specified>
struct def_helper;
}}} // namespace boost::python::detail
#endif // DEF_HELPER_FWD_DWA2003810_HPP

View File

@@ -1,291 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright David Abrahams 2002, Joel de Guzman, 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
///////////////////////////////////////////////////////////////////////////////
#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
{
// Called as::
//
// name_space_def(ns, "func", func, kw, policies, docstring, &ns)
//
// Dispatch to properly add f to namespace ns.
//
// @group define_stub_function helpers {
template <class Func, class CallPolicies, class NameSpaceT>
static void name_space_def(
NameSpaceT& name_space
, 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(
f, policies, kw, get_signature(f, (wrapped_type*)0))
, 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 -- is this obsolete?
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);
}
// }
// Expansions of ::
//
// 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
//
// @group define_stub_function<N> {
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()
// }
// 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::vector<int, int>
// void bar(int, int) mpl::vector<void, int, int>
// void C::foo(int) mpl::vector<void, C, int>
//
template <class OverloadsT, class NameSpaceT, class SigT>
inline void
define_with_defaults(
char const* name,
OverloadsT const& overloads,
NameSpaceT& name_space,
SigT const&)
{
typedef typename mpl::front<SigT>::type return_type;
typedef typename OverloadsT::void_return_type void_return_type;
typedef typename OverloadsT::non_void_return_type non_void_return_type;
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

@@ -1,388 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright David Abrahams 2002, Joel de Guzman, 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
///////////////////////////////////////////////////////////////////////////////
#ifndef 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/deref.hpp>
#include <cstddef>
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::deref<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::deref<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::deref<rt_iter>::type RT; \
\
typedef typename ::boost::mpl::next<rt_iter>::type class_iter; \
typedef typename ::boost::mpl::deref<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 <std::size_t N> \
fstubs_name(char const* doc, ::boost::python::detail::keywords<N> const& keywords) \
: ::boost::python::detail::overloads_common<fstubs_name>( \
doc, keywords.range()) \
{ \
typedef typename ::boost::python::detail:: \
error::more_keywords_than_function_arguments< \
N,n_args>::too_many_keywords assertion; \
} \
template <std::size_t N> \
fstubs_name(::boost::python::detail::keywords<N> 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< \
N,n_args>::too_many_keywords assertion; \
}
# if defined(BOOST_NO_VOID_RETURNS)
# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
struct fstubs_name \
: public ::boost::python::detail::overloads_common<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 + 1, 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 + 1, 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

@@ -1,27 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef 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

View File

@@ -1,106 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DESTROY_DWA2002221_HPP
# define DESTROY_DWA2002221_HPP
# include <boost/type_traits/is_array.hpp>
# include <boost/detail/workaround.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
# include <boost/type_traits/is_enum.hpp>
# endif
namespace boost { namespace python { namespace detail {
template <
bool array
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
, bool enum_ // vc7 has a problem destroying enums
# endif
> struct value_destroyer;
template <>
struct value_destroyer<
false
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
, false
# endif
>
{
template <class T>
static void execute(T const volatile* p)
{
p->T::~T();
}
};
template <>
struct value_destroyer<
true
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
, false
# endif
>
{
template <class A, class T>
static void execute(A*, T const volatile* const first)
{
for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p)
{
value_destroyer<
boost::is_array<T>::value
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
, boost::is_enum<T>::value
# endif
>::execute(p);
}
}
template <class T>
static void execute(T const volatile* p)
{
execute(p, *p);
}
};
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
template <>
struct value_destroyer<true,true>
{
template <class T>
static void execute(T const volatile*)
{
}
};
template <>
struct value_destroyer<false,true>
{
template <class T>
static void execute(T const volatile*)
{
}
};
# endif
template <class T>
inline void destroy_referent_impl(void* p, T& (*)())
{
// note: cv-qualification needed for MSVC6
// must come *before* T for metrowerks
value_destroyer<
(boost::is_array<T>::value)
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
, (boost::is_enum<T>::value)
# endif
>::execute((const volatile T*)p);
}
template <class T>
inline void destroy_referent(void* p, T(*)() = 0)
{
destroy_referent_impl(p, (T(*)())0);
}
}}} // namespace boost::python::detail
#endif // DESTROY_DWA2002221_HPP

View File

@@ -1,72 +0,0 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef ENABLE_IF_DWA2004722_HPP
# define ENABLE_IF_DWA2004722_HPP
# include <boost/python/detail/sfinae.hpp>
# include <boost/detail/workaround.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
# include <boost/mpl/if.hpp>
namespace boost { namespace python { namespace detail {
template <class T> struct always_void { typedef void type; };
template <class C, class T = int>
struct enable_if_arg
{
typedef typename mpl::if_<C,T,int&>::type type;
};
template <class C, class T = int>
struct disable_if_arg
{
typedef typename mpl::if_<C,int&,T>::type type;
};
template <class C, class T = typename always_void<C>::type>
struct enable_if_ret
{
typedef typename mpl::if_<C,T,int[2]>::type type;
};
template <class C, class T = typename always_void<C>::type>
struct disable_if_ret
{
typedef typename mpl::if_<C,int[2],T>::type type;
};
}}} // namespace boost::python::detail
# elif !defined(BOOST_NO_SFINAE)
# include <boost/utility/enable_if.hpp>
namespace boost { namespace python { namespace detail {
template <class C, class T = int>
struct enable_if_arg
: enable_if<C,T>
{};
template <class C, class T = int>
struct disable_if_arg
: disable_if<C,T>
{};
template <class C, class T = void>
struct enable_if_ret
: enable_if<C,T>
{};
template <class C, class T = void>
struct disable_if_ret
: disable_if<C,T>
{};
}}} // namespace boost::python::detail
# endif
#endif // ENABLE_IF_DWA2004722_HPP

View File

@@ -1,48 +0,0 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef EXCEPTION_HANDLER_DWA2002810_HPP
# define EXCEPTION_HANDLER_DWA2002810_HPP
# include <boost/python/detail/config.hpp>
# include <boost/function/function0.hpp>
# include <boost/function/function2.hpp>
namespace boost { namespace python { namespace detail {
struct BOOST_PYTHON_DECL_FORWARD exception_handler;
typedef function2<bool, exception_handler const&, function0<void> const&> handler_function;
struct BOOST_PYTHON_DECL exception_handler
{
private: // types
public:
explicit exception_handler(handler_function const& impl);
inline bool handle(function0<void> const& f) const;
bool operator()(function0<void> const& f) const;
static exception_handler* chain;
private:
static exception_handler* tail;
handler_function m_impl;
exception_handler* m_next;
};
inline bool exception_handler::handle(function0<void> const& f) const
{
return this->m_impl(*this, f);
}
BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f);
}}} // namespace boost::python::detail
#endif // EXCEPTION_HANDLER_DWA2002810_HPP

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