mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 16:32:16 +00:00
Compare commits
153 Commits
svn-branch
...
boost-1.59
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99022d2eb8 | ||
|
|
37f8f37cda | ||
|
|
156054371b | ||
|
|
d06f4aeaca | ||
|
|
e8d7bb5027 | ||
|
|
b207fc1a04 | ||
|
|
9742c30f47 | ||
|
|
97f894bc1a | ||
|
|
eefc434bae | ||
|
|
226d1ac961 | ||
|
|
36f8f69411 | ||
|
|
97b0d9737c | ||
|
|
3e405b6fd5 | ||
|
|
e1e9eb303a | ||
|
|
9eee9ef461 | ||
|
|
fe24ab9dd5 | ||
|
|
a911c17fd6 | ||
|
|
8d5d777ebb | ||
|
|
ea87bfee8c | ||
|
|
17a7655c74 | ||
|
|
0a47c583b1 | ||
|
|
e445e193fe | ||
|
|
832a1edd79 | ||
|
|
6b7e0cc71f | ||
|
|
74b9bcaaa5 | ||
|
|
371914a0e0 | ||
|
|
8021a21abb | ||
|
|
9ceb9c02f5 | ||
|
|
97f9a10b9c | ||
|
|
87f776b178 | ||
|
|
590b7887f4 | ||
|
|
badedbebfc | ||
|
|
cc80f46a6d | ||
|
|
42e7d7bbb3 | ||
|
|
5476f97d59 | ||
|
|
da01e9b660 | ||
|
|
a89bf7e9e8 | ||
|
|
52201f0cba | ||
|
|
3480aee9e7 | ||
|
|
ead8d0aba5 | ||
|
|
7a4b240838 | ||
|
|
f500202dab | ||
|
|
ca18dc9daa | ||
|
|
fc3f1bb531 | ||
|
|
8cc149f4f4 | ||
|
|
5f8f5b4c3e | ||
|
|
a3f478e9af | ||
|
|
303885fefa | ||
|
|
46796f3413 | ||
|
|
2c1a276671 | ||
|
|
0b8b88abc7 | ||
|
|
c3d20eb07f | ||
|
|
e32979fe0a | ||
|
|
76db3311ed | ||
|
|
af8efb72bd | ||
|
|
5792bffaa2 | ||
|
|
7acb544b47 | ||
|
|
e3130fe75b | ||
|
|
f054b64315 | ||
|
|
ef6194f1f8 | ||
|
|
b262615aa8 | ||
|
|
842cf85d4b | ||
|
|
9064a063b2 | ||
|
|
5daa36d04d | ||
|
|
fa24dbb88f | ||
|
|
ba5503cf89 | ||
|
|
49e8699b9f | ||
|
|
8449c34948 | ||
|
|
838f44c050 | ||
|
|
6699e8a4a2 | ||
|
|
302fee14b0 | ||
|
|
211c90ae0f | ||
|
|
f1efb481c3 | ||
|
|
3e409f9a87 | ||
|
|
cfa2baf8c9 | ||
|
|
1212a14739 | ||
|
|
8e703e9569 | ||
|
|
faf3cd0b78 | ||
|
|
4df7f1c247 | ||
|
|
201c100422 | ||
|
|
f441ec7dfd | ||
|
|
09dc86f5f2 | ||
|
|
a5e564be83 | ||
|
|
dcc3590907 | ||
|
|
a11a3f9f76 | ||
|
|
74daea3d88 | ||
|
|
4c2927ca46 | ||
|
|
e28f0509d8 | ||
|
|
a8fb9f7746 | ||
|
|
0a211a746d | ||
|
|
2a20884e78 | ||
|
|
ba213663b6 | ||
|
|
b5336f36d6 | ||
|
|
736ba48c2b | ||
|
|
fa32b8dfab | ||
|
|
6066ffef9a | ||
|
|
c501874bc2 | ||
|
|
f759e9eb0e | ||
|
|
cae31b5380 | ||
|
|
76af2cfc6b | ||
|
|
846c5d9914 | ||
|
|
bd8a9eb1fd | ||
|
|
65b3aadc63 | ||
|
|
38e92833f6 | ||
|
|
14ea71e201 | ||
|
|
e13ebcd0e8 | ||
|
|
63a3f188b8 | ||
|
|
34b162738f | ||
|
|
e481c136e5 | ||
|
|
569b395cdd | ||
|
|
ea3c254370 | ||
|
|
ed6e9d6726 | ||
|
|
1f04129832 | ||
|
|
b63d44e781 | ||
|
|
52d7dfffdf | ||
|
|
a3e76d59c3 | ||
|
|
4b9cb5337d | ||
|
|
86db60255a | ||
|
|
37b45d2baf | ||
|
|
471be524f4 | ||
|
|
e485244886 | ||
|
|
b9cd3ff109 | ||
|
|
d804f1250e | ||
|
|
89100353db | ||
|
|
46be73387c | ||
|
|
d685a5e8c5 | ||
|
|
e80224b1ad | ||
|
|
03fdf5b992 | ||
|
|
73b4cd3325 | ||
|
|
f7d31f6ead | ||
|
|
47bb3f55a7 | ||
|
|
6296bd5bc4 | ||
|
|
217250f078 | ||
|
|
29152af56c | ||
|
|
19846f5d79 | ||
|
|
a1924a2a72 | ||
|
|
c205cd86c6 | ||
|
|
8d86dc199c | ||
|
|
55e9ff14a1 | ||
|
|
4fea58f634 | ||
|
|
694ae13063 | ||
|
|
5168895803 | ||
|
|
c8bf94663c | ||
|
|
928a9389ce | ||
|
|
7d22435994 | ||
|
|
96dd880146 | ||
|
|
63f8e9f3d7 | ||
|
|
d9b4ada654 | ||
|
|
f5df393360 | ||
|
|
bf33b54638 | ||
|
|
87451007b9 | ||
|
|
2392a6a3e2 | ||
|
|
6c1e7decfa |
@@ -14,14 +14,20 @@ if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
|
||||
# Attempt default configuration of python
|
||||
import toolset : using ;
|
||||
using python ;
|
||||
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
ECHO "WARNING: No python installation configured and autoconfiguration" ;
|
||||
ECHO " failed. See http://www.boost.org/libs/python/doc/building.html" ;
|
||||
ECHO " for configuration instructions or pass --without-python to" ;
|
||||
ECHO " suppress this message and silently skip all Boost.Python targets" ;
|
||||
}
|
||||
}
|
||||
|
||||
if [ python.configured ] || ( --without-python in [ modules.peek : ARGV ] )
|
||||
{
|
||||
alias config-warning ;
|
||||
}
|
||||
else
|
||||
{
|
||||
message config-warning
|
||||
: "warning: No python installation configured and autoconfiguration"
|
||||
: "note: failed. See http://www.boost.org/libs/python/doc/building.html"
|
||||
: "note: for configuration instructions or pass --without-python to"
|
||||
: "note: suppress this message and silently skip all Boost.Python targets"
|
||||
;
|
||||
}
|
||||
|
||||
rule find-py3-version
|
||||
@@ -122,6 +128,7 @@ rule lib_boost_python ( is-py3 ? )
|
||||
# as it's not possible anyway, and to cause dependents to
|
||||
# fail to build
|
||||
[ unless [ python.configured ] : <build>no ]
|
||||
<dependency>config-warning
|
||||
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
[ cond $(is-py3) : <python>$(py3-version) ]
|
||||
|
||||
28
class.cpp
Normal file
28
class.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct X
|
||||
{
|
||||
int x;
|
||||
X(int n) : x(n) { }
|
||||
};
|
||||
|
||||
int x_function(X& x)
|
||||
{ return x.x;
|
||||
}
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(class_ext)
|
||||
{
|
||||
class_<X>("X", init<int>());
|
||||
def("x_function", x_function);
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -27,7 +27,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
Somerville, MA 02143
|
||||
:Contact: dave@boost-consulting.com
|
||||
:organization: `Boost Consulting`_
|
||||
:date: $Date$
|
||||
:status: This is a "work in progress"
|
||||
:version: 1
|
||||
:copyright: Copyright David Abrahams 2002. All rights reserved
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
:Author: David Goodger
|
||||
:Contact: goodger@users.sourceforge.net
|
||||
:date: $Date$
|
||||
:version: $Revision$
|
||||
:copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
boostinspect:nolicense
|
||||
|
||||
@@ -396,27 +396,33 @@
|
||||
</blockquote>
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
|
||||
LLC</a></b></dt>
|
||||
<dt><b><a href="http://pyrap.googlecode.com/">Pyrap</a></b></dt>
|
||||
<dd>
|
||||
<p><a href="diepen@astron.nl"
|
||||
>Ger van Diepen</a> writes:</p>
|
||||
|
||||
<blockquote>
|
||||
<p>Pyrap is the python interface to the Radio-Astronomical Package
|
||||
casacore (<a href="http://casacore.googlecode.com/"
|
||||
>casacore.googlecode.com</a>). Astronomers love pyrap because
|
||||
it makes it easily possible to get their data (observed with
|
||||
radio-astronomical telescopes like LOFAR, ASKAP, and eVLA) in numpy
|
||||
arrays and do basic data inspection and manipulation using the many
|
||||
python packages that are available.</p>
|
||||
|
||||
<p>Boost.Python made it quite easily possible to create converters for
|
||||
the various data types, also for numpy arrays and individual elements
|
||||
of a numpy array. It's nice they work fully recursively. Mapping C++
|
||||
functions to Python was straightforward.</p>
|
||||
</blockquote>
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="http://www.rdkit.org/"
|
||||
>RDKit: Cheminformatics and Machine Learning Software</a></b></dt>
|
||||
|
||||
<dd>
|
||||
Rational Discovery provides computational modeling, combinatorial
|
||||
library design and custom software development services to the
|
||||
pharmaceutical, biotech and chemical industries. We do a substantial
|
||||
amount of internal research to develop new approaches for applying
|
||||
machine-learning techniques to solve chemical problems. Because we're a
|
||||
small organization and chemistry is a large and complex field, it is
|
||||
essential that we be able to quickly and easily prototype and test new
|
||||
algorithms.
|
||||
|
||||
<p>For our internal software, we implement core data structures in C
|
||||
and expose them to Python using Boost.Python. Algorithm development is
|
||||
done in Python and then translated to C if required (often it's not).
|
||||
This hybrid development approach not only greatly increases our
|
||||
productivity, but it also allows "non-developers" (people without C
|
||||
experience) to take part in method development. Learning C is a
|
||||
daunting task, but "Python fits your brain." (Thanks to Bruce Eckel for
|
||||
the quote.)</p>
|
||||
A collection of cheminformatics and machine-learning software
|
||||
written in C++ and Python.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ boostbook tutorial
|
||||
tutorial.qbk
|
||||
:
|
||||
<xsl:param>boost.root=../../../../../..
|
||||
<xsl:param>boost.libraries=../../../../../../libs/libraries.htm
|
||||
<xsl:param>html.stylesheet=../../../../../../doc/html/boostbook.css
|
||||
<format>pdf:<xsl:param>img.src.path=$(images)/
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/python/doc/tutorial/doc/html
|
||||
;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Chapter 1. python 2.0</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Chapter 1. python 2.0</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="next" href="python/hello.html" title="Building Hello World">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@@ -17,21 +17,21 @@
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a></div>
|
||||
<div class="chapter" lang="en">
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
<div class="chapter">
|
||||
<div class="titlepage"><div>
|
||||
<div><h2 class="title">
|
||||
<a name="python"></a>Chapter 1. python 1.0</h2></div>
|
||||
<a name="python"></a>Chapter 1. python 2.0</h2></div>
|
||||
<div><div class="author"><h3 class="author">
|
||||
<span class="firstname">Joel</span> <span class="surname">de Guzman</span>
|
||||
</h3></div></div>
|
||||
<div><div class="author"><h3 class="author">
|
||||
<span class="firstname">David</span> <span class="surname">Abrahams</span>
|
||||
</h3></div></div>
|
||||
<div><p class="copyright">Copyright © 2002-2005 Joel
|
||||
<div><p class="copyright">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="id457106"></a><p>
|
||||
<a name="python.legal"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
@@ -42,8 +42,8 @@
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl>
|
||||
<dt><span class="section"><a href="index.html#python.quickstart">QuickStart</a></span></dt>
|
||||
<dt><span class="section"><a href="python/hello.html"> Building Hello World</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html"> Exposing Classes</a></span></dt>
|
||||
<dt><span class="section"><a href="python/hello.html">Building Hello World</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html">Exposing Classes</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.constructors">Constructors</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.class_data_members">Class Data Members</a></span></dt>
|
||||
@@ -60,18 +60,19 @@
|
||||
<dt><span class="section"><a href="python/functions.html#python.default_arguments">Default Arguments</a></span></dt>
|
||||
<dt><span class="section"><a href="python/functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="python/object.html"> Object Interface</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html">Object Interface</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="python/object.html#python.basic_interface">Basic Interface</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html#python.derived_object_types">Derived Object types</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html#python.enums">Enums</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html#python.creating_python_object">Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code></a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="python/embedding.html">Embedding</a></span></dt>
|
||||
<dd><dl><dt><span class="section"><a href="python/embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></dd>
|
||||
<dt><span class="section"><a href="python/iterators.html">Iterators</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exception.html"> Exception Translation</a></span></dt>
|
||||
<dt><span class="section"><a href="python/techniques.html"> General Techniques</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exception.html">Exception Translation</a></span></dt>
|
||||
<dt><span class="section"><a href="python/techniques.html">General Techniques</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="python/techniques.html#python.creating_packages">Creating Packages</a></span></dt>
|
||||
<dt><span class="section"><a href="python/techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
|
||||
@@ -79,7 +80,7 @@
|
||||
</dl></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.quickstart"></a>QuickStart</h2></div></div></div>
|
||||
<p>
|
||||
@@ -93,10 +94,10 @@
|
||||
code takes on the look of a kind of declarative interface definition language
|
||||
(IDL).
|
||||
</p>
|
||||
<a name="quickstart.hello_world"></a><h2>
|
||||
<a name="id386707"></a>
|
||||
<h3>
|
||||
<a name="quickstart.hello_world"></a>
|
||||
Hello World
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Following C/C++ tradition, let's start with the "hello, world". A
|
||||
C++ Function:
|
||||
@@ -121,31 +122,21 @@
|
||||
That's it. We're done. We can now build this as a shared library. The resulting
|
||||
DLL is now visible to Python. Here's a sample Python session:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">hello_ext</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<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>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World module
|
||||
from start to finish...</strong></span></em></span>
|
||||
</p></blockquote></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: November 22, 2008 at 03:24:11 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: December 26, 2011 at 21:58:39 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a></div>
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Embedding</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="prev" href="object.html" title="Object Interface">
|
||||
<link rel="next" href="iterators.html" title="Iterators">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@@ -20,9 +20,9 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.embedding"></a>Embedding</h2></div></div></div>
|
||||
<div class="toc"><dl><dt><span class="section"><a href="embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></div>
|
||||
@@ -39,28 +39,28 @@
|
||||
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><h2>
|
||||
<a name="id472330"></a>
|
||||
<h3>
|
||||
<a name="embedding.building_embedded_programs"></a>
|
||||
Building embedded programs
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
To be able to embed python into your programs, you have to link to both Boost.Python's
|
||||
as well as Python's own runtime library.
|
||||
</p>
|
||||
<p>
|
||||
Boost.Python's library comes in two variants. Both are located in Boost's
|
||||
<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
|
||||
<code class="literal">/libs/python/build/bin-stage</code> subdirectory. On Windows, the
|
||||
variants are called <code class="literal">boost_python.lib</code> (for release builds)
|
||||
and <code class="literal">boost_python_debug.lib</code> (for debugging). If you can't
|
||||
find the libraries, you probably haven't built Boost.Python yet. See <a href="../../../../building.html" target="_top">Building and Testing</a> on how to do this.
|
||||
</p>
|
||||
<p>
|
||||
Python's library can be found in the <tt class="literal">/libs</tt> subdirectory
|
||||
Python's library can be found in the <code class="literal">/libs</code> subdirectory
|
||||
of your Python directory. On Windows it is called pythonXY.lib where X.Y is
|
||||
your major Python version number.
|
||||
</p>
|
||||
<p>
|
||||
Additionally, Python's <tt class="literal">/include</tt> subdirectory has to be added
|
||||
Additionally, Python's <code class="literal">/include</code> subdirectory has to be added
|
||||
to your include path.
|
||||
</p>
|
||||
<p>
|
||||
@@ -81,56 +81,49 @@ exe embedded_program # name of the executable
|
||||
<library-path>$(PYTHON_LIB_PATH)
|
||||
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
|
||||
</pre>
|
||||
<a name="embedding.getting_started"></a><h2>
|
||||
<a name="id472435"></a>
|
||||
<h3>
|
||||
<a name="embedding.getting_started"></a>
|
||||
Getting started
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Being able to build is nice, but there is nothing to build yet. Embedding the
|
||||
Python interpreter into one of your C++ programs requires these 4 steps:
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
#include <tt class="literal"><boost/python.hpp></tt>
|
||||
</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 <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module.
|
||||
</li>
|
||||
<li>
|
||||
Call other Python C API routines to use the interpreter.
|
||||
</li>
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
#include <code class="literal"><boost/python.hpp></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
|
||||
to start the interpreter and create the <code class="literal">__main__</code> module.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Call other Python C API routines to use the interpreter.
|
||||
</li>
|
||||
</ol></div>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
<span class="bold"><b>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.</b></span>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
<span class="bold"><strong>Note that at this time you must not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
|
||||
to stop the interpreter. This may be fixed in a future version of boost.python.</strong></span>
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
(Of course, there can be other C++ code between all of these steps.)
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<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>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
<div class="section" lang="en">
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="emphasis"><em><span class="bold"><strong>Now that we can embed the interpreter in
|
||||
our programs, lets see how to put it to use...</strong></span></em></span>
|
||||
</p></blockquote></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
|
||||
<p>
|
||||
As you probably already know, objects in Python are reference-counted. Naturally,
|
||||
the <tt class="literal">PyObject</tt>s of the Python C API are also reference-counted.
|
||||
the <code class="literal">PyObject</code>s of the Python C API are also reference-counted.
|
||||
There is a difference however. While the reference-counting is fully automatic
|
||||
in Python, the Python C API requires you to do it <a href="http://www.python.org/doc/current/c-api/refcounting.html" target="_top">by
|
||||
hand</a>. This is messy and especially hard to get right in the presence
|
||||
@@ -138,10 +131,10 @@ exe embedded_program # name of the executable
|
||||
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><h2>
|
||||
<a name="id472601"></a>
|
||||
<h3>
|
||||
<a name="using_the_interpreter.running_python_code"></a>
|
||||
Running Python code
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Boost.python provides three related functions to run Python code from C++.
|
||||
</p>
|
||||
@@ -155,11 +148,10 @@ exe embedded_program # name of the executable
|
||||
and exec_file executes the code contained in the given file.
|
||||
</p>
|
||||
<p>
|
||||
The <tt class="literal">globals</tt> and <tt class="literal">locals</tt> parameters are
|
||||
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 <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module for both parameters.
|
||||
dictionary of the <code class="literal">__main__</code> module for both parameters.
|
||||
</p>
|
||||
<p>
|
||||
Boost.python provides a function to import a module:
|
||||
@@ -171,8 +163,8 @@ exe embedded_program # name of the executable
|
||||
first), and returns it.
|
||||
</p>
|
||||
<p>
|
||||
Let's import the <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module and run some Python code in its namespace:
|
||||
Let's import the <code class="literal">__main__</code> module and run some Python code
|
||||
in its namespace:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
|
||||
@@ -186,15 +178,15 @@ exe embedded_program # name of the executable
|
||||
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><h2>
|
||||
<a name="id473185"></a>
|
||||
<h3>
|
||||
<a name="using_the_interpreter.manipulating_python_objects"></a>
|
||||
Manipulating Python objects
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Often we'd like to have a class to manipulate Python objects. But we have
|
||||
already seen such a class above, and in the <a href="object.html" target="_top">previous
|
||||
section</a>: the aptly named <tt class="literal">object</tt> class and its
|
||||
derivatives. We've already seen that they can be constructed from a <tt class="literal">handle</tt>.
|
||||
section</a>: the aptly named <code class="literal">object</code> class and its
|
||||
derivatives. We've already seen that they can be constructed from a <code class="literal">handle</code>.
|
||||
The following examples should further illustrate this fact:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
@@ -203,18 +195,18 @@ exe embedded_program # name of the executable
|
||||
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</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 <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:
|
||||
Here we create a dictionary object for the <code class="literal">__main__</code> module's
|
||||
namespace. Then we assign 5 squared to the result variable and read this
|
||||
variable from the dictionary. Another way to achieve the same result is to
|
||||
use eval instead, which returns the result directly:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">result</span><span class="special">);</span>
|
||||
</pre>
|
||||
<a name="using_the_interpreter.exception_handling"></a><h2>
|
||||
<a name="id473554"></a>
|
||||
<h3>
|
||||
<a name="using_the_interpreter.exception_handling"></a>
|
||||
Exception handling
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
|
||||
is thrown:
|
||||
@@ -222,16 +214,16 @@ exe embedded_program # name of the executable
|
||||
<pre class="programlisting"><span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
|
||||
<span class="comment">// execution will never get here:
|
||||
</span> <span class="keyword">int</span> <span class="identifier">five_divided_by_zero</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">result</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"><</span><span class="keyword">int</span><span class="special">>(</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">&)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// handle the exception in some way
|
||||
</span><span class="special">}</span>
|
||||
<span class="comment">// handle the exception in some way</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The <tt class="literal">error_already_set</tt> exception class doesn't carry any
|
||||
The <code class="literal">error_already_set</code> exception class doesn't carry any
|
||||
information in itself. To find out more about the Python exception that occurred,
|
||||
you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
|
||||
handling functions</a> of the Python C API in your catch-statement. This
|
||||
@@ -244,12 +236,12 @@ exe embedded_program # name of the executable
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// handle ZeroDivisionError specially
|
||||
</span> <span class="special">}</span>
|
||||
<span class="comment">// handle ZeroDivisionError specially</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// print all other errors to stderr
|
||||
</span> <span class="identifier">PyErr_Print</span><span class="special">();</span>
|
||||
<span class="comment">// print all other errors to stderr</span>
|
||||
<span class="identifier">PyErr_Print</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
@@ -261,7 +253,7 @@ exe embedded_program # name of the executable
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -271,7 +263,7 @@ exe embedded_program # name of the executable
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Exception Translation</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Exception Translation</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.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%"><tr>
|
||||
@@ -20,11 +20,11 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.exception"></a> Exception Translation</h2></div></div></div>
|
||||
<a name="python.exception"></a>Exception Translation</h2></div></div></div>
|
||||
<p>
|
||||
All C++ exceptions must be caught at the boundary with Python code. This boundary
|
||||
is the point where C++ meets Python. Boost.Python provides a default exception
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -57,7 +57,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Exposing Classes</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Exposing Classes</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="prev" href="hello.html" title="Building Hello World">
|
||||
<link rel="next" href="functions.html" title="Functions">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@@ -20,11 +20,11 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.exposing"></a> Exposing Classes</h2></div></div></div>
|
||||
<a name="python.exposing"></a>Exposing Classes</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="exposing.html#python.constructors">Constructors</a></span></dt>
|
||||
<dt><span class="section"><a href="exposing.html#python.class_data_members">Class Data Members</a></span></dt>
|
||||
@@ -62,24 +62,22 @@
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
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
|
||||
Here, we wrote a C++ class wrapper that exposes the member functions <code class="literal">greet</code>
|
||||
and <code class="literal">set</code>. Now, after building our module as a shared library,
|
||||
we may use our class <code class="literal">World</code> in Python. Here's a sample Python
|
||||
session:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">'howdy'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="string">'howdy'</span>
|
||||
</pre>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.constructors"></a>Constructors</h3></div></div></div>
|
||||
<p>
|
||||
Our previous example didn't have any explicit constructors. Since <tt class="literal">World</tt>
|
||||
Our previous example didn't have any explicit constructors. Since <code class="literal">World</code>
|
||||
is declared as a plain struct, it has an implicit default constructor. Boost.Python
|
||||
exposes the default constructor by default, which is why we were able to
|
||||
write
|
||||
@@ -90,20 +88,18 @@
|
||||
We may wish to wrap a class with a non-default constructor. Let us build
|
||||
on our previous example:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">):</span> <span class="identifier">msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span> <span class="special">{}</span> <span class="comment">// added constructor
|
||||
</span> <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="identifier">World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">):</span> <span class="identifier">msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span> <span class="special">{}</span> <span class="comment">// added constructor</span>
|
||||
<span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">greet</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
This time <tt class="literal">World</tt> has no default constructor; our previous
|
||||
This time <code class="literal">World</code> has no default constructor; our previous
|
||||
wrapping code would fail to compile when the library tried to expose it.
|
||||
We have to tell <tt class="literal">class_<World></tt> about the constructor
|
||||
We have to tell <code class="literal">class_<World></code> about the constructor
|
||||
we want to expose instead.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
@@ -118,13 +114,13 @@
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
<tt class="literal">init<std::string>()</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>").
|
||||
<code class="literal">init<std::string>()</code> exposes the constructor taking
|
||||
in a <code class="literal">std::string</code> (in Python, constructors are spelled
|
||||
"<code class="literal">"__init__"</code>").
|
||||
</p>
|
||||
<p>
|
||||
We can expose additional constructors by passing more <tt class="literal">init<...></tt>s
|
||||
to the <tt class="literal">def()</tt> member function. Say for example we have
|
||||
We can expose additional constructors by passing more <code class="literal">init<...></code>s
|
||||
to the <code class="literal">def()</code> member function. Say for example we have
|
||||
another World constructor taking in two doubles:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
@@ -135,23 +131,23 @@
|
||||
</pre>
|
||||
<p>
|
||||
On the other hand, if we do not wish to expose any constructors at all, we
|
||||
may use <tt class="literal">no_init</tt> instead:
|
||||
may use <code class="literal">no_init</code> instead:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Abstract</span><span class="special">>(</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 <tt class="literal"><span class="underline">_init</span>_</tt>
|
||||
method which always raises a Python RuntimeError exception.
|
||||
This actually adds an <code class="literal">__init__</code> method which always raises
|
||||
a Python RuntimeError exception.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_data_members"></a>Class Data Members</h3></div></div></div>
|
||||
<p>
|
||||
Data members may also be exposed to Python so that they can be accessed as
|
||||
attributes of the corresponding Python class. Each data member that we wish
|
||||
to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
|
||||
or <span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:
|
||||
to be exposed may be regarded as <span class="bold"><strong>read-only</strong></span>
|
||||
or <span class="bold"><strong>read-write</strong></span>. Consider this class <code class="literal">Var</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Var</span>
|
||||
<span class="special">{</span>
|
||||
@@ -161,7 +157,7 @@
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
|
||||
Our C++ <code class="literal">Var</code> class and its data members can be exposed
|
||||
to Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Var</span><span class="special">>(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>())</span>
|
||||
@@ -172,24 +168,22 @@
|
||||
Then, in Python, assuming we have placed our Var class inside the namespace
|
||||
hello as we did before:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span><span class="special">,</span> <span class="string">'is around'</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span>
|
||||
<span class="identifier">pi</span> <span class="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
|
||||
</pre>
|
||||
<p>
|
||||
Note that <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>.
|
||||
Note that <code class="literal">name</code> is exposed as <span class="bold"><strong>read-only</strong></span>
|
||||
while <code class="literal">value</code> is exposed as <span class="bold"><strong>read-write</strong></span>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
|
||||
</span><span class="identifier">Traceback</span> <span class="special">(</span><span class="identifier">most</span> <span class="identifier">recent</span> <span class="identifier">call</span> <span class="identifier">last</span><span class="special">):</span>
|
||||
<span class="identifier">File</span> <span class="string">"<stdin>"</span><span class="special">,</span> <span class="identifier">line</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">in</span> #
|
||||
<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span>#<span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name</span>
|
||||
<span class="identifier">Traceback</span> <span class="special">(</span><span class="identifier">most</span> <span class="identifier">recent</span> <span class="identifier">call</span> <span class="identifier">last</span><span class="special">):</span>
|
||||
<span class="identifier">File</span> <span class="string">"<stdin>"</span><span class="special">,</span> <span class="identifier">line</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">in</span> <span class="error">?</span>
|
||||
<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span><span class="error">'</span><span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_properties"></a>Class Properties</h3></div></div></div>
|
||||
<p>
|
||||
@@ -198,8 +192,6 @@
|
||||
The only way to access the class' data is through access (getter/setter)
|
||||
functions. Access functions expose class properties. Here's an example:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Num</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">Num</span><span class="special">();</span>
|
||||
@@ -211,7 +203,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 <tt class="literal">Num</tt>
|
||||
can just be a different syntax for a method call. Wrapping our <code class="literal">Num</code>
|
||||
class using Boost.Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Num</span><span class="special">>(</span><span class="string">"Num"</span><span class="special">)</span>
|
||||
@@ -221,25 +213,21 @@
|
||||
<p>
|
||||
And at last, in Python:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span>
|
||||
<span class="special">(</span><span class="number">3.14</span><span class="special">,</span> <span class="number">3.14</span><span class="special">)</span>
|
||||
<span class="special">>>></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>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span> <span class="special">=</span> <span class="number">2.17</span> <span class="comment"># error!</span>
|
||||
</pre>
|
||||
<p>
|
||||
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>
|
||||
Take note that the class property <code class="literal">rovalue</code> is exposed as
|
||||
<span class="bold"><strong>read-only</strong></span> since the <code class="literal">rovalue</code>
|
||||
setter member function is not passed in:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.inheritance"></a>Inheritance</h3></div></div></div>
|
||||
<p>
|
||||
@@ -256,7 +244,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 <tt class="literal">Base</tt> and <tt class="literal">Derived</tt>
|
||||
And a set of C++ functions operating on <code class="literal">Base</code> and <code class="literal">Derived</code>
|
||||
object instances:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
|
||||
@@ -264,15 +252,15 @@
|
||||
<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 <tt class="literal">Base</tt>:
|
||||
We've seen how we can wrap the base class <code class="literal">Base</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Base</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now we can inform Boost.Python of the inheritance relationship between <tt class="literal">Derived</tt>
|
||||
and its base class <tt class="literal">Base</tt>. Thus:
|
||||
Now we can inform Boost.Python of the inheritance relationship between <code class="literal">Derived</code>
|
||||
and its base class <code class="literal">Base</code>. Thus:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span> <span class="special">>(</span><span class="string">"Derived"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
@@ -281,47 +269,47 @@
|
||||
<p>
|
||||
Doing so, we get some things for free:
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
Derived automatically inherits all of Base's Python methods (wrapped C++
|
||||
member functions)
|
||||
</li>
|
||||
<li>
|
||||
<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
|
||||
<tt class="literal">Base</tt> can be passed where a pointer or reference to
|
||||
<tt class="literal">Derived</tt> is expected.
|
||||
</li>
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
Derived automatically inherits all of Base's Python methods (wrapped
|
||||
C++ member functions)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>If</strong></span> Base is polymorphic, <code class="literal">Derived</code>
|
||||
objects which have been passed to Python via a pointer or reference to
|
||||
<code class="literal">Base</code> can be passed where a pointer or reference to
|
||||
<code class="literal">Derived</code> is expected.
|
||||
</li>
|
||||
</ol></div>
|
||||
<p>
|
||||
Now, we will expose the C++ free functions <tt class="literal">b</tt> and <tt class="literal">d</tt>
|
||||
and <tt class="literal">factory</tt>:
|
||||
Now, we will expose the C++ free functions <code class="literal">b</code> and <code class="literal">d</code>
|
||||
and <code class="literal">factory</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Note that free function <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<manage_new_object></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 will see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
|
||||
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<manage_new_object></code> to instruct
|
||||
Python to adopt the pointer to <code class="literal">Base</code> and hold the instance
|
||||
in a new Python <code class="literal">Base</code> object until the the Python object
|
||||
is destroyed. We will see more of Boost.Python <a class="link" href="functions.html#python.call_policies" title="Call Policies">call
|
||||
policies</a> later.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">// Tell Python to take ownership of factory's result
|
||||
</span><span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">,</span>
|
||||
<pre class="programlisting"><span class="comment">// Tell Python to take ownership of factory's result</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">,</span>
|
||||
<span class="identifier">return_value_policy</span><span class="special"><</span><span class="identifier">manage_new_object</span><span class="special">>());</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_virtual_functions"></a>Class Virtual Functions</h3></div></div></div>
|
||||
<p>
|
||||
In this section, we will learn how to make functions behave polymorphically
|
||||
through virtual functions. Continuing our example, let us add a virtual function
|
||||
to our <tt class="literal">Base</tt> class:
|
||||
to our <code class="literal">Base</code> class:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
@@ -333,11 +321,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 <tt class="computeroutput"><span class="identifier">Base</span></tt>. Yet, when
|
||||
to our class <code class="computeroutput"><span class="identifier">Base</span></code>. Yet, when
|
||||
you have a virtual function that's going to be overridden in Python and called
|
||||
polymorphically <span class="bold"><b>from C++</b></span>, we'll need to
|
||||
polymorphically <span class="bold"><strong>from C++</strong></span>, we'll need to
|
||||
add some scaffoldings to make things work properly. What we'll do is write
|
||||
a class wrapper that derives from <tt class="computeroutput"><span class="identifier">Base</span></tt>
|
||||
a class wrapper that derives from <code class="computeroutput"><span class="identifier">Base</span></code>
|
||||
that will unintrusively hook into the virtual functions so that a Python
|
||||
override may be called:
|
||||
</p>
|
||||
@@ -350,65 +338,66 @@
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
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"><</span><span class="identifier">Base</span><span class="special">></span></tt> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
|
||||
The <tt class="computeroutput"><span class="identifier">wrapper</span></tt> template makes
|
||||
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"><</span><span class="identifier">Base</span><span class="special">></span></code> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
|
||||
The <code class="computeroutput"><span class="identifier">wrapper</span></code> template makes
|
||||
the job of wrapping classes that are meant to overridden in Python, easier.
|
||||
</p>
|
||||
<div class="sidebar">
|
||||
<div class="titlepage"></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
If you are using Microsoft Visual C++ 6 or 7, you have to write <tt class="computeroutput"><span class="identifier">f</span></tt> as:
|
||||
If you are using Microsoft Visual C++ 6 or 7, you have to write <code class="computeroutput"><span class="identifier">f</span></code> as:
|
||||
</p>
|
||||
<p>
|
||||
<tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="keyword">this</span><span class="special">-></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>.
|
||||
<code class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="keyword">this</span><span class="special">-></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 <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>.
|
||||
BaseWrap's overridden virtual member function <code class="computeroutput"><span class="identifier">f</span></code>
|
||||
in effect calls the corresponding method of the Python object through <code class="computeroutput"><span class="identifier">get_override</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:
|
||||
Finally, exposing <code class="computeroutput"><span class="identifier">Base</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</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">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
<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
|
||||
<code class="computeroutput"><span class="identifier">pure_virtual</span></code> signals Boost.Python
|
||||
that the function <code class="computeroutput"><span class="identifier">f</span></code> is a
|
||||
pure virtual function.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top">
|
||||
<tr><td align="left" valign="top">
|
||||
<p>
|
||||
<span class="bold"><b>member function and methods</b></span>
|
||||
<span class="bold"><strong>member function and methods</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
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>
|
||||
Python, like many object oriented languages uses the term <span class="bold"><strong>methods</strong></span>.
|
||||
Methods correspond roughly to C++'s <span class="bold"><strong>member functions</strong></span>
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.virtual_functions_with_default_implementations"></a>Virtual Functions with Default Implementations</h3></div></div></div>
|
||||
<p>
|
||||
We've seen in the previous section how classes with pure virtual functions
|
||||
are wrapped using Boost.Python's <a href="../../../../v2/wrapper.html" target="_top">class
|
||||
wrapper</a> facilities. If we wish to wrap <span class="bold"><b>non</b></span>-pure-virtual
|
||||
wrapper</a> facilities. If we wish to wrap <span class="bold"><strong>non</strong></span>-pure-virtual
|
||||
functions instead, the mechanism is a bit different.
|
||||
</p>
|
||||
<p>
|
||||
Recall that in the <a href="exposing.html#python.class_virtual_functions" title="Class Virtual Functions">previous
|
||||
Recall that in the <a class="link" href="exposing.html#python.class_virtual_functions" title="Class Virtual Functions">previous
|
||||
section</a>, we wrapped a class with a pure virtual function that we then
|
||||
implemented in C++, or Python classes derived from it. Our base class:
|
||||
</p>
|
||||
@@ -418,8 +407,8 @@
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
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:
|
||||
had a pure virtual function <code class="literal">f</code>. If, however, its member
|
||||
function <code class="literal">f</code> was not declared as pure virtual:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
<span class="special">{</span>
|
||||
@@ -435,28 +424,29 @@
|
||||
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">override</span> <span class="identifier">f</span> <span class="special">=</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">))</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">();</span> <span class="comment">// *note*
|
||||
</span> <span class="keyword">return</span> <span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">();</span> <span class="comment">// *note*</span>
|
||||
<span class="keyword">return</span> <span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">default_f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span> <span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice how we implemented <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>.
|
||||
Notice how we implemented <code class="computeroutput"><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">f</span></code>. Now,
|
||||
we have to check if there is an override for <code class="computeroutput"><span class="identifier">f</span></code>.
|
||||
If none, then we call <code class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></code>.
|
||||
</p>
|
||||
<div class="sidebar">
|
||||
<div class="titlepage"></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
If you are using Microsoft Visual C++ 6 or 7, you have to rewrite the line
|
||||
with the <tt class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></tt> as:
|
||||
with the <code class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></code> as:
|
||||
</p>
|
||||
<p>
|
||||
<tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*>(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></tt>.
|
||||
<code class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*>(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></code>.
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
@@ -467,16 +457,14 @@
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Take note that we expose both <tt class="computeroutput"><span class="special">&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></tt> and <tt class="computeroutput"><span class="special">&</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.
|
||||
Take note that we expose both <code class="computeroutput"><span class="special">&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></code> and <code class="computeroutput"><span class="special">&</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span></code>. Boost.Python needs to keep track
|
||||
of 1) the dispatch function <code class="literal">f</code> and 2) the forwarding function
|
||||
to its default implementation <code class="literal">default_f</code>. There's a special
|
||||
<code class="literal">def</code> function for this purpose.
|
||||
</p>
|
||||
<p>
|
||||
In Python, the results would be as expected:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">(</span><span class="identifier">Base</span><span class="special">):</span>
|
||||
<span class="special">...</span> <span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
@@ -485,36 +473,34 @@
|
||||
<span class="special">>>></span> <span class="identifier">derived</span> <span class="special">=</span> <span class="identifier">Derived</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
Calling <tt class="literal">base.f()</tt>:
|
||||
Calling <code class="literal">base.f()</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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 <tt class="literal">derived.f()</tt>:
|
||||
Calling <code class="literal">derived.f()</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
|
||||
<span class="number">42</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
|
||||
<a name="class_operators_special_functions.python_operators"></a><h2>
|
||||
<a name="id462548"></a>
|
||||
<h3>
|
||||
<a name="class_operators_special_functions.python_operators"></a>
|
||||
Python Operators
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
C is well known for the abundance of operators. C++ extends this to the extremes
|
||||
by allowing operator overloading. Boost.Python takes advantage of this and
|
||||
makes it easy to wrap C++ operator-powered classes.
|
||||
</p>
|
||||
<p>
|
||||
Consider a file position class <tt class="literal">FilePos</tt> and a set of operators
|
||||
Consider a file position class <code class="literal">FilePos</code> and a set of operators
|
||||
that take on FilePos instances:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
|
||||
|
||||
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
|
||||
@@ -530,27 +516,27 @@
|
||||
and intuitively:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">FilePos</span><span class="special">>(</span><span class="string">"FilePos"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __add__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="keyword">int</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __radd__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __sub__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __sub__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+=</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __iadd__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-=</span> <span class="identifier">other</span><span class="special"><</span><span class="keyword">int</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special"><</span> <span class="identifier">self</span><span class="special">);</span> <span class="comment">// __lt__
|
||||
</span></pre>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __add__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="keyword">int</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __radd__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __sub__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __sub__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+=</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __iadd__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-=</span> <span class="identifier">other</span><span class="special"><</span><span class="keyword">int</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special"><</span> <span class="identifier">self</span><span class="special">);</span> <span class="comment">// __lt__</span>
|
||||
</pre>
|
||||
<p>
|
||||
The code snippet above is very clear and needs almost no explanation at all.
|
||||
It is virtually the same as the operators' signatures. Just take note that
|
||||
<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<T>()</tt>
|
||||
in place of an actual <tt class="literal">T</tt> instance when writing "self
|
||||
<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<T>()</code>
|
||||
in place of an actual <code class="literal">T</code> instance when writing "self
|
||||
expressions".
|
||||
</p>
|
||||
<a name="class_operators_special_functions.special_methods"></a><h2>
|
||||
<a name="id463302"></a>
|
||||
<h3>
|
||||
<a name="class_operators_special_functions.special_methods"></a>
|
||||
Special Methods
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Python has a few more <span class="emphasis"><em>Special Methods</em></span>. Boost.Python
|
||||
supports all of the standard special method names supported by real Python
|
||||
@@ -566,30 +552,30 @@
|
||||
<span class="identifier">ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<(</span><span class="identifier">ostream</span><span class="special">&,</span><span class="identifier">Rational</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Rational</span><span class="special">>(</span><span class="string">"Rational"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">float_</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __float__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">other</span><span class="special"><</span><span class="identifier">Rational</span><span class="special">>))</span> <span class="comment">// __pow__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __abs__
|
||||
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __str__
|
||||
</span> <span class="special">;</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">float_</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __float__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">other</span><span class="special"><</span><span class="identifier">Rational</span><span class="special">>))</span> <span class="comment">// __pow__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __abs__</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __str__</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Need we say more?
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
What is the business of <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</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"><<</span></tt> to do its work (i.e. <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</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>.
|
||||
<tr><td align="left" valign="top"><p>
|
||||
What is the business of <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</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"><<</span></code> to do its work (i.e. <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></code>
|
||||
is used by the method defined by <code class="computeroutput"><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span></code>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -599,7 +585,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Functions</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="prev" href="exposing.html" title="Exposing Classes">
|
||||
<link rel="next" href="object.html" title="Object Interface">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@@ -20,9 +20,9 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.functions"></a>Functions</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
@@ -38,18 +38,12 @@
|
||||
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
|
||||
<tt class="literal">>>> import this</tt>.
|
||||
<code class="literal">>>> import this</code>.
|
||||
</p>
|
||||
<pre class="programlisting">>>> import this
|
||||
The Zen of Python, by Tim Peters
|
||||
@@ -68,12 +62,12 @@ 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"><b>right</b></span> now.
|
||||
Although never is often better than <span class="bold"><strong>right</strong></span> now.
|
||||
If the implementation is hard to explain, it's a bad idea.
|
||||
If the implementation is easy to explain, it may be a good idea.
|
||||
Namespaces are one honking great idea -- let's do more of those!
|
||||
</pre>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.call_policies"></a>Call Policies</h3></div></div></div>
|
||||
<p>
|
||||
@@ -121,30 +115,30 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
Here's what's happening:
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
<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 <tt class="literal">y.x</tt> is returned
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">y</tt> is deleted. <tt class="literal">x</tt> is a dangling reference
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">x.some_method()</tt> is called
|
||||
</li>
|
||||
<li><span class="bold"><b>BOOM!</b></span></li>
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
<code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
|
||||
and a pointer to <code class="literal">z</code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A reference to <code class="literal">y.x</code> is returned
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="literal">y</code> is deleted. <code class="literal">x</code> is a dangling reference
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="literal">x.some_method()</code> is called
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>BOOM!</strong></span>
|
||||
</li>
|
||||
</ol></div>
|
||||
<p>
|
||||
We could copy result into a new object:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
|
||||
</span><span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="comment"># No crash, but still bad
|
||||
</span><span class="number">3.14</span>
|
||||
<pre class="programlisting"><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">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears</span>
|
||||
<span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="comment"># No crash, but still bad</span>
|
||||
<span class="number">3.14</span>
|
||||
</pre>
|
||||
<p>
|
||||
This is not really our intent of our C++ interface. We've broken our promise
|
||||
@@ -154,8 +148,6 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
Our problems do not end there. Suppose Y is implemented as follows:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Y</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">;</span>
|
||||
@@ -163,7 +155,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice that the data member <tt class="literal">z</tt> is held by class Y using
|
||||
Notice that the data member <code class="literal">z</code> is held by class Y using
|
||||
a raw pointer. Now we have a potential dangling pointer problem inside Y:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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>
|
||||
@@ -171,7 +163,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
|
||||
</pre>
|
||||
<p>
|
||||
For reference, here's the implementation of <tt class="literal">f</tt> again:
|
||||
For reference, here's the implementation of <code class="literal">f</code> again:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -182,35 +174,38 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
Here's what's happening:
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
<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 <tt class="literal">z</tt> is held by <tt class="literal">y</tt>
|
||||
</li>
|
||||
<li>
|
||||
A reference to <tt class="literal">y.x</tt> is returned
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">z</tt> is deleted. <tt class="literal">y.z</tt> is a dangling pointer
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">y.z_value()</tt> is called
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">z->value()</tt> is called
|
||||
</li>
|
||||
<li><span class="bold"><b>BOOM!</b></span></li>
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
<code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
|
||||
and a pointer to <code class="literal">z</code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A pointer to <code class="literal">z</code> is held by <code class="literal">y</code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A reference to <code class="literal">y.x</code> is returned
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="literal">z</code> is deleted. <code class="literal">y.z</code> is a dangling
|
||||
pointer
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="literal">y.z_value()</code> is called
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="literal">z->value()</code> is called
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>BOOM!</strong></span>
|
||||
</li>
|
||||
</ol></div>
|
||||
<a name="call_policies.call_policies"></a><h2>
|
||||
<a name="id465291"></a>
|
||||
<h3>
|
||||
<a name="call_policies.call_policies"></a>
|
||||
Call Policies
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Call Policies may be used in situations such as the example detailed above.
|
||||
In our example, <tt class="literal">return_internal_reference</tt> and <tt class="literal">with_custodian_and_ward</tt>
|
||||
In our example, <code class="literal">return_internal_reference</code> and <code class="literal">with_custodian_and_ward</code>
|
||||
are our friends:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
@@ -218,25 +213,25 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span> <span class="special">>());</span>
|
||||
</pre>
|
||||
<p>
|
||||
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you
|
||||
What are the <code class="literal">1</code> and <code class="literal">2</code> parameters, you
|
||||
ask?
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the first argument, in our case <tt class="literal">Y&
|
||||
y</tt>, is the owner of the returned reference: <tt class="literal">X&</tt>.
|
||||
The "<tt class="literal">1</tt>" simply specifies the first argument.
|
||||
In short: "return an internal reference <tt class="literal">X&</tt> owned
|
||||
by the 1st argument <tt class="literal">Y& y</tt>".
|
||||
Informs Boost.Python that the first argument, in our case <code class="literal">Y&
|
||||
y</code>, is the owner of the returned reference: <code class="literal">X&</code>.
|
||||
The "<code class="literal">1</code>" simply specifies the first argument.
|
||||
In short: "return an internal reference <code class="literal">X&</code> owned
|
||||
by the 1st argument <code class="literal">Y& y</code>".
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the lifetime of the argument indicated by ward
|
||||
(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&
|
||||
y</tt>).
|
||||
(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&
|
||||
y</code>).
|
||||
</p>
|
||||
<p>
|
||||
It is also important to note that we have defined two policies above. Two
|
||||
@@ -250,42 +245,44 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
Here is the list of predefined call policies. A complete reference detailing
|
||||
these can be found <a href="../../../../v2/reference.html#models_of_call_policies" target="_top">here</a>.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
<span class="bold"><b>with_custodian_and_ward</b></span>: Ties lifetimes
|
||||
of the arguments
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>with_custodian_and_ward_postcall</b></span>: Ties
|
||||
lifetimes of the arguments and results
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>return_internal_reference</b></span>: Ties lifetime
|
||||
of one argument to that of result
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>return_value_policy<T> with T one of:</b></span><div class="itemizedlist"><ul type="circle">
|
||||
<li>
|
||||
<span class="bold"><b>reference_existing_object</b></span>: naive (dangerous)
|
||||
approach
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>copy_const_reference</b></span>: Boost.Python
|
||||
v1 approach
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>copy_non_const_reference</b></span>:
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>manage_new_object</b></span>: Adopt a pointer
|
||||
and hold the instance
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>with_custodian_and_ward</strong></span>: Ties lifetimes
|
||||
of the arguments
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>with_custodian_and_ward_postcall</strong></span>: Ties
|
||||
lifetimes of the arguments and results
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>return_internal_reference</strong></span>: Ties lifetime
|
||||
of one argument to that of result
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>return_value_policy<T> with T one of:</strong></span>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>reference_existing_object</strong></span>: naive
|
||||
(dangerous) approach
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>copy_const_reference</strong></span>: Boost.Python
|
||||
v1 approach
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>copy_non_const_reference</strong></span>:
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>manage_new_object</strong></span>: Adopt a pointer
|
||||
and hold the instance
|
||||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
</li>
|
||||
</ul></div>
|
||||
<div class="sidebar">
|
||||
<div class="titlepage"></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span>
|
||||
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><strong>Remember the Zen, Luke:</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
"Explicit is better than implicit"
|
||||
@@ -295,7 +292,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.overloading"></a>Overloading</h3></div></div></div>
|
||||
<p>
|
||||
@@ -347,59 +344,59 @@ 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="string">"f"</span><span class="special">,</span> <span class="identifier">fx4</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.default_arguments"></a>Default Arguments</h3></div></div></div>
|
||||
<p>
|
||||
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
|
||||
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
|
||||
pointers carry no default argument info. Take a function <code class="literal">f</code>
|
||||
with default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
But the type of a pointer to the function <tt class="literal">f</tt> has no information
|
||||
But the type of a pointer to the function <code class="literal">f</code> has no information
|
||||
about its default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
|
||||
</span></pre>
|
||||
<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 <tt class="literal">def</tt> function,
|
||||
When we pass this function pointer to the <code class="literal">def</code> function,
|
||||
there is no way to retrieve the default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
|
||||
</span></pre>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!</span>
|
||||
</pre>
|
||||
<p>
|
||||
Because of this, when wrapping C++ code, we had to resort to manual wrapping
|
||||
as outlined in the <a href="functions.html#python.overloading" title="Overloading">previous section</a>,
|
||||
as outlined in the <a class="link" href="functions.html#python.overloading" title="Overloading">previous section</a>,
|
||||
or writing thin wrappers:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">// write "thin wrappers"
|
||||
</span><span class="keyword">int</span> <span class="identifier">f1</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span> <span class="special">}</span>
|
||||
<pre class="programlisting"><span class="comment">// write "thin wrappers"</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f1</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
|
||||
<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span> <span class="special">}</span>
|
||||
|
||||
<span class="comment">/*...*/</span>
|
||||
|
||||
<span class="comment">// in module init
|
||||
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// all arguments
|
||||
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span> <span class="comment">// two arguments
|
||||
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span> <span class="comment">// one argument
|
||||
</span></pre>
|
||||
<span class="comment">// in module init</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// all arguments</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span> <span class="comment">// two arguments</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span> <span class="comment">// one argument</span>
|
||||
</pre>
|
||||
<p>
|
||||
When you want to wrap functions (or member functions) that either:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
have default arguments, or
|
||||
</li>
|
||||
<li>
|
||||
are overloaded with a common sequence of initial arguments
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
have default arguments, or
|
||||
</li>
|
||||
<li class="listitem">
|
||||
are overloaded with a common sequence of initial arguments
|
||||
</li>
|
||||
</ul></div>
|
||||
<a name="default_arguments.boost_python_function_overloads"></a><h2>
|
||||
<a name="id467317"></a>
|
||||
<h3>
|
||||
<a name="default_arguments.boost_python_function_overloads"></a>
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Boost.Python now has a way to make it easier. For instance, given a function:
|
||||
</p>
|
||||
@@ -415,18 +412,18 @@ 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 <tt class="literal">foo_overloads</tt> that can be passed on to <tt class="literal">def(...)</tt>.
|
||||
a class <code class="literal">foo_overloads</code> that can be passed on to <code class="literal">def(...)</code>.
|
||||
The third and fourth macro argument are the minimum arguments and maximum
|
||||
arguments, respectively. In our <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>
|
||||
arguments, respectively. In our <code class="literal">foo</code> function the minimum
|
||||
number of arguments is 1 and the maximum number of arguments is 4. The <code class="literal">def(...)</code>
|
||||
function will automatically add all the foo variants for us:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
|
||||
<a name="id467632"></a>
|
||||
<h3>
|
||||
<a name="default_arguments.boost_python_member_function_overloads"></a>
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Objects here, objects there, objects here there everywhere. More frequently
|
||||
than anything else, we need to expose member functions of our classes to
|
||||
@@ -435,7 +432,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 <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>, <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
|
||||
Like <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>, <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
|
||||
may be used to automatically create the thin wrappers for wrapping member
|
||||
functions. Let's have an example:
|
||||
</p>
|
||||
@@ -454,11 +451,11 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
will generate a set of thin wrappers for george's <tt class="literal">wack_em</tt>
|
||||
will generate a set of thin wrappers for george's <code class="literal">wack_em</code>
|
||||
member function accepting a minimum of 1 and a maximum of 3 arguments (i.e.
|
||||
the third and fourth macro argument). The thin wrappers are all enclosed
|
||||
in a class named <tt class="literal">george_overloads</tt> that can then be used
|
||||
as an argument to <tt class="literal">def(...)</tt>:
|
||||
in a class named <code class="literal">george_overloads</code> that can then be used
|
||||
as an argument to <code class="literal">def(...)</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
@@ -466,13 +463,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><h2>
|
||||
<a name="id467992"></a>
|
||||
<h3>
|
||||
<a name="default_arguments.init_and_optional"></a>
|
||||
init and optional
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
A similar facility is provided for class constructors, again, with default
|
||||
arguments or a sequence of overloads. Remember <tt class="literal">init<...></tt>?
|
||||
arguments or a sequence of overloads. Remember <code class="literal">init<...></code>?
|
||||
For example, given a class X with a constructor:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
@@ -487,16 +484,16 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</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">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice the use of <tt class="literal">init<...></tt> and <tt class="literal">optional<...></tt>
|
||||
Notice the use of <code class="literal">init<...></code> and <code class="literal">optional<...></code>
|
||||
to signify the default (optional arguments).
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.auto_overloading"></a>Auto-Overloading</h3></div></div></div>
|
||||
<p>
|
||||
It was mentioned in passing in the previous section that <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
|
||||
and <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> can also be
|
||||
It was mentioned in passing in the previous section that <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>
|
||||
and <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code> can also be
|
||||
used for overloaded functions and member functions with a common sequence
|
||||
of initial arguments. Here is an example:
|
||||
</p>
|
||||
@@ -535,24 +532,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><h2>
|
||||
<a name="id468767"></a>
|
||||
<h3>
|
||||
<a name="auto_overloading.manual_wrapping"></a>
|
||||
Manual Wrapping
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
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,
|
||||
It is important to emphasize however that <span class="bold"><strong>the overloaded
|
||||
functions must have a common sequence of initial arguments</strong></span>. Otherwise,
|
||||
our scheme above will not work. If this is not the case, we have to wrap
|
||||
our functions <a href="functions.html#python.overloading" title="Overloading">manually</a>.
|
||||
our functions <a class="link" href="functions.html#python.overloading" title="Overloading">manually</a>.
|
||||
</p>
|
||||
<p>
|
||||
Actually, we can mix and match manual wrapping of overloaded functions and
|
||||
automatic wrapping through <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
|
||||
automatic wrapping through <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
|
||||
and its sister, <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>. Following
|
||||
up on our example presented in the section <a class="link" href="functions.html#python.overloading" title="Overloading">on
|
||||
overloading</a>, since the first 4 overload functins have a common sequence
|
||||
of initial arguments, we can use <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
|
||||
to automatically wrap the first three of the <tt class="literal">def</tt>s and
|
||||
of initial arguments, we can use <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
|
||||
to automatically wrap the first three of the <code class="literal">def</code>s and
|
||||
manually wrap just the last. Here's how we'll do this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
|
||||
@@ -573,7 +570,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -583,7 +580,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Building Hello World</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Building Hello World</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="prev" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="next" href="exposing.html" title="Exposing Classes">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@@ -20,34 +20,34 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.hello"></a> Building Hello World</h2></div></div></div>
|
||||
<a name="hello.from_start_to_finish"></a><h2>
|
||||
<a name="id388718"></a>
|
||||
<a name="python.hello"></a>Building Hello World</h2></div></div></div>
|
||||
<h3>
|
||||
<a name="hello.from_start_to_finish"></a>
|
||||
From Start To Finish
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Now the first thing you'd want to do is to build the Hello World module and
|
||||
try it for yourself in Python. In this section, we will outline the steps necessary
|
||||
to achieve that. We will use the build tool that comes bundled with every boost
|
||||
distribution: <span class="bold"><b>bjam</b></span>.
|
||||
distribution: <span class="bold"><strong>bjam</strong></span>.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top">
|
||||
<tr><td align="left" valign="top">
|
||||
<p>
|
||||
<span class="bold"><b>Building without bjam</b></span>
|
||||
<span class="bold"><strong>Building without bjam</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
Besides bjam, there are of course other ways to get your module built. What's
|
||||
written here should not be taken as "the one and only way". There
|
||||
are of course other build tools apart from <tt class="literal">bjam</tt>.
|
||||
are of course other build tools apart from <code class="literal">bjam</code>.
|
||||
</p>
|
||||
<p>
|
||||
Take note however that the preferred build tool for Boost.Python is bjam.
|
||||
@@ -65,65 +65,59 @@
|
||||
and run a python program using the extension.
|
||||
</p>
|
||||
<p>
|
||||
The tutorial example can be found in the directory: <tt class="literal">libs/python/example/tutorial</tt>.
|
||||
The tutorial example can be found in the directory: <code class="literal">libs/python/example/tutorial</code>.
|
||||
There, you can find:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
hello.cpp
|
||||
</li>
|
||||
<li>
|
||||
hello.py
|
||||
</li>
|
||||
<li>
|
||||
Jamroot
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
hello.cpp
|
||||
</li>
|
||||
<li class="listitem">
|
||||
hello.py
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Jamroot
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The <tt class="literal">hello.cpp</tt> file is our C++ hello world example. The
|
||||
<tt class="literal">Jamroot</tt> is a minimalist <span class="emphasis"><em>bjam</em></span> script
|
||||
that builds the DLLs for us. Finally, <tt class="literal">hello.py</tt> is our Python
|
||||
program that uses the extension in <tt class="literal">hello.cpp</tt>.
|
||||
The <code class="literal">hello.cpp</code> file is our C++ hello world example. The
|
||||
<code class="literal">Jamroot</code> is a minimalist <span class="emphasis"><em>bjam</em></span> script
|
||||
that builds the DLLs for us. Finally, <code class="literal">hello.py</code> is our Python
|
||||
program that uses the extension in <code class="literal">hello.cpp</code>.
|
||||
</p>
|
||||
<p>
|
||||
Before anything else, you should have the bjam executable in your boost directory
|
||||
or somewhere in your path such that <tt class="literal">bjam</tt> can be executed
|
||||
or somewhere in your path such that <code class="literal">bjam</code> can be executed
|
||||
in the command line. Pre-built Boost.Jam executables are available for most
|
||||
platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
|
||||
</p>
|
||||
<a name="hello.let_s_jam_"></a><h2>
|
||||
<a name="id387300"></a>
|
||||
<h3>
|
||||
<a name="hello.let_s_jam_"></a>
|
||||
Let's Jam!
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/jam.png" alt="jam"></span>
|
||||
</p>
|
||||
<p>
|
||||
<a href="../../../../../example/tutorial/Jamroot" target="_top">Here</a> is our minimalist
|
||||
Jamroot file. Simply copy the file and tweak <tt class="literal">use-project boost</tt>
|
||||
Jamroot file. Simply copy the file and tweak <code class="literal">use-project boost</code>
|
||||
to where your boost root directory is and your OK.
|
||||
</p>
|
||||
<p>
|
||||
The comments contained in the Jamrules file above should be sufficient to get
|
||||
you going.
|
||||
</p>
|
||||
<a name="hello.running_bjam"></a><h2>
|
||||
<a name="id387357"></a>
|
||||
<h3>
|
||||
<a name="hello.running_bjam"></a>
|
||||
Running bjam
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
|
||||
interpreter.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
Start it up.
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
Start it up.
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
A file called user-config.jam in your home directory is used to configure your
|
||||
tools. In Windows, your home directory can be found by typing:
|
||||
@@ -139,18 +133,18 @@
|
||||
using msvc : 8.0 ;
|
||||
|
||||
# Python configuration
|
||||
using python : 2.4 : C:/dev/tools<span class="emphasis"><em>Python</em></span> ;
|
||||
using python : 2.4 : C:<span class="emphasis"><em>dev/tools/Python</em></span> ;
|
||||
</pre>
|
||||
<p>
|
||||
The first rule tells Bjam to use the MSVC 8.0 compiler and associated tools.
|
||||
The second rule provides information on Python, its version and where it is
|
||||
located. The above assumes that the Python installation is in <tt class="literal">C:/dev/tools/Python/</tt>.
|
||||
located. The above assumes that the Python installation is in <code class="literal">C:<span class="emphasis"><em>dev/tools\/Python</em></span></code>.
|
||||
If you have one fairly "standard" python installation for your platform,
|
||||
you might not need to do this.
|
||||
</p>
|
||||
<p>
|
||||
Now we are ready... Be sure to <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">"Jamroot"</tt>
|
||||
Now we are ready... Be sure to <code class="literal">cd</code> to <code class="literal">libs/python/example/tutorial</code>
|
||||
where the tutorial <code class="literal">"hello.cpp"</code> and the <code class="literal">"Jamroot"</code>
|
||||
is situated.
|
||||
</p>
|
||||
<p>
|
||||
@@ -171,7 +165,7 @@ bjam
|
||||
And so on... Finally:
|
||||
</p>
|
||||
<pre class="programlisting">Creating library <span class="emphasis"><em>path-to-boost_python.dll</em></span>
|
||||
Creating library <span class="emphasis"><em>path-to-'''hello_ext'''.exp</em></span>
|
||||
Creating library /path-to-hello_ext.exp/
|
||||
**passed** ... hello.test
|
||||
...updated 35 targets...
|
||||
</pre>
|
||||
@@ -179,30 +173,13 @@ bjam
|
||||
Or something similar. If all is well, you should now have built the DLLs and
|
||||
run the Python program.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
Starting from Boost 1.35, bjam erases the generated executables (e.g. pyd
|
||||
file) after the test has concluded to conserve disk space. To keep bjam from
|
||||
doing that, pass --preserve-test-targets to bjam.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><b>There you go... Have fun!</b></span>
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="bold"><strong>There you go... Have fun!</strong></span>
|
||||
</p></blockquote></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -212,7 +189,7 @@ bjam
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Iterators</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.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%"><tr>
|
||||
@@ -20,9 +20,9 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.iterators"></a>Iterators</h2></div></div></div>
|
||||
<p>
|
||||
@@ -30,54 +30,50 @@
|
||||
iterators, but these are two very different beasts.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><b>C++ iterators:</b></span>
|
||||
<span class="bold"><strong>C++ iterators:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
C++ has 5 type categories (random-access, bidirectional, forward, input,
|
||||
output)
|
||||
</li>
|
||||
<li>
|
||||
There are 2 Operation categories: reposition, access
|
||||
</li>
|
||||
<li>
|
||||
A pair of iterators is needed to represent a (first/last) range.
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
C++ has 5 type categories (random-access, bidirectional, forward, input,
|
||||
output)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There are 2 Operation categories: reposition, access
|
||||
</li>
|
||||
<li class="listitem">
|
||||
A pair of iterators is needed to represent a (first/last) range.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="bold"><b>Python Iterators:</b></span>
|
||||
<span class="bold"><strong>Python Iterators:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
1 category (forward)
|
||||
</li>
|
||||
<li>
|
||||
1 operation category (next())
|
||||
</li>
|
||||
<li>
|
||||
Raises StopIteration exception at end
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
1 category (forward)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
1 operation category (next())
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Raises StopIteration exception at end
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The typical Python iteration protocol: <tt class="literal"><span class="bold"><b>for y
|
||||
in x...</b></span></tt> is as follows:
|
||||
The typical Python iteration protocol: <code class="literal"><span class="bold"><strong>for y
|
||||
in x...</strong></span></code> is as follows:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
|
||||
</span><span class="keyword">try</span><span class="special">:</span>
|
||||
<pre class="programlisting"><span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator</span>
|
||||
<span class="keyword">try</span><span class="special">:</span>
|
||||
<span class="keyword">while</span> <span class="number">1</span><span class="special">:</span>
|
||||
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item
|
||||
</span> <span class="special">...</span> <span class="comment"># process y
|
||||
</span><span class="keyword">except</span> <span class="identifier">StopIteration</span><span class="special">:</span> <span class="keyword">pass</span> <span class="comment"># iterator exhausted
|
||||
</span></pre>
|
||||
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item</span>
|
||||
<span class="special">...</span> <span class="comment"># process y</span>
|
||||
<span class="keyword">except</span> <span class="identifier">StopIteration</span><span class="special">:</span> <span class="keyword">pass</span> <span class="comment"># iterator exhausted</span>
|
||||
</pre>
|
||||
<p>
|
||||
Boost.Python provides some mechanisms to make C++ iterators play along nicely
|
||||
as Python iterators. What we need to do is to produce appropriate <tt class="computeroutput"><span class="identifier">__iter__</span></tt> function from C++ iterators that
|
||||
as Python iterators. What we need to do is to produce appropriate <code class="computeroutput"><span class="identifier">__iter__</span></code> function from C++ iterators that
|
||||
is compatible with the Python iteration protocol. For example:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>();</span>
|
||||
<span class="identifier">object</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">();</span>
|
||||
@@ -88,49 +84,47 @@
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><b>range</b></span>
|
||||
<span class="bold"><strong>range</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
We can create a Python savvy iterator using the range function:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
range(start, finish)
|
||||
</li>
|
||||
<li>
|
||||
range<Policies,Target>(start, finish)
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
range(start, finish)
|
||||
</li>
|
||||
<li class="listitem">
|
||||
range<Policies,Target>(start, finish)
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Here, start/finish may be one of:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
member data pointers
|
||||
</li>
|
||||
<li>
|
||||
member function pointers
|
||||
</li>
|
||||
<li>
|
||||
adaptable function object (use Target parameter)
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
member data pointers
|
||||
</li>
|
||||
<li class="listitem">
|
||||
member function pointers
|
||||
</li>
|
||||
<li class="listitem">
|
||||
adaptable function object (use Target parameter)
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="bold"><b>iterator</b></span>
|
||||
<span class="bold"><strong>iterator</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc"><li>
|
||||
iterator<T, Policies>()
|
||||
</li></ul></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
||||
iterator<T, Policies>()
|
||||
</li></ul></div>
|
||||
<p>
|
||||
Given a container <tt class="literal">T</tt>, iterator is a shortcut that simply
|
||||
calls <tt class="literal">range</tt> with &T::begin, &T::end.
|
||||
Given a container <code class="literal">T</code>, iterator is a shortcut that simply
|
||||
calls <code class="literal">range</code> with &T::begin, &T::end.
|
||||
</p>
|
||||
<p>
|
||||
Let's put this into action... Here's an example from some hypothetical bogon
|
||||
Particle accelerator code:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
|
||||
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
|
||||
<span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
|
||||
@@ -140,50 +134,44 @@
|
||||
<p>
|
||||
Now, our C++ Wrapper:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">F</span><span class="special">>(</span><span class="string">"Field"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&</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"><b>stl_input_iterator</b></span>
|
||||
<span class="bold"><strong>stl_input_iterator</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes
|
||||
we wish to go the other way, though: we'd like to pass a Python sequence to
|
||||
an STL algorithm or use it to initialize an STL container. We need to make
|
||||
a Python iterator look like an STL iterator. For that, we use <tt class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special"><></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"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">assign</span><span class="special">()</span></tt> to Python:
|
||||
</p>
|
||||
<p>
|
||||
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"><></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"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">assign</span><span class="special">()</span></code> to Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="comment">// Turn a Python sequence into an STL input range
|
||||
</span> <span class="identifier">stl_input_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
|
||||
<span class="comment">// Turn a Python sequence into an STL input range</span>
|
||||
<span class="identifier">stl_input_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
|
||||
<span class="identifier">l</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="comment">// Part of the wrapper for list<int>
|
||||
</span><span class="identifier">class_</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>(</span><span class="string">"list_int"</span><span class="special">)</span>
|
||||
<span class="comment">// Part of the wrapper for list<int></span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>(</span><span class="string">"list_int"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"assign"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">list_assign</span><span class="special"><</span><span class="keyword">int</span><span class="special">>)</span>
|
||||
<span class="comment">// ...
|
||||
</span> <span class="special">;</span>
|
||||
<span class="comment">// ...</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now in Python, we can assign any integer sequence to <tt class="computeroutput"><span class="identifier">list_int</span></tt>
|
||||
Now in Python, we can assign any integer sequence to <code class="computeroutput"><span class="identifier">list_int</span></code>
|
||||
objects:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -193,7 +181,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Object Interface</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Object Interface</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="prev" href="functions.html" title="Functions">
|
||||
<link rel="next" href="embedding.html" title="Embedding">
|
||||
</head>
|
||||
@@ -20,48 +20,47 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.object"></a> Object Interface</h2></div></div></div>
|
||||
<a name="python.object"></a>Object Interface</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="object.html#python.basic_interface">Basic Interface</a></span></dt>
|
||||
<dt><span class="section"><a href="object.html#python.derived_object_types">Derived Object types</a></span></dt>
|
||||
<dt><span class="section"><a href="object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
|
||||
<dt><span class="section"><a href="object.html#python.enums">Enums</a></span></dt>
|
||||
<dt><span class="section"><a href="object.html#python.creating_python_object">Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code></a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
Python is dynamically typed, unlike C++ which is statically typed. Python variables
|
||||
may hold an integer, a float, list, dict, tuple, str, long etc., among other
|
||||
things. In the viewpoint of Boost.Python and C++, these Pythonic variables
|
||||
are just instances of class <tt class="literal">object</tt>. We will see in this
|
||||
are just instances of class <code class="literal">object</code>. We will see in this
|
||||
chapter how to deal with Python objects.
|
||||
</p>
|
||||
<p>
|
||||
As mentioned, one of the goals of Boost.Python is to provide a bidirectional
|
||||
mapping between C++ and Python while maintaining the Python feel. Boost.Python
|
||||
C++ <tt class="literal">object</tt>s are as close as possible to Python. This should
|
||||
C++ <code class="literal">object</code>s are as close as possible to Python. This should
|
||||
minimize the learning curve significantly.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/python.png" alt="python"></span>
|
||||
</p>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.basic_interface"></a>Basic Interface</h3></div></div></div>
|
||||
<p>
|
||||
Class <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
|
||||
Class <code class="literal">object</code> wraps <code class="literal">PyObject*</code>. All the
|
||||
intricacies of dealing with <code class="literal">PyObject</code>s such as managing
|
||||
reference counting are handled by the <code class="literal">object</code> class. C++
|
||||
object interoperability is seamless. Boost.Python C++ <code class="literal">object</code>s
|
||||
can in fact be explicitly constructed from any C++ object.
|
||||
</p>
|
||||
<p>
|
||||
To illustrate, this Python code snippet:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">'foo'</span><span class="special">):</span>
|
||||
<span class="identifier">x</span><span class="special">[</span><span class="number">3</span><span class="special">:</span><span class="number">7</span><span class="special">]</span> <span class="special">=</span> <span class="string">'bar'</span>
|
||||
@@ -75,8 +74,6 @@
|
||||
<p>
|
||||
Can be rewritten in C++ using Boost.Python facilities this way:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">)</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">slice</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">7</span><span class="special">)</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
|
||||
@@ -93,63 +90,63 @@
|
||||
in C++, the look and feel should be immediately apparent to the Python coder.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.derived_object_types"></a>Derived Object types</h3></div></div></div>
|
||||
<p>
|
||||
Boost.Python comes with a set of derived <tt class="literal">object</tt> types
|
||||
Boost.Python comes with a set of derived <code class="literal">object</code> types
|
||||
corresponding to that of Python's:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
list
|
||||
</li>
|
||||
<li>
|
||||
dict
|
||||
</li>
|
||||
<li>
|
||||
tuple
|
||||
</li>
|
||||
<li>
|
||||
str
|
||||
</li>
|
||||
<li>
|
||||
long_
|
||||
</li>
|
||||
<li>
|
||||
enum
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
list
|
||||
</li>
|
||||
<li class="listitem">
|
||||
dict
|
||||
</li>
|
||||
<li class="listitem">
|
||||
tuple
|
||||
</li>
|
||||
<li class="listitem">
|
||||
str
|
||||
</li>
|
||||
<li class="listitem">
|
||||
long_
|
||||
</li>
|
||||
<li class="listitem">
|
||||
enum
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
These derived <tt class="literal">object</tt> types act like real Python types.
|
||||
These derived <code class="literal">object</code> types act like real Python types.
|
||||
For instance:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==></span> <span class="string">"1"</span>
|
||||
</pre>
|
||||
<p>
|
||||
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:
|
||||
Wherever appropriate, a particular derived <code class="literal">object</code> has
|
||||
corresponding Python type's methods. For instance, <code class="literal">dict</code>
|
||||
has a <code class="literal">keys()</code> method:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
|
||||
<code class="literal">make_tuple</code> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
In C++, when Boost.Python <tt class="literal">object</tt>s are used as arguments
|
||||
In C++, when Boost.Python <code class="literal">object</code>s are used as arguments
|
||||
to functions, subtype matching is required. For example, when a function
|
||||
<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.
|
||||
<code class="literal">f</code>, as declared below, is wrapped, it will only accept
|
||||
instances of Python's <code class="literal">str</code> type and subtypes.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">object</span> <span class="identifier">n2</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span> <span class="comment">// NAME = name.upper()
|
||||
</span> <span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span> <span class="comment">// better
|
||||
</span> <span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">n2</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span> <span class="comment">// NAME = name.upper()</span>
|
||||
<span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span> <span class="comment">// better</span>
|
||||
<span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -164,33 +161,36 @@
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Demonstrates that you can write the C++ equivalent of <tt class="literal">"format"
|
||||
% x,y,z</tt> in Python, which is useful since there's no easy way to
|
||||
Demonstrates that you can write the C++ equivalent of <code class="literal">"format"
|
||||
% x,y,z</code> in Python, which is useful since there's no easy way to
|
||||
do that in std C++.
|
||||
</p>
|
||||
<div class="sidebar"><p>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>Beware</b></span> the common pitfall
|
||||
<div class="sidebar">
|
||||
<div class="titlepage"></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>Beware</strong></span> the common pitfall
|
||||
of forgetting that the constructors of most of Python's mutable types make
|
||||
copies, just as in Python.
|
||||
</p></div>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__
|
||||
</span><span class="special">>>></span> <span class="identifier">d</span><span class="special">[</span><span class="string">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span> <span class="comment"># modifies the copy
|
||||
</span></pre>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__</span>
|
||||
<span class="special">>>></span> <span class="identifier">d</span><span class="special">[</span><span class="string">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span> <span class="comment"># modifies the copy</span>
|
||||
</pre>
|
||||
<p>
|
||||
C++:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
|
||||
</span><span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy
|
||||
</span></pre>
|
||||
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
|
||||
<a name="id470756"></a>
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__</span>
|
||||
<span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy</span>
|
||||
</pre>
|
||||
<h3>
|
||||
<a name="derived_object_types.class__lt_t_gt__as_objects"></a>
|
||||
class_<T> as objects
|
||||
</h2>
|
||||
</h3>
|
||||
<p>
|
||||
Due to the dynamic nature of Boost.Python objects, any <tt class="literal">class_<T></tt>
|
||||
Due to the dynamic nature of Boost.Python objects, any <code class="literal">class_<T></code>
|
||||
may also be one of these types! The following code snippet wraps the class
|
||||
(type) object.
|
||||
</p>
|
||||
@@ -206,19 +206,19 @@
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">vec345</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">)</span> <span class="special">==</span> <span class="number">5.0</span><span class="special">);</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.extracting_c___objects"></a>Extracting C++ objects</h3></div></div></div>
|
||||
<p>
|
||||
At some point, we will need to get C++ values out of object instances. This
|
||||
can be achieved with the <tt class="literal">extract<T></tt> function. Consider
|
||||
can be achieved with the <code class="literal">extract<T></code> function. Consider
|
||||
the following:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
|
||||
</span></pre>
|
||||
<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 <tt class="literal">object</tt>
|
||||
can't be implicitly converted to <tt class="literal">double</tt>s. Instead, what
|
||||
In the code above, we got a compiler error because Boost.Python <code class="literal">object</code>
|
||||
can't be implicitly converted to <code class="literal">double</code>s. Instead, what
|
||||
we wanted to do above can be achieved by writing:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">double</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>
|
||||
@@ -227,14 +227,14 @@
|
||||
</pre>
|
||||
<p>
|
||||
The first line attempts to extract the "length" attribute of the
|
||||
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>.
|
||||
Boost.Python <code class="literal">object</code>. The second line attempts to <span class="emphasis"><em>extract</em></span>
|
||||
the <code class="literal">Vec2</code> object from held by the Boost.Python <code class="literal">object</code>.
|
||||
</p>
|
||||
<p>
|
||||
Take note that we said "attempt to" above. What if the Boost.Python
|
||||
<tt class="literal">object</tt> does not really hold a <tt class="literal">Vec2</tt>
|
||||
<code class="literal">object</code> does not really hold a <code class="literal">Vec2</code>
|
||||
type? This is certainly a possibility considering the dynamic nature of Python
|
||||
<tt class="literal">object</tt>s. To be on the safe side, if the C++ type can't
|
||||
<code class="literal">object</code>s. To be on the safe side, if the C++ type can't
|
||||
be extracted, an appropriate exception is thrown. To avoid an exception,
|
||||
we need to test for extractibility:
|
||||
</p>
|
||||
@@ -243,20 +243,20 @@
|
||||
<span class="identifier">Vec2</span><span class="special">&</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 <tt class="literal">extract<T></tt>
|
||||
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <code class="literal">extract<T></code>
|
||||
facility in fact solves the mutable copying problem:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">dict</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="identifier">d</span><span class="special">[</span><span class="string">"whatever"</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies x.__dict__ !
|
||||
</span></pre>
|
||||
<span class="identifier">d</span><span class="special">[</span><span class="string">"whatever"</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies x.__dict__ !</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.enums"></a>Enums</h3></div></div></div>
|
||||
<p>
|
||||
Boost.Python has a nifty facility to capture and wrap C++ enums. While Python
|
||||
has no <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
|
||||
has no <code class="literal">enum</code> type, we'll often want to expose our C++ enums
|
||||
to Python as an <code class="literal">int</code>. Boost.Python's enum facility makes
|
||||
this easy while taking care of the proper conversions from Python's dynamic
|
||||
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
|
||||
to enums). To illustrate, given a C++ enum:
|
||||
@@ -273,18 +273,18 @@
|
||||
</pre>
|
||||
<p>
|
||||
can be used to expose to Python. The new enum type is created in the current
|
||||
<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>
|
||||
<code class="literal">scope()</code>, which is usually the current module. The snippet
|
||||
above creates a Python class derived from Python's <code class="literal">int</code>
|
||||
type which is associated with the C++ type passed as its first parameter.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top">
|
||||
<tr><td align="left" valign="top">
|
||||
<p>
|
||||
<span class="bold"><b>what is a scope?</b></span>
|
||||
<span class="bold"><strong>what is a scope?</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
The scope is a class that has an associated global Python object which
|
||||
@@ -296,8 +296,6 @@
|
||||
<p>
|
||||
You can access those values in Python as
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
<span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
</pre>
|
||||
@@ -305,24 +303,48 @@
|
||||
where my_module is the module where the enum is declared. You can also create
|
||||
a new scope around a class:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special"><</span><span class="identifier">X</span><span class="special">>(</span><span class="string">"X"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
|
||||
<span class="comment">// Expose X::nested as X.nested
|
||||
</span><span class="identifier">enum_</span><span class="special"><</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">>(</span><span class="string">"nested"</span><span class="special">)</span>
|
||||
<span class="comment">// Expose X::nested as X.nested</span>
|
||||
<span class="identifier">enum_</span><span class="special"><</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">>(</span><span class="string">"nested"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.creating_python_object"></a>Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
When you want a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> to manage a pointer to <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code>
|
||||
pyobj one does:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span> <span class="identifier">o</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">handle</span><span class="special"><>(</span><span class="identifier">pyobj</span><span class="special">));</span>
|
||||
</pre>
|
||||
<p>
|
||||
In this case, the <code class="computeroutput"><span class="identifier">o</span></code> object,
|
||||
manages the <code class="computeroutput"><span class="identifier">pyobj</span></code>, it won’t
|
||||
increase the reference count on construction.
|
||||
</p>
|
||||
<p>
|
||||
Otherwise, to use a borrowed reference:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span> <span class="identifier">o</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">handle</span><span class="special"><>(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">borrowed</span><span class="special">(</span><span class="identifier">pyobj</span><span class="special">)));</span>
|
||||
</pre>
|
||||
<p>
|
||||
In this case, <code class="computeroutput"><span class="identifier">Py_INCREF</span></code> is
|
||||
called, so <code class="computeroutput"><span class="identifier">pyobj</span></code> is not destructed
|
||||
when object o goes out of scope.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -332,7 +354,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> General Techniques</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<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">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>General Techniques</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 2.0">
|
||||
<link rel="prev" href="exception.html" title="Exception Translation">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@@ -19,11 +19,11 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a>
|
||||
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.techniques"></a> General Techniques</h2></div></div></div>
|
||||
<a name="python.techniques"></a>General Techniques</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="techniques.html#python.creating_packages">Creating Packages</a></span></dt>
|
||||
<dt><span class="section"><a href="techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
|
||||
@@ -33,7 +33,7 @@
|
||||
Here are presented some useful techniques that you can use while wrapping code
|
||||
with Boost.Python.
|
||||
</p>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.creating_packages"></a>Creating Packages</h3></div></div></div>
|
||||
<p>
|
||||
@@ -50,7 +50,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)
|
||||
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
|
||||
<code class="literal">sounds</code>. Our library already has a neat C++ namespace hierarchy,
|
||||
like so:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
|
||||
@@ -62,8 +62,8 @@
|
||||
him to write code like this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> <span class="comment"># echo is a C++ function
|
||||
</span></pre>
|
||||
<span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> <span class="comment"># echo is a C++ function</span>
|
||||
</pre>
|
||||
<p>
|
||||
The first step is to write the wrapping code. We have to export each module
|
||||
separately with Boost.Python, like this:
|
||||
@@ -90,18 +90,18 @@
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
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>.
|
||||
Compiling these files will generate the following Python extensions: <code class="literal">core.pyd</code>,
|
||||
<code class="literal">io.pyd</code> and <code class="literal">filters.pyd</code>.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
The extension <tt class="literal">.pyd</tt> is used for python extension modules,
|
||||
<tr><td align="left" valign="top"><p>
|
||||
The extension <code class="literal">.pyd</code> is used for python extension modules,
|
||||
which are just shared libraries. Using the default for your system, like
|
||||
<tt class="literal">.so</tt> for Unix and <tt class="literal">.dll</tt> for Windows,
|
||||
<code class="literal">.so</code> for Unix and <code class="literal">.dll</code> for Windows,
|
||||
works just as well.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
@@ -115,17 +115,15 @@
|
||||
io.pyd
|
||||
</pre>
|
||||
<p>
|
||||
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
|
||||
The file <code class="literal">__init__.py</code> is what tells Python that the directory
|
||||
<code class="literal">sounds/</code> is actually a Python package. It can be a empty
|
||||
file, but can also perform some magic, that will be shown later.
|
||||
</p>
|
||||
<p>
|
||||
Now our package is ready. All the user has to do is put <tt class="literal">sounds</tt>
|
||||
Now our package is ready. All the user has to do is put <code class="literal">sounds</code>
|
||||
into his <a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000" target="_top">PYTHONPATH</a>
|
||||
and fire up the interpreter:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="string">'file.mp3'</span><span class="special">)</span>
|
||||
@@ -146,8 +144,6 @@
|
||||
If we want this flexibility, we will have to complicate our package hierarchy
|
||||
a little. First, we will have to change the name of the extension modules:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">/* file core.cpp */</span>
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -157,7 +153,7 @@
|
||||
</pre>
|
||||
<p>
|
||||
Note that we added an underscore to the module name. The filename will have
|
||||
to be changed to <tt class="literal">_core.pyd</tt> as well, and we do the same
|
||||
to be changed to <code class="literal">_core.pyd</code> as well, and we do the same
|
||||
to the other extension modules. Now, we change our package hierarchy like
|
||||
so:
|
||||
</p>
|
||||
@@ -178,17 +174,15 @@
|
||||
to each one. But if we leave it that way, the user will have to access the
|
||||
functions in the core module with this syntax:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span>
|
||||
<span class="special">>>></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 <tt class="literal">__init__.py</tt>
|
||||
magic: everything that is brought to the <tt class="literal">__init__.py</tt> namespace
|
||||
which is not what we want. But here enters the <code class="literal">__init__.py</code>
|
||||
magic: everything that is brought to the <code class="literal">__init__.py</code> namespace
|
||||
can be accessed directly by the user. So, all we have to do is bring the
|
||||
entire namespace from <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>:
|
||||
entire namespace from <code class="literal">_core.pyd</code> to <code class="literal">core/__init__.py</code>.
|
||||
So add this line of code to <code class="literal">sounds/core/__init__.py</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
</pre>
|
||||
@@ -203,10 +197,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, <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
|
||||
Python function, <code class="literal">echo_noise</code>, to the <code class="literal">filters</code>
|
||||
package. This function applies both the <code class="literal">echo</code> and <code class="literal">noise</code>
|
||||
filters in sequence in the given <code class="literal">sound</code> object. We create
|
||||
a file named <code class="literal">sounds/filters/echo_noise.py</code> and code our
|
||||
function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">_filters</span>
|
||||
@@ -216,19 +210,19 @@
|
||||
<span class="keyword">return</span> <span class="identifier">s</span>
|
||||
</pre>
|
||||
<p>
|
||||
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</tt>:
|
||||
Next, we add this line to <code class="literal">sounds/filters/__init__.py</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
|
||||
</pre>
|
||||
<p>
|
||||
And that's it. The user now accesses this function like any other function
|
||||
from the <tt class="literal">filters</tt> package:
|
||||
from the <code class="literal">filters</code> package:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo_noise</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.extending_wrapped_objects_in_python"></a>Extending Wrapped Objects in Python</h3></div></div></div>
|
||||
<p>
|
||||
@@ -237,11 +231,11 @@
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
|
||||
<span class="special">>>></span>
|
||||
<span class="special">>>></span> <span class="comment"># a regular function
|
||||
</span><span class="special">>>></span> <span class="keyword">def</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span> <span class="keyword">return</span> <span class="string">'A C instance!'</span>
|
||||
<span class="special">>>></span> <span class="comment"># a regular function</span>
|
||||
<span class="special">>>></span> <span class="keyword">def</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span> <span class="keyword">return</span> <span class="string">'A C instance!'</span>
|
||||
<span class="special">>>></span>
|
||||
<span class="special">>>></span> <span class="comment"># now we turn it in a member function
|
||||
</span><span class="special">>>></span> <span class="identifier">C</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">C_str</span>
|
||||
<span class="special">>>></span> <span class="comment"># now we turn it in a member function</span>
|
||||
<span class="special">>>></span> <span class="identifier">C</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">C_str</span>
|
||||
<span class="special">>>></span>
|
||||
<span class="special">>>></span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">C</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">c</span>
|
||||
@@ -254,9 +248,7 @@
|
||||
</p>
|
||||
<p>
|
||||
We can do the same with classes that were wrapped with Boost.Python. Suppose
|
||||
we have a class <tt class="literal">point</tt> in C++:
|
||||
</p>
|
||||
<p>
|
||||
we have a class <code class="literal">point</code> in C++:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
|
||||
|
||||
@@ -266,46 +258,44 @@
|
||||
<span class="special">}</span>
|
||||
</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 <tt class="literal">geom/__init__.py</tt>:
|
||||
</p>
|
||||
<p>
|
||||
If we are using the technique from the previous session, <a class="link" href="techniques.html#python.creating_packages" title="Creating Packages">Creating
|
||||
Packages</a>, we can code directly into <code class="literal">geom/__init__.py</code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
|
||||
<span class="comment"># a regular function
|
||||
</span><span class="keyword">def</span> <span class="identifier">point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
<span class="comment"># a regular function</span>
|
||||
<span class="keyword">def</span> <span class="identifier">point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
<span class="keyword">return</span> <span class="identifier">str</span><span class="special">((</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">))</span>
|
||||
|
||||
<span class="comment"># now we turn it into a member function
|
||||
</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
|
||||
<span class="comment"># now we turn it into a member function</span>
|
||||
<span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><b>All</b></span> point instances created from C++ will
|
||||
<span class="bold"><strong>All</strong></span> point instances created from C++ will
|
||||
also have this member function! This technique has several advantages:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
Cut down compile times to zero for these additional functions
|
||||
</li>
|
||||
<li>
|
||||
Reduce the memory footprint to virtually zero
|
||||
</li>
|
||||
<li>
|
||||
Minimize the need to recompile
|
||||
</li>
|
||||
<li>
|
||||
Rapid prototyping (you can move the code to C++ if required without changing
|
||||
the interface)
|
||||
</li>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
Cut down compile times to zero for these additional functions
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Reduce the memory footprint to virtually zero
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Minimize the need to recompile
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Rapid prototyping (you can move the code to C++ if required without changing
|
||||
the interface)
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
You can even add a little syntactic sugar with the use of metaclasses. Let's
|
||||
create a special metaclass that "injects" methods in other classes.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment"># The one Boost.Python uses for all wrapped classes.
|
||||
</span><span class="comment"># You can use here any class exported by Boost instead of "point"
|
||||
</span><span class="identifier">BoostPythonMetaclass</span> <span class="special">=</span> <span class="identifier">point</span><span class="special">.</span><span class="identifier">__class__</span>
|
||||
<pre class="programlisting"><span class="comment"># The one Boost.Python uses for all wrapped classes.</span>
|
||||
<span class="comment"># You can use here any class exported by Boost instead of "point"</span>
|
||||
<span class="identifier">BoostPythonMetaclass</span> <span class="special">=</span> <span class="identifier">point</span><span class="special">.</span><span class="identifier">__class__</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">injector</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span>
|
||||
<span class="keyword">class</span> <span class="identifier">__metaclass__</span><span class="special">(</span><span class="identifier">BoostPythonMetaclass</span><span class="special">):</span>
|
||||
@@ -316,8 +306,8 @@
|
||||
<span class="identifier">setattr</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">k</span><span class="special">,</span><span class="identifier">v</span><span class="special">)</span>
|
||||
<span class="keyword">return</span> <span class="identifier">type</span><span class="special">.</span><span class="identifier">__init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">,</span> <span class="identifier">dict</span><span class="special">)</span>
|
||||
|
||||
<span class="comment"># inject some methods in the point foo
|
||||
</span><span class="keyword">class</span> <span class="identifier">more_point</span><span class="special">(</span><span class="identifier">injector</span><span class="special">,</span> <span class="identifier">point</span><span class="special">):</span>
|
||||
<span class="comment"># inject some methods in the point foo</span>
|
||||
<span class="keyword">class</span> <span class="identifier">more_point</span><span class="special">(</span><span class="identifier">injector</span><span class="special">,</span> <span class="identifier">point</span><span class="special">):</span>
|
||||
<span class="keyword">def</span> <span class="identifier">__repr__</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
<span class="keyword">return</span> <span class="string">'Point(x=%s, y=%s)'</span> <span class="special">%</span> <span class="special">(</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">)</span>
|
||||
<span class="keyword">def</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
@@ -346,7 +336,7 @@
|
||||
support.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.reducing_compiling_time"></a>Reducing Compiling Time</h3></div></div></div>
|
||||
<p>
|
||||
@@ -355,8 +345,6 @@
|
||||
can easily become too high. If this is causing you problems, you can split
|
||||
the class_ definitions in multiple files:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">/* file point.cpp */</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
@@ -376,7 +364,7 @@
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now you create a file <tt class="literal">main.cpp</tt>, which contains the <tt class="literal">BOOST_PYTHON_MODULE</tt>
|
||||
Now you create a file <code class="literal">main.cpp</code>, which contains the <code class="literal">BOOST_PYTHON_MODULE</code>
|
||||
macro, and call the various export functions inside it.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
|
||||
@@ -412,21 +400,21 @@
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
|
||||
take a look at the <tt class="literal">--multiple</tt> option, that generates
|
||||
take a look at the <code class="literal">--multiple</code> option, that generates
|
||||
the wrappers in various files as demonstrated here.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
This method is useful too if you are getting the error message <span class="emphasis"><em>"fatal
|
||||
error C1204:Compiler limit:internal structure overflow"</em></span>
|
||||
when compiling a large source file, as explained in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.
|
||||
@@ -436,7 +424,7 @@
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
@@ -446,7 +434,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a>
|
||||
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -62,7 +62,7 @@ resulting DLL is now visible to Python. Here's a sample Python session:
|
||||
[python]
|
||||
|
||||
>>> import hello_ext
|
||||
>>> print hello.greet()
|
||||
>>> print hello_ext.greet()
|
||||
hello, world
|
||||
|
||||
[c++]
|
||||
@@ -901,8 +901,8 @@ wrapping as outlined in the [link python.overloading previous section], or
|
||||
writing thin wrappers:
|
||||
|
||||
// write "thin wrappers"
|
||||
int f1(int x) { f(x); }
|
||||
int f2(int x, double y) { f(x,y); }
|
||||
int f1(int x) { return f(x); }
|
||||
int f2(int x, double y) { return f(x,y); }
|
||||
|
||||
/*...*/
|
||||
|
||||
@@ -1302,6 +1302,23 @@ create a new scope around a class:
|
||||
[def PyModule_GetDict [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-594 PyModule_GetDict]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:creating_python_object Creating `boost::python::object` from `PyObject*`]
|
||||
|
||||
When you want a `boost::python::object` to manage a pointer to `PyObject*` pyobj one does:
|
||||
|
||||
boost::python::object o(boost::python::handle<>(pyobj));
|
||||
|
||||
In this case, the `o` object, manages the `pyobj`, it won’t increase the reference count on construction.
|
||||
|
||||
Otherwise, to use a borrowed reference:
|
||||
|
||||
boost::python::object o(boost::python::handle<>(boost::python::borrowed(pyobj)));
|
||||
|
||||
In this case, `Py_INCREF` is called, so `pyobj` is not destructed when object o goes out of scope.
|
||||
|
||||
[endsect] [/ creating_python_object ]
|
||||
|
||||
[endsect] [/ Object Interface]
|
||||
|
||||
[section Embedding]
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace boost { namespace python
|
||||
struct arg
|
||||
{
|
||||
template <class T>
|
||||
arg &perator = (T const &value);
|
||||
arg &operator = (T const &value);
|
||||
explicit arg (char const *name){elements[0].name = name;}
|
||||
};
|
||||
|
||||
|
||||
@@ -96,10 +96,10 @@ template <class F, class Policies, class Keywords, class Signature>
|
||||
to <code>f</code>. <ul>
|
||||
<li> If <code>policies</code> are supplied, it
|
||||
will be applied to the function as described <a href=
|
||||
"CallPolicies.html">here</a>.
|
||||
"CallPolicies.html">here</a>.
|
||||
<li>If <code>keywords</code> are
|
||||
supplied, the keywords will be applied in order to the final
|
||||
arguments of the resulting function.
|
||||
arguments of the resulting function.
|
||||
<li>If <code>Signature</code>
|
||||
is supplied, it should be an instance of an <a
|
||||
href="../../../mpl/doc/refmanual/front-extensible-sequence.html">MPL front-extensible
|
||||
@@ -125,36 +125,33 @@ template <class F, class Policies, class Keywords, class Signature>
|
||||
</dl>
|
||||
|
||||
<pre>
|
||||
<a name=
|
||||
"make_constructor-spec"></a>template <class T, class ArgList, class Generator>
|
||||
<a href="object.html#object-spec">object</a> make_constructor();
|
||||
|
||||
template <class ArgList, class Generator, class Policies>
|
||||
<a name="make_constructor-spec">template <class F></a>
|
||||
<a href="object.html#object-spec">object</a> make_constructor(F f)
|
||||
|
||||
template <class F, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_constructor(Policies const& policies)
|
||||
"object.html#object-spec">object</a> make_constructor(F f, Policies const& policies)
|
||||
|
||||
template <class F, class Policies, class KeywordsOrSignature>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_constructor(F f, Policies const& policies, KeywordsOrSignature const& ks)
|
||||
|
||||
template <class F, class Policies, class Keywords, class Signature>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_constructor(F f, Policies const& policies, Keywords const& kw, Signature const& sig)
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is a class type.
|
||||
<code>Policies</code> is a model of <a href=
|
||||
"CallPolicies.html">CallPolicies</a>. <code>ArgList</code> is an <a
|
||||
href="../../../mpl/doc/refmanual/forward-sequence.html">MPL sequence</a> of C++ argument
|
||||
types (<i>A1, A2,... AN</i>) such that if
|
||||
<code>a1, a2</code>... <code>aN</code> are objects of type
|
||||
<i>A1, A2,... AN</i> respectively, the expression <code>new
|
||||
Generator::apply<T>::type(a1, a2</code>... <code>aN</code>)
|
||||
is valid. Generator is a model of <a href=
|
||||
"HolderGenerator.html">HolderGenerator</a>.</dt>
|
||||
<dt><b>Requires:</b> <code>F</code> is a
|
||||
function pointer type. If <code>policies</code> are supplied, it must
|
||||
be a model of <a href="CallPolicies.html">CallPolicies</a>. If
|
||||
<code>kewords</code> are supplied, it must be the result of a <a href=
|
||||
"args.html#keyword-expression"><em>keyword-expression</em></a>
|
||||
specifying no more arguments than the <a href=
|
||||
"definitions.html#arity">arity</a> of <code>f</code>.</dt>
|
||||
|
||||
<dt><b>Effects:</b> Creates a Python callable object which, when called
|
||||
from Python, expects its first argument to be a Boost.Python extension
|
||||
class object. It converts its remaining its arguments to C++ and passes
|
||||
them to the constructor of a dynamically-allocated
|
||||
<code>Generator::apply<T>::type</code> object, which is then
|
||||
installed in the extension class object. In the second form, the
|
||||
<code>policies</code> are applied to the arguments and result (<a href=
|
||||
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a>)
|
||||
of the Python callable object</dt>
|
||||
from Python, converts its arguments to C++ and calls <code>f</code>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> An instance of <a href=
|
||||
"object.html#object-spec">object</a> which holds the new Python
|
||||
@@ -186,7 +183,7 @@ BOOST_PYTHON_MODULE(make_function_test)
|
||||
def("choose_function", choose_function);
|
||||
}
|
||||
</pre>
|
||||
It can be used this way in Python:
|
||||
It can be used this way in Python:
|
||||
<pre>
|
||||
>>> from make_function_test import *
|
||||
>>> f = choose_function(1)
|
||||
|
||||
@@ -167,12 +167,13 @@ PyObject* postcall(PyObject* args, PyObject* result);
|
||||
|
||||
class Bar
|
||||
{
|
||||
public:
|
||||
Bar(int x) : x(x) {}
|
||||
int get_x() const { return x; }
|
||||
void set_x(int x) { this->x = x; }
|
||||
private:
|
||||
int x;
|
||||
}
|
||||
};
|
||||
|
||||
class Foo
|
||||
{
|
||||
@@ -189,7 +190,7 @@ class Foo
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE(internal_refs)
|
||||
{
|
||||
class_<Bar>("Bar")
|
||||
class_<Bar>("Bar", init<int>())
|
||||
.def("get_x", &Bar::get_x)
|
||||
.def("set_x", &Bar::set_x)
|
||||
;
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace boost { namespace python
|
||||
object stop();
|
||||
object step();
|
||||
|
||||
// The return type of slice::get_indicies()
|
||||
// The return type of slice::get_indices()
|
||||
template <typename RandomAccessIterator>
|
||||
struct range
|
||||
{
|
||||
@@ -96,7 +96,7 @@ namespace boost { namespace python
|
||||
|
||||
template <typename RandomAccessIterator>
|
||||
range<RandomAccessIterator>
|
||||
get_indicies(
|
||||
get_indices(
|
||||
RandomAccessIterator const& begin,
|
||||
RandomAccessIterator const& end);
|
||||
};
|
||||
@@ -164,7 +164,7 @@ slice object, but in practice they are usually integers.</dt>
|
||||
<pre>
|
||||
template <typename RandomAccessIterator>
|
||||
slice::range<RandomAccessIterator>
|
||||
slice::get_indicies(
|
||||
slice::get_indices(
|
||||
RandomAccessIterator const& begin,
|
||||
RandomAccessIterator const& end) const;
|
||||
</pre>
|
||||
@@ -173,8 +173,8 @@ slice::get_indicies(
|
||||
Iterators that form a half-open range.</dt>
|
||||
<dt><b>Effects:</b> Create a RandomAccessIterator pair that defines a
|
||||
fully-closed range within the [begin,end) range of its arguments.
|
||||
This function translates this slice's indicies while accounting for the
|
||||
effects of any PyNone or negative indicies, and non-singular step sizes.</dt>
|
||||
This function translates this slice's indices while accounting for the
|
||||
effects of any PyNone or negative indices, and non-singular step sizes.</dt>
|
||||
<dt><b>Returns:</b> a slice::range
|
||||
that has been initialized with a non-zero value of step and a pair of
|
||||
RandomAccessIterators that point within the range of this functions
|
||||
@@ -182,7 +182,7 @@ arguments and define a closed interval.</dt>
|
||||
<dt><b>Throws:</b> <a href="definitions.html#raise">Raises</a> a Python <code>TypeError</code> exception if any of this slice's arguments
|
||||
are neither references to <code>PyNone</code> nor convertible to <code>int</code>. Throws
|
||||
<code>std::invalid_argument</code> if the resulting range would be empty. You
|
||||
should always wrap calls to <code>slice::get_indicies()</code>
|
||||
should always wrap calls to <code>slice::get_indices()</code>
|
||||
within <code>try { ...; } catch (std::invalid_argument) {}</code> to
|
||||
handle this case and take appropriate action.</dt>
|
||||
<dt><b>Rationale</b>: closed-interval: If
|
||||
@@ -221,7 +221,7 @@ double partial_sum(std::vector<double> const& Foo, const slice index)
|
||||
{
|
||||
slice::range<std::vector<double>::const_iterator> bounds;
|
||||
try {
|
||||
bounds = index.get_indicies<>(Foo.begin(), Foo.end());
|
||||
bounds = index.get_indices<>(Foo.begin(), Foo.end());
|
||||
}
|
||||
catch (std::invalid_argument) {
|
||||
return 0.0;
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="introduction">Introduction</a>
|
||||
</h2>This header provides faciliites for establishing a lifetime
|
||||
</h2>This header provides facilities for establishing a lifetime
|
||||
dependency between two of a function's Python argument or result objects.
|
||||
The <i>ward</i> object will not be destroyed until after the custodian as
|
||||
long as the <i>custodian</i> object supports <a href=
|
||||
|
||||
5
example/Jamroot
Executable file → Normal file
5
example/Jamroot
Executable file → Normal file
@@ -11,7 +11,10 @@ use-project boost
|
||||
# boost_python library from the project whose global ID is
|
||||
# /boost/python.
|
||||
project
|
||||
: requirements <library>/boost/python//boost_python ;
|
||||
: requirements <library>/boost/python//boost_python
|
||||
<implicit-dependency>/boost//headers
|
||||
: usage-requirements <implicit-dependency>/boost//headers
|
||||
;
|
||||
|
||||
# Declare the three extension modules. You can specify multiple
|
||||
# source files after the colon separated by spaces.
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Edit this path to point at the tools/build/v2 subdirectory of your
|
||||
# Edit this path to point at the tools/build/src subdirectory of your
|
||||
# Boost installation. Absolute paths work, too.
|
||||
boost-build ../../../tools/build/v2 ;
|
||||
boost-build ../../../tools/build/src ;
|
||||
|
||||
4
example/quickstart/Jamroot
Executable file → Normal file
4
example/quickstart/Jamroot
Executable file → Normal file
@@ -12,6 +12,8 @@ use-project boost
|
||||
# /boost/python.
|
||||
project boost-python-quickstart
|
||||
: requirements <library>/boost/python//boost_python
|
||||
<implicit-dependency>/boost//headers
|
||||
: usage-requirements <implicit-dependency>/boost//headers
|
||||
;
|
||||
|
||||
# Make the definition of the python-extension rule available
|
||||
@@ -29,7 +31,7 @@ import testing ;
|
||||
testing.make-test run-pyd : extending test_extending.py : : test_ext ;
|
||||
|
||||
# Declare a test of the embedding application
|
||||
testing.run embedding
|
||||
testing.run embedding embedding.cpp
|
||||
: # any ordinary arguments
|
||||
: script.py # any arguments that should be treated as relative paths
|
||||
: # requirements
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Edit this path to point at the tools/build/v2 subdirectory of your
|
||||
# Edit this path to point at the tools/build/src subdirectory of your
|
||||
# Boost installation. Absolute paths work, too.
|
||||
boost-build ../../../../tools/build/v2 ;
|
||||
boost-build ../../../../tools/build/src ;
|
||||
|
||||
@@ -20,12 +20,23 @@ use-project boost
|
||||
# boost_python library from the project whose global ID is
|
||||
# /boost/python.
|
||||
project
|
||||
: requirements <library>/boost/python//boost_python ;
|
||||
: requirements <library>/boost/python//boost_python
|
||||
<implicit-dependency>/boost//headers
|
||||
: usage-requirements <implicit-dependency>/boost//headers
|
||||
;
|
||||
|
||||
# Declare the three extension modules. You can specify multiple
|
||||
# source files after the colon separated by spaces.
|
||||
python-extension hello_ext : hello.cpp ;
|
||||
|
||||
# Put the extension and Boost.Python DLL in the current directory, so
|
||||
# that running script by hand works.
|
||||
install convenient_copy
|
||||
: hello_ext
|
||||
: <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
|
||||
<location>.
|
||||
;
|
||||
|
||||
# A little "rule" (function) to clean up the syntax of declaring tests
|
||||
# of these extension modules.
|
||||
local rule run-test ( test-name : sources + )
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
# include <boost/python/pointee.hpp>
|
||||
# include <boost/python/pure_virtual.hpp>
|
||||
# include <boost/python/ptr.hpp>
|
||||
# include <boost/python/raw_function.hpp>
|
||||
# include <boost/python/reference_existing_object.hpp>
|
||||
# include <boost/python/register_ptr_to_python.hpp>
|
||||
# include <boost/python/return_arg.hpp>
|
||||
@@ -61,7 +62,9 @@
|
||||
# include <boost/python/return_value_policy.hpp>
|
||||
# include <boost/python/scope.hpp>
|
||||
# include <boost/python/self.hpp>
|
||||
# include <boost/python/slice.hpp>
|
||||
# include <boost/python/slice_nil.hpp>
|
||||
# include <boost/python/stl_iterator.hpp>
|
||||
# include <boost/python/str.hpp>
|
||||
# include <boost/python/to_python_converter.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
|
||||
@@ -102,7 +102,6 @@ namespace detail
|
||||
return this->operator,(python::arg(name));
|
||||
}
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
struct is_keywords
|
||||
{
|
||||
@@ -126,31 +125,6 @@ namespace detail
|
||||
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)
|
||||
|
||||
@@ -29,7 +29,6 @@ struct back_reference
|
||||
T m_value;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
class is_back_reference
|
||||
{
|
||||
@@ -44,36 +43,6 @@ class is_back_reference<back_reference<T> >
|
||||
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
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T> struct specifies_bases
|
||||
: mpl::false_
|
||||
{
|
||||
@@ -35,23 +34,6 @@ namespace boost { namespace python {
|
||||
: 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_<
|
||||
|
||||
@@ -45,8 +45,7 @@
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) \
|
||||
/* pro9 reintroduced the bug */ \
|
||||
|| (BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) \
|
||||
|| BOOST_WORKAROUND(__GNUC__, < 3)
|
||||
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
|
||||
|
||||
# define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1
|
||||
|
||||
@@ -138,7 +137,8 @@ namespace detail
|
||||
static void
|
||||
must_be_derived_class_member(Default const&)
|
||||
{
|
||||
typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
|
||||
// https://svn.boost.org/trac/boost/ticket/5803
|
||||
//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
|
||||
@@ -301,7 +301,6 @@ class class_ : public objects::class_base
|
||||
}
|
||||
|
||||
// Property creation
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
template <class Get>
|
||||
self& add_property(char const* name, Get fget, char const* docstr = 0)
|
||||
{
|
||||
@@ -316,47 +315,6 @@ class class_ : public objects::class_base
|
||||
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)
|
||||
|
||||
4
include/boost/python/converter/arg_from_python.hpp
Executable file → Normal file
4
include/boost/python/converter/arg_from_python.hpp
Executable file → Normal file
@@ -115,9 +115,9 @@ struct arg_rvalue_from_python
|
||||
arg_rvalue_from_python(PyObject*);
|
||||
bool convertible() const;
|
||||
|
||||
# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
|
||||
# if _MSC_FULL_VER > 13102196
|
||||
typename arg_rvalue_from_python<T>::
|
||||
# endif
|
||||
# endif
|
||||
result_type operator()();
|
||||
|
||||
private:
|
||||
|
||||
8
include/boost/python/converter/arg_to_python_base.hpp
Executable file → Normal file
8
include/boost/python/converter/arg_to_python_base.hpp
Executable file → Normal file
@@ -13,17 +13,9 @@ 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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -122,9 +122,30 @@ 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
|
||||
# if defined(_MSC_VER) && defined(_WIN64) && PY_VERSION_HEX < 0x03000000
|
||||
/* Under 64-bit Windows std::size_t is "unsigned long long". To avoid
|
||||
getting a Python long for each std::size_t the value is checked before
|
||||
the conversion. A std::size_t is converted to a simple Python int
|
||||
if possible; a Python long appears only if the value is too small or
|
||||
too large to fit into a simple int. */
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(
|
||||
signed BOOST_PYTHON_LONG_LONG,
|
||||
( x < static_cast<signed BOOST_PYTHON_LONG_LONG>(
|
||||
(std::numeric_limits<long>::min)())
|
||||
|| x > static_cast<signed BOOST_PYTHON_LONG_LONG>(
|
||||
(std::numeric_limits<long>::max)()))
|
||||
? ::PyLong_FromLongLong(x)
|
||||
: ::PyInt_FromLong(static_cast<long>(x)), &PyInt_Type)
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(
|
||||
unsigned BOOST_PYTHON_LONG_LONG,
|
||||
x > static_cast<unsigned BOOST_PYTHON_LONG_LONG>(
|
||||
(std::numeric_limits<long>::max)())
|
||||
? ::PyLong_FromUnsignedLongLong(x)
|
||||
: ::PyInt_FromLong(static_cast<long>(x)), &PyInt_Type)
|
||||
//
|
||||
# elif defined(HAVE_LONG_LONG) // using Python's macro instead of Boost's
|
||||
// - we don't seem to get the config right
|
||||
// all the time.
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyLong_Type)
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyLong_Type)
|
||||
# endif
|
||||
|
||||
74
include/boost/python/converter/object_manager.hpp
Executable file → Normal file
74
include/boost/python/converter/object_manager.hpp
Executable file → Normal file
@@ -121,7 +121,6 @@ struct is_object_manager
|
||||
{
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager
|
||||
: mpl::false_
|
||||
@@ -151,79 +150,6 @@ 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
|
||||
|
||||
|
||||
@@ -44,8 +44,7 @@ struct registered
|
||||
{
|
||||
};
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
||||
# if !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
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct registration;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct registered_pointee
|
||||
: registered<
|
||||
@@ -26,37 +25,6 @@ struct registered_pointee
|
||||
>
|
||||
{
|
||||
};
|
||||
# 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
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace registry
|
||||
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);
|
||||
BOOST_PYTHON_DECL void insert(convertible_function, type_info, PyTypeObject const* (*expected_pytype)() = 0);
|
||||
|
||||
// Insert an rvalue from_python converter
|
||||
BOOST_PYTHON_DECL void insert(
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct copy_const_reference_expects_a_const_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
# if defined(__GNUC__) || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct copy_non_const_reference_expects_a_non_const_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
# if defined(__GNUC__) || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
|
||||
@@ -270,7 +270,7 @@ inline object make_getter(D& x)
|
||||
return detail::make_getter(x, policy, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
|
||||
# if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
# if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
|
||||
template <class D>
|
||||
inline object make_getter(D const& d)
|
||||
{
|
||||
@@ -305,7 +305,7 @@ 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))
|
||||
# if BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
|
||||
template <class D>
|
||||
inline object make_setter(D const& x)
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ 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__)
|
||||
# if defined(__GNUC__) || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
|
||||
30
include/boost/python/detail/borrowed_ptr.hpp
Executable file → Normal file
30
include/boost/python/detail/borrowed_ptr.hpp
Executable file → Normal file
@@ -19,7 +19,6 @@ template<class T> class borrowed
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
struct is_borrowed_ptr
|
||||
{
|
||||
@@ -68,35 +67,6 @@ struct is_borrowed_ptr<T*>
|
||||
};
|
||||
# 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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
# 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
|
||||
@@ -76,13 +73,13 @@
|
||||
|
||||
# if BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
|
||||
# if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_DECL __attribute__ ((visibility("default")))
|
||||
# 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")))
|
||||
# define BOOST_PYTHON_DECL_EXCEPTION __attribute__ ((__visibility__("default")))
|
||||
# elif (defined(_WIN32) || defined(__CYGWIN__))
|
||||
# if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_DECL __declspec(dllexport)
|
||||
|
||||
@@ -8,13 +8,7 @@
|
||||
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
|
||||
)
|
||||
void construct_pointee(void* storage, Arg& x, T const volatile*)
|
||||
{
|
||||
new (storage) T(x);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ 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_);
|
||||
BOOST_STATIC_CONSTANT(bool, is_volatile = is_volatile_);
|
||||
};
|
||||
|
||||
typedef cv_tag<false,false> cv_unqualified;
|
||||
|
||||
@@ -7,25 +7,12 @@
|
||||
|
||||
# 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 <bool array> struct value_destroyer;
|
||||
|
||||
template <>
|
||||
struct value_destroyer<
|
||||
false
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
||||
, false
|
||||
# endif
|
||||
>
|
||||
struct value_destroyer<false>
|
||||
{
|
||||
template <class T>
|
||||
static void execute(T const volatile* p)
|
||||
@@ -35,12 +22,7 @@ struct value_destroyer<
|
||||
};
|
||||
|
||||
template <>
|
||||
struct value_destroyer<
|
||||
true
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
||||
, false
|
||||
# endif
|
||||
>
|
||||
struct value_destroyer<true>
|
||||
{
|
||||
template <class A, class T>
|
||||
static void execute(A*, T const volatile* const first)
|
||||
@@ -49,9 +31,6 @@ struct value_destroyer<
|
||||
{
|
||||
value_destroyer<
|
||||
boost::is_array<T>::value
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
||||
, boost::is_enum<T>::value
|
||||
# endif
|
||||
>::execute(p);
|
||||
}
|
||||
}
|
||||
@@ -63,25 +42,6 @@ struct value_destroyer<
|
||||
}
|
||||
};
|
||||
|
||||
# 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& (*)())
|
||||
{
|
||||
@@ -89,9 +49,6 @@ inline void destroy_referent_impl(void* p, T& (*)())
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
35
include/boost/python/detail/enable_if.hpp
Executable file → Normal file
35
include/boost/python/detail/enable_if.hpp
Executable file → Normal file
@@ -7,40 +7,7 @@
|
||||
# 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)
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
# include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
14
include/boost/python/detail/force_instantiate.hpp
Executable file → Normal file
14
include/boost/python/detail/force_instantiate.hpp
Executable file → Normal file
@@ -10,23 +10,9 @@ namespace boost { namespace python { namespace detail {
|
||||
// Allows us to force the argument to be instantiated without
|
||||
// incurring unused variable warnings
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC < 1300 || _MSC_FULL_VER > 13102196
|
||||
|
||||
template <class T>
|
||||
inline void force_instantiate(T const&) {}
|
||||
|
||||
# else
|
||||
|
||||
# pragma optimize("g", off)
|
||||
inline void force_instantiate_impl(...) {}
|
||||
# pragma optimize("", on)
|
||||
template <class T>
|
||||
inline void force_instantiate(T const& x)
|
||||
{
|
||||
detail::force_instantiate_impl(&x);
|
||||
}
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // FORCE_INSTANTIATE_DWA200265_HPP
|
||||
|
||||
@@ -25,46 +25,11 @@ struct if_selected
|
||||
};
|
||||
};
|
||||
|
||||
# if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
|
||||
namespace msvc70_aux {
|
||||
|
||||
template< bool > struct inherit_from
|
||||
{
|
||||
template< typename T > struct result
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<> struct inherit_from<true>
|
||||
{
|
||||
template< typename T > struct result
|
||||
{
|
||||
struct type {};
|
||||
};
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct never_true
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
} // namespace msvc70_aux
|
||||
|
||||
#endif // # if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
|
||||
|
||||
template <class T>
|
||||
struct elif_selected
|
||||
{
|
||||
# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407)
|
||||
# if !(defined(__MWERKS__) && __MWERKS__ <= 0x2407)
|
||||
template <class U> class then;
|
||||
# elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
|
||||
template <class U>
|
||||
struct then : msvc70_aux::inherit_from< msvc70_aux::never_true<U>::value >
|
||||
::template result< if_selected<T> >::type
|
||||
{
|
||||
};
|
||||
# else
|
||||
template <class U>
|
||||
struct then : if_selected<T>
|
||||
@@ -73,7 +38,7 @@ struct elif_selected
|
||||
# endif
|
||||
};
|
||||
|
||||
# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407)
|
||||
# if !(defined(__MWERKS__) && __MWERKS__ <= 0x2407)
|
||||
template <class T>
|
||||
template <class U>
|
||||
class elif_selected<T>::then : public if_selected<T>
|
||||
|
||||
@@ -57,7 +57,7 @@ object make_keyword_range_constructor(
|
||||
, Holder* = 0
|
||||
, ArgList* = 0, Arity* = 0)
|
||||
{
|
||||
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
|
||||
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
|
||||
python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_();
|
||||
#endif
|
||||
return detail::make_keyword_range_function(
|
||||
|
||||
@@ -7,15 +7,18 @@
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/type_traits/config.hpp>
|
||||
|
||||
//
|
||||
// Fix for MSVC's broken typeid() implementation which doesn't strip
|
||||
// Fix for icc's broken typeid() implementation which doesn't strip
|
||||
// decoration. This fix doesn't handle cv-qualified array types. It
|
||||
// could probably be done, but I haven't figured it out yet.
|
||||
//
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 700
|
||||
// Note: This file is badly named. It initially was MSVC specific, but was
|
||||
// extended to cover intel too. Now the old version of MSVC is no longer
|
||||
// supported, but the intel version is still supported.
|
||||
|
||||
# if defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 700
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
@@ -44,8 +47,14 @@ inline typeinfo typeid_ref(type<T>*, ...)
|
||||
return detail::typeid_ref_1((T(*)())0);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32))
|
||||
# define BOOST_PYTT_DECL __cdecl
|
||||
#else
|
||||
# define BOOST_PYTT_DECL /**/
|
||||
#endif
|
||||
|
||||
template< typename T > T&(* is_ref_tester1(type<T>) )(type<T>) { return 0; }
|
||||
inline char BOOST_TT_DECL is_ref_tester1(...) { return 0; }
|
||||
inline char BOOST_PYTT_DECL is_ref_tester1(...) { return 0; }
|
||||
|
||||
template <class T>
|
||||
inline typeinfo msvc_typeid(boost::type<T>*)
|
||||
@@ -71,5 +80,5 @@ inline typeinfo assert_array_typeid_compiles()
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
# endif // BOOST_MSVC
|
||||
# endif // BOOST_INTEL_CXX_VERSION
|
||||
#endif // MSVC_TYPEINFO_DWA200222_HPP
|
||||
|
||||
@@ -53,6 +53,9 @@ enum operator_id
|
||||
op_nonzero,
|
||||
#endif
|
||||
op_repr
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
,op_truediv
|
||||
#endif
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -42,7 +42,6 @@ union aligned_storage
|
||||
// but sizeof() is broken in CodeWarriors <= 8.0
|
||||
template <class T> struct referent_size;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
struct referent_size<T&>
|
||||
@@ -51,15 +50,6 @@ union aligned_storage
|
||||
std::size_t, value = sizeof(T));
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
template <class T> struct referent_size
|
||||
{
|
||||
static T f();
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f()));
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
// A metafunction returning a POD type which can store U, where T ==
|
||||
// U&. If T is not a reference type, returns a POD which can store T.
|
||||
|
||||
@@ -43,9 +43,7 @@ namespace boost { namespace python { namespace detail {
|
||||
template <class R, class T>
|
||||
boost::type<R>* result(R (T::*), int = 0) { return 0; }
|
||||
|
||||
# if (defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140) \
|
||||
|| (defined(__GNUC__) && __GNUC__ < 3) \
|
||||
|| (defined(__MWERKS__) && __MWERKS__ < 0x3000)
|
||||
# if (defined(__MWERKS__) && __MWERKS__ < 0x3000)
|
||||
// This code actually works on all implementations, but why use it when we don't have to?
|
||||
template <class T>
|
||||
struct get_result_type
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_string_literal : mpl::false_
|
||||
{
|
||||
@@ -45,43 +44,6 @@ struct is_string_literal<T[n]>
|
||||
{
|
||||
};
|
||||
# endif
|
||||
# else
|
||||
template <bool is_array = true>
|
||||
struct string_literal_helper
|
||||
{
|
||||
typedef char (&yes_string_literal)[1];
|
||||
typedef char (&no_string_literal)[2];
|
||||
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef apply<T> self;
|
||||
static T x;
|
||||
static yes_string_literal check(char const*);
|
||||
static no_string_literal check(char*);
|
||||
static no_string_literal check(void const volatile*);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct string_literal_helper<false>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : mpl::false_
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_string_literal
|
||||
: string_literal_helper<is_array<T>::value>::apply<T>
|
||||
{
|
||||
};
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
|
||||
@@ -30,10 +30,6 @@
|
||||
# include <boost/mpl/vector/vector10.hpp>
|
||||
# endif
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
# include <boost/python/detail/type_list_impl.hpp>
|
||||
# else
|
||||
# include <boost/python/detail/type_list_impl_no_pts.hpp>
|
||||
# endif
|
||||
|
||||
#endif // TYPE_LIST_DWA2002913_HPP
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
#ifndef 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 TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP
|
||||
# define TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP
|
||||
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
# include <boost/preprocessor/enum_params_with_a_default.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
# include <boost/preprocessor/empty.hpp>
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/mpl/void.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template< typename T >
|
||||
struct is_list_arg
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_list_arg<mpl::void_>
|
||||
{
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template<int> struct type_list_impl_chooser;
|
||||
|
||||
# define BOOST_PYTHON_LIST_ACTUAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,T)
|
||||
# define BOOST_PYTHON_LIST_FORMAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,class T)
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, BOOST_PYTHON_LIST_SIZE, <boost/python/detail/type_list_impl_no_pts.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
# define BOOST_PYTHON_PLUS() +
|
||||
# define BOOST_PYTHON_IS_LIST_ARG(z, n, data) \
|
||||
BOOST_PP_IF(n, BOOST_PYTHON_PLUS, BOOST_PP_EMPTY)() \
|
||||
is_list_arg< BOOST_PP_CAT(T,n) >::value
|
||||
|
||||
template<
|
||||
BOOST_PYTHON_LIST_FORMAL_PARAMS
|
||||
>
|
||||
struct type_list_count_args
|
||||
{
|
||||
enum { value =
|
||||
BOOST_PP_REPEAT_1(BOOST_PYTHON_LIST_SIZE, BOOST_PYTHON_IS_LIST_ARG, _)
|
||||
};
|
||||
};
|
||||
|
||||
template<
|
||||
BOOST_PYTHON_LIST_FORMAL_PARAMS
|
||||
>
|
||||
struct type_list_impl
|
||||
{
|
||||
typedef type_list_count_args< BOOST_PYTHON_LIST_ACTUAL_PARAMS > arg_num_;
|
||||
typedef typename detail::type_list_impl_chooser< arg_num_::value >
|
||||
::template result_< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type type;
|
||||
};
|
||||
|
||||
template<
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_)
|
||||
>
|
||||
struct type_list
|
||||
: detail::type_list_impl< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type
|
||||
{
|
||||
typedef typename detail::type_list_impl<
|
||||
BOOST_PYTHON_LIST_ACTUAL_PARAMS
|
||||
>::type type;
|
||||
};
|
||||
|
||||
# undef BOOST_PYTHON_IS_LIST_ARG
|
||||
# undef BOOST_PYTHON_PLUS
|
||||
# undef BOOST_PYTHON_LIST_FORMAL_PARAMS
|
||||
# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
# endif // TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP
|
||||
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
|
||||
template<>
|
||||
struct type_list_impl_chooser<N>
|
||||
{
|
||||
template<
|
||||
BOOST_PYTHON_LIST_FORMAL_PARAMS
|
||||
>
|
||||
struct result_
|
||||
{
|
||||
typedef typename BOOST_PP_CAT(mpl::vector,N)<
|
||||
BOOST_PP_ENUM_PARAMS(N, T)
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
@@ -9,35 +9,6 @@
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
# include <boost/type_traits/is_reference.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
|
||||
# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \
|
||||
template <class X_> \
|
||||
struct value_is_##name \
|
||||
{ \
|
||||
typedef char yes; \
|
||||
typedef char (&no)[2]; \
|
||||
\
|
||||
static typename add_reference<X_>::type dummy; \
|
||||
\
|
||||
template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \
|
||||
static yes test( \
|
||||
qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) > const&, int \
|
||||
); \
|
||||
\
|
||||
template <class U> \
|
||||
static no test(U&, ...); \
|
||||
\
|
||||
BOOST_STATIC_CONSTANT( \
|
||||
bool, value \
|
||||
= (sizeof(test(dummy, 0)) == sizeof(yes))); \
|
||||
\
|
||||
typedef mpl::bool_<value> type; \
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
@@ -57,6 +28,5 @@ struct value_is_##name \
|
||||
\
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
#endif // VALUE_IS_XXX_DWA2003224_HPP
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
|
||||
# include <boost/bind.hpp>
|
||||
# include <boost/bind/placeholders.hpp>
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/python/detail/translate_exception.hpp>
|
||||
# include <boost/python/detail/exception_handler.hpp>
|
||||
@@ -18,7 +19,7 @@ template <class ExceptionType, class Translate>
|
||||
void register_exception_translator(Translate translate, boost::type<ExceptionType>* = 0)
|
||||
{
|
||||
detail::register_exception_handler(
|
||||
bind<bool>(detail::translate_exception<ExceptionType,Translate>(), _1, _2, translate)
|
||||
boost::bind<bool>(detail::translate_exception<ExceptionType,Translate>(), _1, _2, translate)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@
|
||||
# include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
|
||||
# include <boost/python/detail/void_ptr.hpp>
|
||||
# include <boost/python/detail/void_return.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/call_traits.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
|
||||
// workaround for VC++ 6.x or 7.0
|
||||
#if BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
|
||||
# define BOOST_EXTRACT_WORKAROUND ()
|
||||
#else
|
||||
# define BOOST_EXTRACT_WORKAROUND
|
||||
|
||||
27
include/boost/python/handle.hpp
Executable file → Normal file
27
include/boost/python/handle.hpp
Executable file → Normal file
@@ -87,8 +87,6 @@ class handle
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
|
||||
|
||||
template<typename Y>
|
||||
handle& operator=(handle<Y> const & r) // never throws
|
||||
{
|
||||
@@ -97,8 +95,6 @@ class handle
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Y>
|
||||
handle(handle<Y> const& r)
|
||||
: m_p(python::xincref(python::upcast<T>(r.get())))
|
||||
@@ -159,7 +155,6 @@ typedef handle<PyTypeObject> type_handle;
|
||||
//
|
||||
// Compile-time introspection
|
||||
//
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
class is_handle
|
||||
{
|
||||
@@ -173,28 +168,6 @@ class is_handle<handle<T> >
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
# else
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_handle_t)[1];
|
||||
typedef char (&no_handle_t)[2];
|
||||
|
||||
no_handle_t is_handle_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_handle_t is_handle_test(boost::type< handle<T> >);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class is_handle
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_handle_test(boost::type<T>()))
|
||||
== sizeof(detail::yes_handle_t)));
|
||||
};
|
||||
# endif
|
||||
|
||||
//
|
||||
// implementations
|
||||
|
||||
@@ -76,27 +76,6 @@ namespace detail
|
||||
//
|
||||
// This metaprogram checks if T is an optional
|
||||
//
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <class T>
|
||||
struct is_optional {
|
||||
|
||||
private:
|
||||
|
||||
template <BOOST_PYTHON_OVERLOAD_TYPES>
|
||||
static boost::type_traits::yes_type f(optional<BOOST_PYTHON_OVERLOAD_ARGS>);
|
||||
static boost::type_traits::no_type f(...);
|
||||
static T t();
|
||||
|
||||
public:
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value =
|
||||
sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
struct is_optional
|
||||
@@ -108,7 +87,6 @@ namespace detail
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
#endif
|
||||
|
||||
template <int NDefaults>
|
||||
struct define_class_init_helper;
|
||||
|
||||
2
include/boost/python/instance_holder.hpp
Executable file → Normal file
2
include/boost/python/instance_holder.hpp
Executable file → Normal file
@@ -7,7 +7,7 @@
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/noncopyable.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
|
||||
@@ -104,14 +104,6 @@ namespace detail
|
||||
|
||||
// If the BasePolicy_ supplied a result converter it would be
|
||||
// ignored; issue an error if it's not the default.
|
||||
#if defined _MSC_VER && _MSC_VER < 1300
|
||||
typedef is_same<
|
||||
typename BasePolicy_::result_converter
|
||||
, default_result_converter
|
||||
> same_result_converter;
|
||||
//see above for explanation
|
||||
BOOST_STATIC_ASSERT(same_result_converter::value) ;
|
||||
#else
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
(is_same<
|
||||
typename BasePolicy_::result_converter
|
||||
@@ -120,7 +112,6 @@ namespace detail
|
||||
, MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
|
||||
, (typename BasePolicy_::result_converter)
|
||||
);
|
||||
#endif
|
||||
typedef constructor_result_converter result_converter;
|
||||
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct manage_new_object_requires_a_pointer_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
# if defined(__GNUC__) || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
|
||||
@@ -6,57 +6,86 @@
|
||||
# define MODULE_INIT_DWA20020722_HPP
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/preprocessor/stringize.hpp>
|
||||
|
||||
# ifndef BOOST_PYTHON_MODULE_INIT
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
# if PY_VERSION_HEX >= 0x03000000
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef&, void(*)());
|
||||
|
||||
#else
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
# if PY_VERSION_HEX >= 0x03000000
|
||||
|
||||
# define _BOOST_PYTHON_MODULE_INIT(name) \
|
||||
PyObject* PyInit_##name() \
|
||||
{ \
|
||||
return boost::python::detail::init_module( \
|
||||
#name,&init_module_##name); \
|
||||
} \
|
||||
void init_module_##name()
|
||||
# define _BOOST_PYTHON_MODULE_INIT(name) \
|
||||
PyObject* BOOST_PP_CAT(PyInit_, name)() \
|
||||
{ \
|
||||
static PyModuleDef_Base initial_m_base = { \
|
||||
PyObject_HEAD_INIT(NULL) \
|
||||
0, /* m_init */ \
|
||||
0, /* m_index */ \
|
||||
0 /* m_copy */ }; \
|
||||
static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; \
|
||||
\
|
||||
static struct PyModuleDef moduledef = { \
|
||||
initial_m_base, \
|
||||
BOOST_PP_STRINGIZE(name), \
|
||||
0, /* m_doc */ \
|
||||
-1, /* m_size */ \
|
||||
initial_methods, \
|
||||
0, /* m_reload */ \
|
||||
0, /* m_traverse */ \
|
||||
0, /* m_clear */ \
|
||||
0, /* m_free */ \
|
||||
}; \
|
||||
\
|
||||
return boost::python::detail::init_module( \
|
||||
moduledef, BOOST_PP_CAT(init_module_, name) ); \
|
||||
} \
|
||||
void BOOST_PP_CAT(init_module_, name)()
|
||||
|
||||
# else
|
||||
|
||||
# define _BOOST_PYTHON_MODULE_INIT(name) \
|
||||
void init##name() \
|
||||
void BOOST_PP_CAT(init,name)() \
|
||||
{ \
|
||||
boost::python::detail::init_module( \
|
||||
#name,&init_module_##name); \
|
||||
BOOST_PP_STRINGIZE(name),&BOOST_PP_CAT(init_module_,name)); \
|
||||
} \
|
||||
void init_module_##name()
|
||||
void BOOST_PP_CAT(init_module_,name)()
|
||||
|
||||
# endif
|
||||
|
||||
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
|
||||
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) \
|
||||
void init_module_##name(); \
|
||||
void BOOST_PP_CAT(init_module_,name)(); \
|
||||
extern "C" __declspec(dllexport) _BOOST_PYTHON_MODULE_INIT(name)
|
||||
|
||||
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
|
||||
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) \
|
||||
void init_module_##name(); \
|
||||
extern "C" __attribute__ ((visibility("default"))) _BOOST_PYTHON_MODULE_INIT(name)
|
||||
void BOOST_PP_CAT(init_module_,name)(); \
|
||||
extern "C" __attribute__ ((__visibility__("default"))) _BOOST_PYTHON_MODULE_INIT(name)
|
||||
|
||||
# else
|
||||
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) \
|
||||
void init_module_##name(); \
|
||||
void BOOST_PP_CAT(init_module_,name)(); \
|
||||
extern "C" _BOOST_PYTHON_MODULE_INIT(name)
|
||||
|
||||
# endif
|
||||
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif // MODULE_INIT_DWA20020722_HPP
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
# define CLASS_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/python/object_core.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
10
include/boost/python/object/class_metadata.hpp
Executable file → Normal file
10
include/boost/python/object/class_metadata.hpp
Executable file → Normal file
@@ -53,11 +53,7 @@ struct register_base_of
|
||||
template <class Base>
|
||||
inline void operator()(Base*) const
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
BOOST_MPL_ASSERT_NOT((is_same<Base,Derived>));
|
||||
# else
|
||||
BOOST_STATIC_ASSERT(!(is_same<Base,Derived>::value));
|
||||
# endif
|
||||
|
||||
// Register the Base class
|
||||
register_dynamic_id<Base>();
|
||||
@@ -238,7 +234,7 @@ struct class_metadata
|
||||
//
|
||||
inline static void maybe_register_pointer_to_python(...) {}
|
||||
|
||||
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
|
||||
{
|
||||
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
|
||||
@@ -255,7 +251,7 @@ struct class_metadata
|
||||
, make_ptr_instance<T2, pointer_holder<held_type, T2> >
|
||||
>()
|
||||
);
|
||||
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
// explicit qualification of type_id makes msvc6 happy
|
||||
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
|
||||
#endif
|
||||
@@ -270,7 +266,7 @@ struct class_metadata
|
||||
inline static void maybe_register_class_to_python(T2*, mpl::false_)
|
||||
{
|
||||
python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
|
||||
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
// explicit qualification of type_id makes msvc6 happy
|
||||
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
|
||||
#endif
|
||||
|
||||
@@ -12,13 +12,7 @@
|
||||
# include <boost/ref.hpp>
|
||||
# include <boost/python/detail/value_arg.hpp>
|
||||
# include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
# include <boost/type_traits/is_enum.hpp>
|
||||
# include <boost/mpl/and.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
# else
|
||||
# include <boost/mpl/or.hpp>
|
||||
# endif
|
||||
# include <boost/mpl/or.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
@@ -42,24 +36,13 @@ struct reference_to_value
|
||||
template <class T>
|
||||
struct forward
|
||||
: mpl::if_<
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
// vc6 chokes on unforwarding enums nested in classes
|
||||
mpl::and_<
|
||||
is_scalar<T>
|
||||
, mpl::not_<
|
||||
is_enum<T>
|
||||
>
|
||||
>
|
||||
# else
|
||||
mpl::or_<python::detail::copy_ctor_mutates_rhs<T>, is_scalar<T> >
|
||||
# endif
|
||||
, T
|
||||
, reference_to_value<T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
struct unforward
|
||||
{
|
||||
@@ -86,88 +69,6 @@ struct unforward_cref<reference_to_value<T> >
|
||||
{
|
||||
};
|
||||
|
||||
# else // no partial specialization
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_reference_to_value_t)[1];
|
||||
typedef char (&no_reference_to_value_t)[2];
|
||||
|
||||
no_reference_to_value_t is_reference_to_value_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_reference_to_value_t is_reference_to_value_test(boost::type< reference_to_value<T> >);
|
||||
|
||||
template<bool wrapped>
|
||||
struct unforwarder
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename unwrap_reference<T>::type& type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct unforwarder<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::reference type;
|
||||
};
|
||||
};
|
||||
|
||||
template<bool wrapped = false>
|
||||
struct cref_unforwarder
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
: python::detail::value_arg<
|
||||
typename unwrap_reference<T>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cref_unforwarder<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
: python::detail::value_arg<
|
||||
typename T::reference
|
||||
>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_reference_to_value
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(is_reference_to_value_test(boost::type<T>()))
|
||||
== sizeof(yes_reference_to_value_t)));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct unforward
|
||||
: public detail::unforwarder<
|
||||
detail::is_reference_to_value<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct unforward_cref
|
||||
: public detail::cref_unforwarder<
|
||||
detail::is_reference_to_value<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
typename reference_to_value<T>::reference
|
||||
|
||||
@@ -39,6 +39,8 @@ struct BOOST_PYTHON_DECL function : PyObject
|
||||
void doc(object const& x);
|
||||
|
||||
object const& name() const;
|
||||
|
||||
object const& get_namespace() const { return m_namespace; }
|
||||
|
||||
private: // helper functions
|
||||
object signature(bool show_return_type=false) const;
|
||||
|
||||
@@ -71,35 +71,7 @@ struct iterator_range
|
||||
# endif
|
||||
};
|
||||
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// for compilers which can't deduce the value_type of pointers, we
|
||||
// have a special implementation of next. This takes advantage of
|
||||
// the fact that T* results are treated like T& results by
|
||||
// Boost.Python's function wrappers.
|
||||
struct next_ptr
|
||||
{
|
||||
typedef Iterator result_type;
|
||||
|
||||
result_type
|
||||
operator()(iterator_range<NextPolicies,Iterator>& self)
|
||||
{
|
||||
if (self.m_start == self.m_finish)
|
||||
stop_iteration_error();
|
||||
return self.m_start++;
|
||||
}
|
||||
};
|
||||
|
||||
typedef mpl::if_<
|
||||
is_same<
|
||||
boost::detail::please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<Iterator>
|
||||
, typename traits_t::value_type
|
||||
>
|
||||
, next_ptr
|
||||
, next
|
||||
>::type next_fn;
|
||||
# else
|
||||
typedef next next_fn;
|
||||
# endif
|
||||
|
||||
object m_sequence; // Keeps the sequence alive while iterating.
|
||||
Iterator m_start;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
# include <boost/python/object/instance.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
|
||||
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
|
||||
# include <boost/python/detail/python_type.hpp>
|
||||
#endif
|
||||
|
||||
@@ -81,7 +81,7 @@ struct make_holder<N>
|
||||
# endif
|
||||
|
||||
static void execute(
|
||||
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
|
||||
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
|
||||
boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
|
||||
#else
|
||||
PyObject *p
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/python/detail/decref_guard.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/mpl/assert.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/type_traits/is_union.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
@@ -46,11 +46,7 @@ template <class T> class wrapper;
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
|
||||
# else
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
|
||||
# endif
|
||||
#define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
|
||||
|
||||
template <class Pointer, class Value>
|
||||
struct pointer_holder : instance_holder
|
||||
|
||||
@@ -33,11 +33,7 @@
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
|
||||
# else
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
|
||||
# endif
|
||||
#define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
|
||||
|
||||
template <class Value>
|
||||
struct value_holder : instance_holder
|
||||
|
||||
@@ -36,12 +36,6 @@
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
# include <boost/type_traits/add_pointer.hpp>
|
||||
# endif
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
@@ -98,11 +92,7 @@ namespace api
|
||||
class object_operators : public def_visitor<U>
|
||||
{
|
||||
protected:
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
|
||||
typedef object const& object_cref;
|
||||
# else
|
||||
typedef object object_cref;
|
||||
# endif
|
||||
public:
|
||||
// function call
|
||||
//
|
||||
@@ -139,25 +129,11 @@ namespace api
|
||||
|
||||
template <class T>
|
||||
const_object_item
|
||||
operator[](T const& key) const
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
;
|
||||
# else
|
||||
{
|
||||
return (*this)[object(key)];
|
||||
}
|
||||
# endif
|
||||
operator[](T const& key) const;
|
||||
|
||||
template <class T>
|
||||
object_item
|
||||
operator[](T const& key)
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
;
|
||||
# else
|
||||
{
|
||||
return (*this)[object(key)];
|
||||
}
|
||||
# endif
|
||||
operator[](T const& key);
|
||||
|
||||
// slicing
|
||||
//
|
||||
@@ -175,29 +151,11 @@ namespace api
|
||||
|
||||
template <class T, class V>
|
||||
const_object_slice
|
||||
slice(T const& start, V const& end) const
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
;
|
||||
# else
|
||||
{
|
||||
return this->slice(
|
||||
slice_bound<T>::type(start)
|
||||
, slice_bound<V>::type(end));
|
||||
}
|
||||
# endif
|
||||
slice(T const& start, V const& end) const;
|
||||
|
||||
template <class T, class V>
|
||||
object_slice
|
||||
slice(T const& start, V const& end)
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
;
|
||||
# else
|
||||
{
|
||||
return this->slice(
|
||||
slice_bound<T>::type(start)
|
||||
, slice_bound<V>::type(end));
|
||||
}
|
||||
# endif
|
||||
slice(T const& start, V const& end);
|
||||
|
||||
private: // def visitation for adding callable objects as class methods
|
||||
|
||||
@@ -248,26 +206,6 @@ namespace api
|
||||
PyObject* m_ptr;
|
||||
};
|
||||
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T, class U>
|
||||
struct is_derived_impl
|
||||
{
|
||||
static T x;
|
||||
template <class X>
|
||||
static X* to_pointer(X const&);
|
||||
|
||||
static char test(U const*);
|
||||
typedef char (&no)[2];
|
||||
static no test(...);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(to_pointer(x))) == 1);
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct is_derived
|
||||
: mpl::bool_<is_derived_impl<T,U>::value>
|
||||
{};
|
||||
# else
|
||||
template <class T, class U>
|
||||
struct is_derived
|
||||
: is_convertible<
|
||||
@@ -275,28 +213,13 @@ namespace api
|
||||
, U const*
|
||||
>
|
||||
{};
|
||||
# endif
|
||||
|
||||
template <class T>
|
||||
typename objects::unforward_cref<T>::type do_unforward_cref(T const& x)
|
||||
{
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
typedef typename objects::unforward_cref<T>::type ret;
|
||||
return ret(x);
|
||||
# else
|
||||
return x;
|
||||
# endif
|
||||
}
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
// GCC 2.x has non-const string literals; this hacks around that problem.
|
||||
template <unsigned N>
|
||||
char const (& do_unforward_cref(char const(&x)[N]) )[N]
|
||||
{
|
||||
return x;
|
||||
}
|
||||
# endif
|
||||
|
||||
class object;
|
||||
|
||||
template <class T>
|
||||
@@ -323,14 +246,7 @@ namespace api
|
||||
|
||||
// explicit conversion from any C++ object to Python
|
||||
template <class T>
|
||||
explicit object(
|
||||
T const& x
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
// use some SFINAE to un-confuse MSVC about its
|
||||
// copy-initialization ambiguity claim.
|
||||
, typename mpl::if_<is_proxy<T>,int&,int>::type* = 0
|
||||
# endif
|
||||
)
|
||||
explicit object(T const& x)
|
||||
: object_base(object_base_initializer(x))
|
||||
{
|
||||
}
|
||||
@@ -348,31 +264,14 @@ namespace api
|
||||
// Macros for forwarding constructors in classes derived from
|
||||
// object. Derived classes will usually want these as an
|
||||
// implementation detail
|
||||
# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
|
||||
inline explicit derived(python::detail::borrowed_reference p) \
|
||||
: base(p) {} \
|
||||
inline explicit derived(python::detail::new_reference p) \
|
||||
: base(p) {} \
|
||||
inline explicit derived(python::detail::new_non_null_reference p) \
|
||||
# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \
|
||||
inline explicit derived(::boost::python::detail::borrowed_reference p) \
|
||||
: base(p) {} \
|
||||
inline explicit derived(::boost::python::detail::new_reference p) \
|
||||
: base(p) {} \
|
||||
inline explicit derived(::boost::python::detail::new_non_null_reference p) \
|
||||
: base(p) {}
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
|
||||
# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_
|
||||
# else
|
||||
// MSVC6 has a bug which causes an explicit template constructor to
|
||||
// be preferred over an appropriate implicit conversion operator
|
||||
// declared on the argument type. Normally, that would cause a
|
||||
// runtime failure when using extract<T> to extract a type with a
|
||||
// templated constructor. This additional constructor will turn that
|
||||
// runtime failure into an ambiguity error at compile-time due to
|
||||
// the lack of partial ordering, or at least a link-time error if no
|
||||
// generalized template constructor is declared.
|
||||
# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \
|
||||
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
|
||||
template <class T> \
|
||||
explicit derived(extract<T> const&);
|
||||
# endif
|
||||
|
||||
//
|
||||
// object_initializer -- get the handle to construct the object with,
|
||||
// based on whether T is a proxy or derived from object
|
||||
|
||||
3
include/boost/python/object_items.hpp
Executable file → Normal file
3
include/boost/python/object_items.hpp
Executable file → Normal file
@@ -44,7 +44,6 @@ object_operators<U>::operator[](object_cref key) const
|
||||
return const_object_item(x, key);
|
||||
}
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
template <class U>
|
||||
template <class T>
|
||||
inline const_object_item
|
||||
@@ -60,8 +59,6 @@ object_operators<U>::operator[](T const& key)
|
||||
{
|
||||
return (*this)[object(key)];
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
inline object const_item_policies::get(object const& target, object const& key)
|
||||
{
|
||||
|
||||
0
include/boost/python/object_protocol.hpp
Executable file → Normal file
0
include/boost/python/object_protocol.hpp
Executable file → Normal file
@@ -99,7 +99,7 @@ object_operators<U>::slice(object_cref start, slice_nil) const
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
|
||||
}
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
|
||||
template <class U>
|
||||
template <class T, class V>
|
||||
inline const_object_slice
|
||||
@@ -119,8 +119,6 @@ object_operators<U>::slice(T const& start, V const& end)
|
||||
typename slice_bound<T>::type(start)
|
||||
, typename slice_bound<V>::type(end));
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
inline object const_slice_policies::get(object const& target, key_type const& key)
|
||||
{
|
||||
|
||||
@@ -172,28 +172,19 @@ PyTypeObject opaque<Pointee>::type_object =
|
||||
};
|
||||
}} // namespace boost::python
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
|
||||
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)
|
||||
|
||||
# else
|
||||
|
||||
// If you change the below, don't forget to alter the end of type_id.hpp
|
||||
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
|
||||
namespace boost { namespace python { \
|
||||
template<> \
|
||||
inline type_info type_id<Pointee>(BOOST_PYTHON_EXPLICIT_TT_DEF(Pointee)) \
|
||||
inline type_info type_id<Pointee>() \
|
||||
{ \
|
||||
return type_info (typeid (Pointee *)); \
|
||||
} \
|
||||
template<> \
|
||||
inline type_info type_id<const volatile Pointee&>( \
|
||||
BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile Pointee&)) \
|
||||
inline type_info type_id<const volatile Pointee&>() \
|
||||
{ \
|
||||
return type_info (typeid (Pointee *)); \
|
||||
} \
|
||||
}}
|
||||
|
||||
# endif
|
||||
|
||||
# endif // OPAQUE_POINTER_CONVERTER_HPP_
|
||||
|
||||
@@ -212,7 +212,11 @@ namespace self_ns \
|
||||
BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
BOOST_PYTHON_BINARY_OPERATOR(truediv, rtruediv, /)
|
||||
#else
|
||||
BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
|
||||
#endif
|
||||
BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)
|
||||
|
||||
62
include/boost/python/other.hpp
Executable file → Normal file
62
include/boost/python/other.hpp
Executable file → Normal file
@@ -7,9 +7,7 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# if _MSC_VER+0 >= 1020
|
||||
# pragma once
|
||||
# endif
|
||||
# pragma once
|
||||
|
||||
# include <boost/config.hpp>
|
||||
|
||||
@@ -20,7 +18,6 @@ template<class T> struct other
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
@@ -51,63 +48,6 @@ namespace detail
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
# else // no partial specialization
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_other_t)[1];
|
||||
typedef char (&no_other_t)[2];
|
||||
|
||||
no_other_t is_other_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_other_t is_other_test(type< other<T> >);
|
||||
|
||||
template<bool wrapped>
|
||||
struct other_unwrapper
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct other_unwrapper<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_other
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_other_test(type<T>()))
|
||||
== sizeof(detail::yes_other_t)));
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class unwrap_other
|
||||
: public detail::other_unwrapper<
|
||||
is_other<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
}
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
|
||||
2
include/boost/python/override.hpp
Executable file → Normal file
2
include/boost/python/override.hpp
Executable file → Normal file
@@ -77,7 +77,7 @@ namespace detail
|
||||
template <class T>
|
||||
T unchecked(type<T>* = 0)
|
||||
{
|
||||
return extract<T>(m_obj)();
|
||||
return extract<T>(m_obj.get())();
|
||||
}
|
||||
private:
|
||||
mutable handle<> m_obj;
|
||||
|
||||
4
include/boost/python/proxy.hpp
Executable file → Normal file
4
include/boost/python/proxy.hpp
Executable file → Normal file
@@ -15,11 +15,7 @@ class proxy : public object_operators<proxy<Policies> >
|
||||
{
|
||||
typedef typename Policies::key_type key_type;
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
|
||||
typedef proxy const& assignment_self;
|
||||
# else
|
||||
typedef proxy assignment_self;
|
||||
# endif
|
||||
public:
|
||||
proxy(object const& target, key_type const& key);
|
||||
operator object() const;
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2001 Peter Dimov
|
||||
|
||||
# if _MSC_VER+0 >= 1020
|
||||
# pragma once
|
||||
# endif
|
||||
# pragma once
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
@@ -38,7 +36,6 @@ inline pointer_wrapper<T> ptr(T t)
|
||||
return pointer_wrapper<T>(t);
|
||||
}
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
class is_pointer_wrapper
|
||||
: public mpl::false_
|
||||
@@ -64,64 +61,6 @@ class unwrap_pointer<pointer_wrapper<T> >
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
# else // no partial specialization
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_pointer_wrapper_t)[1];
|
||||
typedef char (&no_pointer_wrapper_t)[2];
|
||||
|
||||
no_pointer_wrapper_t is_pointer_wrapper_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_pointer_wrapper_t is_pointer_wrapper_test(boost::type< pointer_wrapper<T> >);
|
||||
|
||||
template<bool wrapped>
|
||||
struct pointer_unwrapper
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct pointer_unwrapper<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class is_pointer_wrapper
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_pointer_wrapper_test(boost::type<T>()))
|
||||
== sizeof(detail::yes_pointer_wrapper_t)));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class unwrap_pointer
|
||||
: public detail::pointer_unwrapper<
|
||||
is_pointer_wrapper<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
|
||||
2
include/boost/python/pure_virtual.hpp
Executable file → Normal file
2
include/boost/python/pure_virtual.hpp
Executable file → Normal file
@@ -47,7 +47,7 @@ namespace detail
|
||||
// replaced by void, and whose first argument is replaced by C&.
|
||||
template <class C, class S>
|
||||
typename replace_front2<S,void,C&>::type
|
||||
error_signature(S BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(C))
|
||||
error_signature(S)
|
||||
{
|
||||
typedef typename replace_front2<S,void,C&>::type r;
|
||||
return r();
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct reference_existing_object_requires_a_pointer_or_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
# if defined(__GNUC__) || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class P>
|
||||
void register_ptr_to_python(BOOST_EXPLICIT_TEMPLATE_TYPE(P))
|
||||
void register_ptr_to_python()
|
||||
{
|
||||
typedef typename boost::python::pointee<P>::type X;
|
||||
objects::class_value_wrapper<
|
||||
|
||||
2
include/boost/python/return_arg.hpp
Executable file → Normal file
2
include/boost/python/return_arg.hpp
Executable file → Normal file
@@ -29,7 +29,7 @@ namespace detail
|
||||
{
|
||||
template <std::size_t>
|
||||
struct return_arg_pos_argument_must_be_positive
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
# if defined(__GNUC__) || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace detail
|
||||
{
|
||||
template <std::size_t>
|
||||
struct return_internal_reference_owner_arg_must_be_greater_than_zero
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
# if defined(__GNUC__) || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/refcount.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace detail
|
||||
// that created this slice, than that parameter is None here, and compares
|
||||
// equal to a default-constructed boost::python::object.
|
||||
// If a user-defined type wishes to support slicing, then support for the
|
||||
// special meaning associated with negative indicies is up to the user.
|
||||
// special meaning associated with negative indices is up to the user.
|
||||
object start() const;
|
||||
object stop() const;
|
||||
object step() const;
|
||||
@@ -63,7 +63,7 @@ class slice : public detail::slice_base
|
||||
|
||||
// The following algorithm is intended to automate the process of
|
||||
// determining a slice range when you want to fully support negative
|
||||
// indicies and non-singular step sizes. Its functionallity is simmilar to
|
||||
// indices and non-singular step sizes. Its functionallity is simmilar to
|
||||
// PySlice_GetIndicesEx() in the Python/C API, but tailored for C++ users.
|
||||
// This template returns a slice::range struct that, when used in the
|
||||
// following iterative loop, will traverse a slice of the function's
|
||||
@@ -110,7 +110,7 @@ class slice : public detail::slice_base
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
slice::range<RandomAccessIterator>
|
||||
get_indicies( const RandomAccessIterator& begin,
|
||||
get_indices( const RandomAccessIterator& begin,
|
||||
const RandomAccessIterator& end) const
|
||||
{
|
||||
// This is based loosely on PySlice_GetIndicesEx(), but it has been
|
||||
@@ -240,6 +240,16 @@ class slice : public detail::slice_base
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Incorrect spelling. DO NOT USE. Only here for backward compatibility.
|
||||
// Corrected 2011-06-14.
|
||||
template<typename RandomAccessIterator>
|
||||
slice::range<RandomAccessIterator>
|
||||
get_indicies( const RandomAccessIterator& begin,
|
||||
const RandomAccessIterator& end) const
|
||||
{
|
||||
return get_indices(begin, end);
|
||||
}
|
||||
|
||||
public:
|
||||
// This declaration, in conjunction with the specialization of
|
||||
|
||||
@@ -131,11 +131,7 @@ namespace boost { namespace python {
|
||||
typedef detail::container_element<Container, Index, DerivedPolicies>
|
||||
container_element_t;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
struct return_policy : return_internal_reference<> {};
|
||||
#else
|
||||
typedef return_internal_reference<> return_policy;
|
||||
#endif
|
||||
|
||||
typedef typename mpl::if_<
|
||||
no_proxy
|
||||
|
||||
@@ -48,12 +48,7 @@ template < class T, class Conversion, bool has_get_pytype=false >
|
||||
struct to_python_converter
|
||||
{
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
#if 0 //defined _MSC_VER && _MSC_VER >=1310
|
||||
//probably other compilers could come here as well
|
||||
typedef typename detail::test_get_pytype<Conversion> HasGetPytype;
|
||||
#else
|
||||
typedef boost::mpl::bool_<has_get_pytype> HasGetPytype;
|
||||
#endif
|
||||
|
||||
static PyTypeObject const* get_pytype_1(boost::mpl::true_ *)
|
||||
{
|
||||
|
||||
@@ -147,11 +147,6 @@ namespace detail
|
||||
template <class T>
|
||||
inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
|
||||
{
|
||||
typedef converter::registered<argument_type> r;
|
||||
# if BOOST_WORKAROUND(__GNUC__, < 3)
|
||||
// suppresses an ICE, somehow
|
||||
(void)r::converters;
|
||||
# endif
|
||||
return converter::registered<argument_type>::converters.to_python(&x);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
|
||||
# ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
||||
# if defined(__GNUC__) \
|
||||
&& ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) \
|
||||
&& !defined(__EDG_VERSION__)
|
||||
# define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
||||
# endif
|
||||
@@ -30,7 +28,7 @@ namespace boost { namespace python {
|
||||
// for this compiler at least, cross-shared-library type_info
|
||||
// comparisons don't work, so use typeid(x).name() instead. It's not
|
||||
// yet clear what the best default strategy is.
|
||||
# if (defined(__GNUC__) && __GNUC__ >= 3) \
|
||||
# if defined(__GNUC__) \
|
||||
|| defined(_AIX) \
|
||||
|| ( defined(__sgi) && defined(__host_mips)) \
|
||||
|| (defined(__hpux) && defined(__HP_aCC)) \
|
||||
@@ -69,21 +67,18 @@ struct type_info : private totally_ordered<type_info>
|
||||
base_id_t m_base_type;
|
||||
};
|
||||
|
||||
# ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
|
||||
# define BOOST_PYTHON_EXPLICIT_TT_DEF(T) ::boost::type<T>*
|
||||
# else
|
||||
# define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
|
||||
# endif
|
||||
|
||||
// This macro is obsolete. Port away and remove.
|
||||
# define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
|
||||
|
||||
template <class T>
|
||||
inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T))
|
||||
inline type_info type_id()
|
||||
{
|
||||
return type_info(
|
||||
# if !defined(_MSC_VER) \
|
||||
|| (!BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
&& !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700))
|
||||
|| !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700)
|
||||
typeid(T)
|
||||
# else // strip the decoration which msvc and Intel mistakenly leave in
|
||||
# else // strip the decoration which Intel mistakenly leaves in
|
||||
python::detail::msvc_typeid((boost::type<T>*)0)
|
||||
# endif
|
||||
);
|
||||
@@ -99,7 +94,7 @@ inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T))
|
||||
|
||||
# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \
|
||||
template <> \
|
||||
inline type_info type_id<T>(BOOST_PYTHON_EXPLICIT_TT_DEF(T)) \
|
||||
inline type_info type_id<T>() \
|
||||
{ \
|
||||
return type_info(typeid(T)); \
|
||||
}
|
||||
@@ -171,22 +166,19 @@ inline char const* type_info::name() const
|
||||
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&);
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template<>
|
||||
inline type_info type_id<void>(BOOST_PYTHON_EXPLICIT_TT_DEF(void))
|
||||
inline type_info type_id<void>()
|
||||
{
|
||||
return type_info (typeid (void *));
|
||||
}
|
||||
# ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template<>
|
||||
inline type_info type_id<const volatile void>(BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile void))
|
||||
inline type_info type_id<const volatile void>()
|
||||
{
|
||||
return type_info (typeid (void *));
|
||||
}
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // TYPE_ID_DWA2002517_HPP
|
||||
|
||||
@@ -85,14 +85,10 @@ struct with_custodian_and_ward_postcall : BasePolicy_
|
||||
static PyObject* postcall(ArgumentPackage const& args_, PyObject* result)
|
||||
{
|
||||
std::size_t arity_ = detail::arity(args_);
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
if ( custodian > arity_ || ward > arity_ )
|
||||
#else
|
||||
// check if either custodian or ward exceeds the arity
|
||||
// (this weird formulation avoids "always false" warnings
|
||||
// for arity_ = 0)
|
||||
if ( (std::max)(custodian, ward) > arity_ )
|
||||
#endif
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_IndexError
|
||||
|
||||
15
meta/libraries.json
Normal file
15
meta/libraries.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"key": "python",
|
||||
"name": "Python",
|
||||
"authors": [
|
||||
"Dave Abrahams"
|
||||
],
|
||||
"description": "The Boost Python Library is a framework for interfacing Python and C++. It allows you to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa, using no special tools -- just your C++ compiler.",
|
||||
"category": [
|
||||
"Inter-language"
|
||||
],
|
||||
"maintainers": [
|
||||
"Ralf Grosse-Kunstleve <rwgrosse-kunstleve -at- lbl.gov>",
|
||||
"Ravi Rajagopal <lists_ravi -at- lavabit.com>"
|
||||
]
|
||||
}
|
||||
@@ -4,12 +4,16 @@
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from declarations import *
|
||||
# try to use cElementTree if avaiable
|
||||
try:
|
||||
from cElementTree import ElementTree
|
||||
# try to use internal elementtree
|
||||
from xml.etree.cElementTree import ElementTree
|
||||
except ImportError:
|
||||
# fall back to the normal elementtree
|
||||
from elementtree.ElementTree import ElementTree
|
||||
# try to use cElementTree if avaiable
|
||||
try:
|
||||
from cElementTree import ElementTree
|
||||
except ImportError:
|
||||
# fall back to the normal elementtree
|
||||
from elementtree.ElementTree import ElementTree
|
||||
from xml.parsers.expat import ExpatError
|
||||
from copy import deepcopy
|
||||
from utils import enumerate
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user