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

Compare commits

...

2 Commits

Author SHA1 Message Date
Bruno da Silva de Oliveira
85e7824565 - added link to Pyste documentation
[SVN r17829]
2003-03-12 04:11:08 +00:00
nobody
748e1cda16 This commit was manufactured by cvs2svn to create branch
'unlabeled-1.23.2'.

[SVN r16300]
2002-11-17 05:59:13 +00:00
424 changed files with 2 additions and 47825 deletions

Binary file not shown.

View File

@@ -1,66 +0,0 @@
# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears
# in all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
#
# Boost.Python library Jamfile
# declare the location of this subproject relative to the root
subproject libs/python/build ;
# bring in the rules for python
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
if [ check-python-config ]
{
local bpl-linkflags ;
if $(UNIX) && ( $(OS) = AIX )
{
bpl-linkflags = <linkflags>"-e initlibboost_python" ;
}
dll boost_python
:
../src/numeric.cpp
../src/list.cpp
../src/long.cpp
../src/dict.cpp
../src/tuple.cpp
../src/str.cpp
../src/aix_init_module.cpp
../src/converter/from_python.cpp
../src/converter/registry.cpp
../src/converter/type_id.cpp
../src/object/enum.cpp
../src/object/class.cpp
../src/object/function.cpp
../src/object/inheritance.cpp
../src/object/life_support.cpp
../src/object/pickle_support.cpp
../src/errors.cpp
../src/module.cpp
../src/converter/builtin_converters.cpp
../src/converter/arg_to_python_base.cpp
../src/object/iterator.cpp
../src/object_protocol.cpp
../src/object_operators.cpp
:
$(BOOST_PYTHON_V2_PROPERTIES)
<define>BOOST_PYTHON_SOURCE
$(bpl-linkflags)
;
stage bin-stage : <dll>boost_python
:
<tag><debug>"_debug"
<tag><debug-python>"_pydebug"
:
debug release
;
}

View File

@@ -1,77 +0,0 @@
import os ;
# Use a very crude way to sense there python is locatted
local PYTHON_PATH ;
if [ GLOB /usr/local/include/python2.2 : * ]
{
PYTHON_PATH = /usr/local ;
}
else if [ GLOB /usr/include/python2.2 : * ]
{
PYTHON_PATH = /usr ;
}
PYTHON_LIB = python2.2 ;
if [ os.name ] in CYGWIN NT
{
lib_condition = <shared>true: ;
defines = USE_DL_IMPORT ;
PYTHON_LIB = python2.2.dll ;
}
if $(PYTHON_PATH) {
project boost/python
: source-location ../src
: requirements <include>$(PYTHON_PATH)/include/python2.2
$(lib_condition)<library-path>$(PYTHON_PATH)/lib/python2.2/config
<shared>true:<find-library>$(PYTHON_LIB)
<define>$(defines)
: use-requirements # requirement that will be propageted to *users* of this library
<include>$(PYTHON_PATH)/include/python2.2
# We have a bug which causes us to conclude that conditionalized
# properties in this section are not free.
# $(lib_condition)<library-path>$(PYTHON_PATH)/lib/python2.2/config
# <shared>true:<find-library>$(PYTHON_LIB)
<library-path>$(PYTHON_PATH)/lib/python2.2/config
<find-library>$(PYTHON_LIB)
;
lib boost_python
:
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
aix_init_module.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object_protocol.cpp
object_operators.cpp
: <shared>false:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
: <shared>true
;
}

Binary file not shown.

View File

@@ -1,59 +0,0 @@
H1
{
FONT-SIZE: 200%
COLOR: #00007f
}
H2
{
FONT-SIZE: 150%;
}
H3
{
FONT-SIZE: 125%;
}
H4
{
FONT-SIZE: 108%;
}
BODY
{
FONT-SIZE: 100%;
BACKGROUND-COLOR: #ffffff
}
PRE
{
MARGIN-LEFT: 2pc;
FONT-SIZE: 80%;
BACKGROUND-COLOR: #dfffff
}
CODE
{
FONT-SIZE: 95%;
white-space: pre
}
.index
{
TEXT-ALIGN: left
}
.page-index
{
TEXT-ALIGN: left
}
.definition
{
TEXT-ALIGN: left
}
.footnote
{
FONT-SIZE: 66%;
VERTICAL-ALIGN: super;
TEXT-DECORATION: none
}
.function-semantics
{
CLEAR: left
}
.metafunction-semantics
{
CLEAR: left
}

View File

@@ -1,302 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - Building and Testing</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Building and Testing</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="Reference">
<dt><a href="#requirements">Requirements</a></dt>
<dt><a href="#building">Building Boost.Python</a></dt>
<dd>
<dl class="index">
<dt><a href="#configuration">Configuration</a></dt>
<dt><a href="#results">Results</a></dt>
<dt><a href="#testing">Testing</a></dt>
</dl>
</dd>
<dt><a href="#building_ext">Building your Extension Module</a></dt>
<dt><a href="#variants">Build Variants</a></dt>
</dl>
<hr>
<h2><a name="requirements">Requirements</a></h2>
<b>Boost.Python</b> version 2 requires <a href=
"http://www.python.org/2.2">Python 2.2</a> <i>or <a href=
"http://www.python.org">newer</a></i>. An unsupported archive of
Boost.Python version 1, which works with versions of Python since 1.5.2,
is available <a href="../build/python_v1.zip">here</a>.
<h2><a name="building">Building Boost.Python</a></h2>
<p>Every Boost.Python extension module must be linked with the
<code>boost_python</code> shared library. To build
<code>boost_python</code>, use <a href=
"../../../tools/build/index.html">Boost.Build</a> in the usual way from
the <code>libs/python/build</code> subdirectory of your boost
installation (if you have already built boost from the top level this may
have no effect, since the work is already done).</p>
<h3><a name="configuration">Configuration</a></h3>
You may need to configure the following variables to point Boost.Build at
your Python installation:
<table border="1" summary="build configuration variables">
<tr>
<th>Variable Name</th>
<th>Semantics</th>
<th>Default</th>
<th>Notes</th>
</tr>
<tr>
<td><code>PYTHON_ROOT</code></td>
<td>The root directory of your Python installation</td>
<td>Windows:&nbsp;<code>c:/tools/python</code>
Unix:&nbsp;<code>/usr/local</code></td>
<td>On Unix, this is the <code>--with-prefix=</code> directory used
to configure Python</td>
</tr>
<tr>
<td><code>PYTHON_VERSION</code></td>
<td>The The 2-part python Major.Minor version number</td>
<td><code>2.2</code></td>
<td>Be sure not to include a third number, e.g. <b>not</b>
"<code>2.2.1</code>", even if that's the version you have.</td>
</tr>
<tr>
<td><code>PYTHON_INCLUDES</code></td>
<td>path to Python <code>#include</code> directories</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>PYTHON_LIB_PATH</code></td>
<td>path to Python library object.</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>PYTHON_STDLIB_PATH</code></td>
<td>path to Python standard library modules</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>CYGWIN_ROOT</code></td>
<td>path to the user's Cygwin installation</td>
<td>
</td>
<td>Use only when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC from a regular Win32 build of
bjam. This and the following two settings are useful when building
with multiple toolsets on Windows, since Cygwin GCC requires a
different build of Python.</td>
</tr>
<tr>
<td><code>GCC_PYTHON_ROOT</code></td>
<td>path to the user's Cygwin Python installation</td>
<td><code>$(CYGWIN_ROOT)/usr/local</code></td>
<td>Use only when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC from a regular Win32 build of
bjam.</td>
</tr>
<tr>
<td><code>GCC_DEBUG_PYTHON_ROOT</code></td>
<td>path to the user's Cygwin <code><a href=
"#variants">pydebug</a></code> build</td>
<td><code>$(CYGWIN_ROOT)/usr/local/pydebug</code></td>
<td>Use only when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC from a regular Win32 build of
bjam.</td>
</tr>
</table>
<h3><a name="results">Results</a></h3>
<p>The build process will create a
<code>libs/python/build/bin-stage</code> subdirectory of the boost root
(or of <code>$(ALL_LOCATE_TARGET)</code>, if you have set that variable),
containing the built libraries. The libraries are actually built to
unique directories for each toolset and variant elsewhere in the
filesystem, and copied to the <code>bin-stage</code> directory as a
convenience, so if you build with multiple toolsets at once, the product
of later toolsets will overwrite that of earlier toolsets in
<code>bin-stage</code>.</p>
<h3><a name="testing">Testing</a></h3>
<p>To build and test Boost.Python, start from the
<code>libs/python/test</code> directory and invoke</p>
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> test
</pre>
</blockquote>
This will update all of the Boost.Python v1 test and example targets. The
tests are relatively quiet by default. To get more-verbose output, you
might try
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
</pre>
</blockquote>
which will print each test's Python code with the expected output as it
passes.
<h2><a name="building_ext">Building your Extension Module</a></h2>
Though there are other approaches, the easiest way to build an extension
module using Boost.Python is with Boost.Build. Until Boost.Build v2 is
released, cross-project build dependencies are not supported, so it works
most smoothly if you add a new subproject to your boost installation. The
<code>libs/python/example</code> subdirectory of your boost installation
contains a minimal example (along with many extra sources). To copy the
example subproject:
<ol>
<li>Create a new subdirectory in, <code>libs/python</code>, say
<code>libs/python/my_project</code>.</li>
<li>Copy <code><a href=
"../example/Jamfile">libs/python/example/Jamfile</a></code> to your new
directory.</li>
<li>Edit the Jamfile as appropriate for your project. You'll want to
change the "<code>subproject</code>" rule invocation at the top, and
the names of some of the source files and/or targets.</li>
</ol>
If you can't modify or copy your boost installation, the alternative is
to create your own Boost.Build project. A similar example you can use as
a starting point is available in <code><a href=
"../example/project.zip">this archive</a></code>. You'll need to edit the
Jamfile and Jamrules files, depending on the relative location of your
Boost installation and the new project. Note that automatic testing of
extension modules is not available in this configuration.
<h2><a name="variants">Build Variants</a></h2>
Three <a href=
"../../../tools/build/build_system.htm#variants">variant</a>
configurations of all python-related targets are supported, and can be
selected by setting the <code><a href=
"../../../tools/build/build_system.htm#user_globals">BUILD</a></code>
variable:
<ul>
<li><code>release</code> (optimization, <tt>-DNDEBUG</tt>)</li>
<li><code>debug</code> (no optimization <tt>-D_DEBUG</tt>)</li>
<li><code>debug-python</code> (no optimization, <tt>-D_DEBUG
-DBOOST_DEBUG_PYTHON</tt>)</li>
</ul>
<p>The first two variants of the <code>boost_python</code> library are
built by default, and are compatible with the default Python
distribution. The <code>debug-python</code> variant corresponds to a
specially-built debugging version of Python. On Unix platforms, this
python is built by adding <code>--with-pydebug</code> when configuring
the Python build. On Windows, the debugging version of Python is
generated by the "Win32 Debug" target of the <code>PCBuild.dsw</code>
Visual C++ 6.0 project in the <code>PCBuild</code> subdirectory of your
Python distribution. Extension modules built with Python debugging
enabled are <b>not link-compatible</b> with a non-debug build of Python.
Since few people actually have a debug build of Python (it doesn't come
with the standard distribution), the normal <code>debug</code> variant
builds modules which are compatible with ordinary Python.</p>
<p>On many windows compilers, when extension modules are built with
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> linking with a special
debugging version of the Python DLL. Since this debug DLL isn't supplied
with the default Python installation for Windows, Boost.Python uses
<tt><a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
<tt>#include</tt>d - unless <code>BOOST_DEBUG_PYTHON</code> is
defined.</p>
<p>If you want the extra runtime checks available with the debugging
version of the library, <tt>#define BOOST_DEBUG_PYTHON</tt> to re-enable
python debuggin, and link with the <code>debug-python</code> variant of
<tt>boost_python</tt>.</p>
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that any
source files in your extension module <tt>#include&nbsp;&lt;<a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>&gt;</tt>
instead of the usual <tt>Python.h</tt>, or you will have link
incompatibilities.<br>
</p>
<hr>
<p>&copy; Copyright David Abrahams 2002. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided ``as is'' without
express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
<p>Updated: O8 October, 2002 (David Abrahams)</p>
</body>
</html>

View File

@@ -84,6 +84,8 @@
<dt><a href="support.html">Support Resources</a></dt>
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="../pyste/index.html">Pyste (Boost.Python code generator)</a></dt>
<dt><a href="news.html">News/Change Log</a></dt>

View File

@@ -1,328 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>A New Type Conversion Mechanism for Boost.Python</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p><img border="0" src="../../../c++boost.gif" width="277" height="86"
alt="boost logo"></p>
<h1>A New Type Conversion Mechanism for Boost.Python</h1>
<p>By <a href="../../../people/dave_abrahams.htm">David Abrahams</a>.
<h2>Introduction</h2>
This document describes a redesign of the mechanism for automatically
converting objects between C++ and Python. The current implementation
uses two functions for any type <tt>T</tt>:
<blockquote><pre>
U from_python(PyObject*, type&lt;T&gt;);
void to_python(V);
</pre></blockquote>
where U is convertible to T and T is convertible to V. These functions
are at the heart of C++/Python interoperability in Boost.Python, so
why would we want to change them? There are many reasons:
<h3>Bugs</h3>
<p>Firstly, the current mechanism relies on a common C++ compiler
bug. This is not just embarrassing: as compilers get to be more
conformant, the library stops working. The issue, in detail, is the
use of inline friend functions in templates to generate
conversions. It is a very powerful, and legal technique as long as
it's used correctly:
<blockquote><pre>
template &lt;class Derived&gt;
struct add_some_functions
{
friend <i>return-type</i> some_function1(..., Derived <i>cv-*-&amp;-opt</i>, ...);
friend <i>return-type</i> some_function2(..., Derived <i>cv-*-&amp;-opt</i>, ...);
};
template &lt;class T&gt;
struct some_template : add_some_functions&lt;some_template&lt;T&gt; &gt;
{
};
</pre></blockquote>
The <tt>add_some_functions</tt> template generates free functions
which operate on <tt>Derived</tt>, or on related types. Strictly
speaking the related types are not just cv-qualified <tt>Derived</tt>
values, pointers and/or references. Section 3.4.2 in the standard
describes exactly which types you must use as parameters to these
functions if you want the functions to be found
(there is also a less-technical description in section 11.5.1 of
C++PL3 <a href="#ref_1">[1]</a>). Suffice it to say that
with the current design, the <tt>from_python</tt> and
<tt>to_python</tt> functions are not supposed to be callable under any
conditions!
<h3>Compilation and Linking Time</h3>
The conversion functions generated for each wrapped class using the
above technique are not function templates, but regular functions. The
upshot is that they must <i>all</i> be generated regardless of whether
they are actually used. Generating all of those functions can slow
down module compilation, and resolving the references can slow down
linking.
<h3>Efficiency</h3>
The conversion functions are primarily used in (member) function
wrappers to convert the arguments and return values. Being functions,
converters have no interface which allows us to ask &quot;will the
conversion succeed?&quot; without calling the function. Since the
return value of the function must be the object to be passed as an
argument, Boost.Python currently uses C++ exception-handling to detect
an unsuccessful conversion. It's not a particularly good use of
exception-handling, since the failure is not handled very far from
where it occurred. More importantly, it means that C++ exceptions are
thrown during overload resolution as we seek an overload that matches
the arguments passed. Depending on the implementation, this approach
can result in significant slowdowns.
<p>It is also unclear that the current library generates a minimal
amount of code for any type conversion. Many of the conversion
functions are nontrivial, and partly because of compiler limitations,
they are declared <tt>inline</tt>. Also, we could have done a better
job separating the type-specific conversion code from the code which
is type-independent.
<h3>Cross-module Support</h3>
The current strategy requires every module to contain the definition
of conversions it uses. In general, a new module can never supply
conversion code which is used by another module. Ralf Grosse-Kunstleve
designed a clever system which imports conversions directly from one
library into another using some explicit declarations, but it has some
disadvantages also:
<ol>
<li>The system Ullrich Koethe designed for implicit conversion between
wrapped classes related through inheritance does not currently work if
the classes are defined in separate modules.
<li>The writer of the importing module is required to know the name of
the module supplying the imported conversions.
<li>There can be only one way to extract any given C++ type from a
Python object in a given module.
</ol>
The first item might be addressed by moving Boost.Python into a shared
library, but the other two cannot. Ralf turned the limitation in item
two into a feature: the required module is loaded implicitly when a
conversion it defines is invoked. We will probably want to provide
that functionality anyway, but it's not clear that we should require
the declaration of all such conversions. The final item is a more
serious limitation. If, for example, new numeric types are defined in
separate modules, and these types can all be converted to
<tt>double</tt>s, we have to choose just one conversion method.
<h3>Ease-of-use</h3>
One persistent source of confusion for users of Boost.Python has been
the fact that conversions for a class are not be visible at
compile-time until the declaration of that class has been seen. When
the user tries to expose a (member) function operating on or returning
an instance of the class in question, compilation fails...even though
the user goes on to expose the class in the same translation unit!
<p>
The new system lifts all compile-time checks for the existence of
particular type conversions and replaces them with runtime checks, in
true Pythonic style. While this might seem cavalier, the compile-time
checks are actually not much use in the current system if many classes
are wrapped in separate modules, since the checks are based only on
the user's declaration that the conversions exist.
<h2>The New Design</h2>
<h3>Motivation</h3>
The new design was heavily influenced by a desire to generate as
little code as possible in extension modules. Some of Boost.Python's
clients are enormous projects where link time is proportional to the
amount of object code, and there are many Python extension modules. As
such, we try to keep type-specific conversion code out of modules
other than the one the converters are defined in, and rely as much as
possible on centralized control through a shared library.
<h3>The Basics</h3>
The library contains a <tt>registry</tt> which maps runtime type
identifiers (actually an extension of <tt>std::type_info</tt> which
preserves references and constness) to entries containing type
converters. An <tt>entry</tt> can contain only one converter from C++ to Python
(<tt>wrapper</tt>), but many converters from Python to C++
(<tt>unwrapper</tt>s). <font color="#ff0000">What should happen if
multiple modules try to register wrappers for the same type?</font>. Wrappers
and unwrappers are known as <tt>body</tt> objects, and are accessed
by the user and the library (in its function-wrapping code) through
corresponding <tt>handle</tt> (<tt>wrap&lt;T&gt;</tt> and
<tt>unwrap&lt;T&gt;</tt>) objects. The <tt>handle</tt> objects are
extremely lightweight, and delegate <i>all</i> of their operations to
the corresponding <tt>body</tt>.
<p>
When a <tt>handle</tt> object is constructed, it accesses the
registry to find a corresponding <tt>body</tt> that can convert the
handle's constructor argument. Actually the registry record for any
type
<tt>T</tt>used in a module is looked up only once and stored in a
static <tt>registration&lt;T&gt;</tt> object for efficiency. For
example, if the handle is an <tt>unwrap&lt;Foo&amp;&gt;</tt> object,
the <tt>entry</tt> for <tt>Foo&amp;</tt> is looked up in the
<tt>registry</tt>, and each <tt>unwrapper</tt> it contains is queried
to determine if it can convert the
<tt>PyObject*</tt> with which the <tt>unwrap</tt> was constructed. If
a body object which can perform the conversion is found, a pointer to
it is stored in the handle. A body object may at any point store
additional data in the handle to speed up the conversion process.
<p>
Now that the handle has been constructed, the user can ask it whether
the conversion can be performed. All handles can be tested as though
they were convertible to <tt>bool</tt>; a <tt>true</tt> value
indicates success. If the user forges ahead and tries to do the
conversion without checking when no conversion is possible, an
exception will be thrown as usual. The conversion itself is performed
by the body object.
<h3>Handling complex conversions</h3>
<p>Some conversions may require a dynamic allocation. For example,
when a Python tuple is converted to a <tt>std::vector&lt;double&gt;
const&amp;</tt>, we need some storage into which to construct the
vector so that a reference to it can be formed. Furthermore, multiple
conversions of the same type may need to be &quot;active&quot;
simultaneously, so we can't keep a single copy of the storage
anywhere. We could keep the storage in the <tt>body</tt> object, and
have the body clone itself in case the storage is used, but in that
case the storage in the body which lives in the registry is never
used. If the storage was actually an object of the target type (the
safest way in C++), we'd have to find a way to construct one for the
body in the registry, since it may not have a default constructor.
<p>
The most obvious way out of this quagmire is to allocate the object using a
<i>new-expression</i>, and store a pointer to it in the handle. Since
the <tt>body</tt> object knows everything about the data it needs to
allocate (if any), it is also given responsibility for destroying that
data. When the <tt>handle</tt> is destroyed it asks the <tt>body</tt>
object to tear down any data it may have stored there. In many ways,
you can think of the <tt>body</tt> as a &quot;dynamically-determined
vtable&quot; for the handle.
<h3>Eliminating Redundancy</h3>
If you look at the current Boost.Python code, you'll see that there
are an enormous number of conversion functions generated for each
wrapped class. For a given class <tt>T</tt>, functions are generated
to extract the following types <tt>from_python</tt>:
<blockquote><pre>
T*
T const*
T const* const&amp;
T* const&amp;
T&amp;
T const&amp;
T
std::auto_ptr&lt;T&gt;&amp;
std::auto_ptr&lt;T&gt;
std::auto_ptr&lt;T&gt; const&amp;
boost::shared_ptr&lt;T&gt;&amp;
boost::shared_ptr&lt;T&gt;
boost::shared_ptr&lt;T&gt; const&amp;
</pre></blockquote>
Most of these are implemented in terms of just a few conversions, and
<t>if you're lucky</t>, they will be inlined and cause no extra
overhead. In the new system, however, a significant amount of data
will be associated with each type that needs to be converted. We
certainly don't want to register a separate unwrapper object for all
of the above types.
<p>Fortunately, much of the redundancy can be eliminated. For example,
if we generate an unwrapper for <tt>T&</tt>, we don't need an
unwrapper for <tt>T const&</tt> or <tt>T</tt>. Accordingly, the user's
request to wrap/unwrap a given type is translated at compile-time into
a request which helps to eliminate redundancy. The rules used to
<tt>unwrap</tt> a type are:
<ol>
<li> Treat built-in types specially: when unwrapping a value or
constant reference to one of these, use a value for the target
type. It will bind to a const reference if neccessary, and more
importantly, avoids having to dynamically allocate room for
an lvalue of types which can be cheaply copied.
<li>
Reduce everything else to a reference to an un-cv-qualified type
where possible. Since cv-qualification is lost on Python
anyway, there's no point in trying to convert to a
<tt>const&amp;</tt>. <font color="#ff0000">What about conversions
to values like the tuple-&gt;vector example above? It seems to me
that we don't want to make a <tt>vector&lt;double&gt;&amp;</tt>
(non-const) converter available for that case. We may need to
rethink this slightly.</font>
</ol>
<p>To handle the problem described above in item 2, we modify the
procedure slightly. To unwrap any non-scalar <tt>T</tt>, we seek an
unwrapper for <tt>add_reference&lt;T&gt;::type</tt>. Unwrappers for
<tt>T&nbsp;const&amp;</tt> always return <tt>T&amp;</tt>, and are
registered under both <tt>T&nbsp;&amp;</tt> and
<tt>T&nbsp;const&amp;</tt>.
<p>For compilers not supporting partial specialization, unwrappers for
<tt>T&nbsp;const&amp;</tt> must return <tt>T&nbsp;const&amp;</tt>
(since constness can't be stripped), but a separate unwrapper object
need to be registered for <tt>T&nbsp;&amp;</tt> and
<tt>T&nbsp;const&amp;</tt> anyway, for the same reasons.
<font color="#ff0000">We may want to make it possible to compile as
though partial specialization were unavailable even on compilers where
it is available, in case modules could be compiled by different
compilers with compatible ABIs (e.g. Intel C++ and MSVC6).</font>
<h3>Efficient Argument Conversion</h3>
Since type conversions are primarily used in function wrappers, an
optimization is provided for the case where a group of conversions are
used together. Each <tt>handle</tt> class has a corresponding
&quot;<tt>_more</tt>&quot; class which does the same job, but has a
trivial destructor. Instead of asking each &quot;<tt>_more</tt>&quot;
handle to destroy its own body, it is linked into an endogenous list
managed by the first (ordinary) handle. The <tt>wrap</tt> and
<tt>unwrap</tt> destructors are responsible for traversing that list
and asking each <tt>body</tt> class to tear down its
<tt>handle</tt>. This mechanism is also used to determine if all of
the argument/return-value conversions can succeed with a single
function call in the function wrapping code. <font color="#ff0000">We
might need to handle return values in a separate step for Python
callbacks, since the availablility of a conversion won't be known
until the result object is retrieved.</font>
<br>
<hr>
<h2>References</h2>
<p><a name="ref_1">[1]</a>B. Stroustrup, The C++ Programming Language
Special Edition Addison-Wesley, ISBN 0-201-70073-5.
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
<p>© Copyright David Abrahams, 2001</p>
</body>
</html>

View File

@@ -1,111 +0,0 @@
This hierarchy contains converter handle classes.
+-------------+
| noncopyable |
+-------------+
^
| A common base class used so that
+--------+--------+ conversions can be linked into a
| conversion_base | chain for efficient argument
+-----------------+ conversion
^
|
+---------+-----------+
| |
+-----------+----+ +------+-------+ only used for
| unwrap_more<T> | | wrap_more<T> | chaining, and don't manage any
+----------------+ +--------------+ resources.
^ ^
| |
+-----+-----+ +-------+-+ These converters are what users
| unwrap<T> | | wrap<T> | actually touch, but they do so
+-----------+ +---------+ through a type generator which
minimizes the number of converters
that must be generated, so they
Each unwrap<T>, unwrap_more<T>, wrap<T>, wrap_more<T> converter holds
a reference to an appropriate converter object
This hierarchy contains converter body classes
Exposes use/release which
are needed in case the converter
+-----------+ in the registry needs to be
| converter | cloned. That occurs when a
+-----------+ unwrap target type is not
^ contained within the Python object.
|
+------------------+-----+
| |
+--------+-------+ Exposes |
| unwrapper_base | convertible() |
+----------------+ |
^ |
| |
+--------+----+ +-----+-----+
| unwrapper<T>| | wrapper<T>|
+-------------+ +-----------+
Exposes T convert(PyObject*) Exposes PyObject* convert(T)
unwrap:
constructed with a PyObject*, whose reference count is
incremented.
find the registry entry for the target type
look in the collection of converters for one which claims to be
able to convert the PyObject to the target type.
stick a pointer to the unwrapper in the unwrap object
when unwrap is queried for convertibility, it checks to see
if it has a pointer to an unwrapper.
on conversion, the unwrapper is asked to allocate an
implementation if the unwrap object isn't already holding
one. The unwrap object "takes ownership" of the unwrapper's
implementation. No memory allocation will actually take place
unless this is a value conversion.
on destruction, the unwrapper is asked to free any implementation
held by the unwrap object. No memory deallocation actually
takes place unless this is a value conversion
on destruction, the reference count on the held PyObject is
decremented.
We need to make sure that by default, you can't instantiate
callback<> for reference and pointer return types: although the
unwrappers may exist, they may convert by-value, which would cause
the referent to be destroyed upon return.
wrap:
find the registry entry for the source type
see if there is a converter. If found, stick a pointer to it in
the wrap object.
when queried for convertibility, it checks to see if it has a
pointer to a converter.
on conversion, a reference to the target PyObject is held by the
converter. Generally, the PyObject will have been created by the
converter, but in certain cases it may be a pre-existing object,
whose reference count will have been incremented.
when a wrap<T> x is used to return from a C++ function,
x.release() is returned so that x no longer holds a reference to
the PyObject when destroyed.
Otherwise, on destruction, any PyObject still held has its
reference-count decremented.
When a converter is created by the user, the appropriate element must
be added to the registry; when it is destroyed, it must be removed
from the registry.

View File

@@ -1,61 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - News/Change Log</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">News/Change Log</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt>14 November 2002</dt>
<dd>Auto-detection of class data members wrapped with <a href=
"v2/data_members.html#make_getter-spec"><code>make_getter</code></a></dd>
<dt>13 November 2002</dt>
<dd>Full Support for <code>std::auto_ptr&lt;&gt;</code> added.</dd>
<dt>October 2002</dt>
<dd>Ongoing updates and improvements to tutorial documentation</dd>
<dt>10 October 2002</dt>
<dd>Boost.Python V2 is released!</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,188 +0,0 @@
How Runtime Polymorphism is expressed in Boost.Python:
-----------------------------------------------------
struct A { virtual std::string f(); virtual ~A(); };
std::string call_f(A& x) { return x.f(); }
struct B { virtual std::string f() { return "B"; } };
struct Bcb : B
{
Bcb(PyObject* self) : m_self(self) {}
virtual std::string f() { return call_method<std::string>(m_sef, "f"); }
static std::string f_default(B& b) { return b.B::f(); }
PyObject* m_self;
};
struct C : B
{
virtual std::string f() { return "C"; }
};
>>> class D(B):
... def f():
... return 'D'
...
>>> class E(B): pass
...
When we write, "invokes B::f non-virtually", we mean:
void g(B& x) { x.B::f(); }
This will call B::f() regardless of the dynamic type of x. Any other
way of invoking B::f, including through a function pointer, is a
"virtual invocation", and will call the most-derived override of f().
Case studies
C++\Python class
\___A_____B_____C_____D____E___
|
A | 1
|
B | 2 3
|
Bcb | 4 5 6
|
C | 7 8
|
1. Simple case
2. Python A holds a B*. Probably won't happen once we have forced
downcasting.
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: A.f invokes A::f() (virtually or otherwise)
3. Python B holds a B*.
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: B.f invokes B::f (virtually or otherwise)
4. B constructed from Python
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: B.f invokes B::f non-virtually. Bcb::f invokes B::f
non-virtually.
Question: Does it help if we arrange for Python B construction to
build a true B object? Then this case doesn't arise.
5. D is a Python class derived from B
Requires:
x.f() -> 'D'
call_f(x) -> 'D'
Implies: Bcb::f must invoke call_method to look up the Python
method override, otherwise call_f wouldn't work.
6. E is like D, but doesn't override f
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: B.f invokes B::f non-virtually. If it were virtual, x.f()
would cause infinite recursion, because we've already
determined that Bcb::f must invoke call_method to look up
the Python method override.
7. Python B object holds a C*
Requires:
x.f() -> 'C'
call_f(x) -> 'C'
Implies: B.f invokes B::f virtually.
8. C object constructed from Python
Requires:
x.f() -> 'C'
call_f(x) -> 'C'
Implies: nothing new.
------
Total implications:
2: A.f invokes A::f() (virtually or otherwise)
3: B.f invokes B::f (virtually or otherwise)
4: B.f invokes B::f non-virtually. Bcb::f invokes B::f non-virtually
6: B.f invokes B::f non-virtually.
7: B.f invokes B::f virtually.
5: Bcb::f invokes call_method to look up the Python method
Though (4) is avoidable, clearly 6 and 7 are not, and they
conflict. The implication is that B.f must choose its behavior
according to the type of the contained C++ object. If it is Bcb, a
non-virtual call to B::f must occur. Otherwise, a virtual call to B::f
must occur. This is essentially the same scheme we had with
Boost.Python v1.
Note: in early versions of Boost.Python v1, we solved this problem by
introducing a new Python class in the hierarchy, so that D and E
actually derive from a B', and B'.f invokes B::f non-virtually, while
B.f invokes B::f virtually. However, people complained about the
artificial class in the hierarchy, which was revealed when they tried
to do normal kinds of Python introspection.
-------
Assumption: we will have a function which builds a virtual function
dispatch callable Python object.
make_virtual_function(pvmf, default_impl, call_policies, dispatch_type)
Pseudocode:
Get first argument from Python arg tuple
if it contains dispatch_type
call default_impl
else
call through pvmf
Open questions:
1. What about Python multiple inheritance? Do we have the right
check in the if clause above?
A: Not quite. The correct test looks like:
Deduce target type of pvmf, i.e. T in R(T::*)(A1...AN).
Find holder in first argument which holds T
if it holds dispatch_type...
2. Can we make this more efficient?
The current "returning" mechanism will look up a holder for T
again. I don't know if we know how to avoid that.

View File

@@ -1,157 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - Projects using Boost.Python</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Projects using Boost.Python</h2>
</td>
</tr>
</table>
<hr>
<h2>Introduction</h2>
<p>This is a partial list of projects using Boost.Python. If you are
using Boost.Python as your Python/C++ binding solution, we'd be proud to
list your project on this page. Just <a href=
"mailto:c++-sig@python.org">post</a> a short description of your project
and how Boost.Python helps you get the job done, and we'll add it to
.</p>
<hr>
<dl class="page-index">
<dt><b>TSLib</b> - <a href="http://www.fortressinv.com">Fortress
Investment Group LLC</a></dt>
<dd>
Fortress Investment Group has contracted <a href=
"http://www.boost-consulting.com">Boost Consulting</a> to develop
core internal financial analysis tools in C++ and to prepare Python
bindings for them using Boost.Python.
<p><a href="mailto:tbarket@optonline.com">Tom Barket</a> writes:</p>
<blockquote>
<i>We have a large C++ analytical library specialized for research
in finance and economics, built for speed and mission critical
stability. Yet Python offers us the flexibility to test out new
ideas quickly and increase the productivity of our time versus
working in C++. There are several key features which make Python
stand out. Its elegance, stability, and breadth of resources on the
web are all valuable, but the most important is its extensibility,
due to its open source transparency. Boost.Python makes Python
extensibility extremely simple and straightforward, yet preserves a
great deal of power and control.</i>
</blockquote>
</dd>
<dt><a href="http://www.llnl.gov/CASC/emsolve"><b>EMSolve</b></a></dt>
<dd>EMSolve is a provably stable, charge conserving, and energy
conserving solver for Maxwell's equations.<br>
&nbsp;</dd>
<dt><b><a href=
"http://www.openscenegraph.org">OpenSceneGraph</a></b></dt>
<dd><a href="mailto:gideon@computer.org">Gideon May</a> has created a
set of bindings for OpenSceneGraph, a cross-platform C++/OpenGL library
for the real-time visualization. You can read the release announcement
at <a href="http://www.hypereyes.com">www.hypereyes.com</a>. <a href=
"mailto:gideon@computer.org">Contact Gideon</a> for more
information.<br>
&nbsp;</dd>
<dt><a href=
"http://pythonmagick.procoders.net/"><b>PythonMagick</b></a></dt>
<dd>PythonMagick binds the <a href=
"http://www.imagemagick.org">ImageMagick</a> image manipulation library
to Python.<br>
&nbsp;</dd>
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
<dd>
The OpenWBEM project is an effort to develop an open-source
implementation of Web Based Enterprise Management suitable for
commercial and non-commercial application
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
<blockquote>
<i>I'm using Boost.Python to wrap the client API of OpenWBEM.This
will make it easier to do rapid prototyping, testing, and scripting
when developing management solutions that use WBEM.</i>
</blockquote>
</dd>
<dt><a href="http://camfr.sourceforge.net"><b>CAMFR</b></a></dt>
<dd>
CAMFR is a photonics and electromagnetics modelling tool. Python is
used for computational steering.
<p><a href="mailto:Peter.Bienstman@rug.ac.be">Peter Bienstman</a>
writes:</p>
<blockquote>
<i>Thanks for providing such a great tool!</i>
</blockquote>
</dd>
<dt><b>HippoDraw</b> - <a href="http://www.slac.stanford.edu">Stanford
Linear Accelerator Center</a></dt>
<dd>
HippoDraw is a data analysis environment consisting of a canvas upon
which graphs such as histograms, scattter plots, etc, are prsented.
It has a highly interactive GUI interface, but some things you need
to do with scripts. HippoDraw can be run as Python extension module
so that all the manipulation can be done from either Python or the
GUI.
<p><a href="mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a>
writes:</p>
<blockquote>
<i>Don't have a web page for the project, but the organization's is
<a href=
"http://www.slac.stanford.edu">http://www.slac.stanford.edu</a>
(the first web server site in America, I installed it).</i>
</blockquote>
Which was just too cool a piece of trivia to omit.
</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
16 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,68 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - Support Resources</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Support Resources</h2>
</td>
</tr>
</table>
<hr>
<h2>Synopsis</h2>
<p>This is a list of available resources for support with Boost.Python
problems and feature requests.</p>
<hr>
<dl class="page-index">
<dt><b><a href="http://www.boost-consulting.com">Boost
Consulting</a></b> - Commercial support, development, training, and
distribution for all the Boost libraries, from the people who brought
you Boost.Python.<br>
&nbsp;</dt>
<dt><b><a href="http://www.python.org/sigs/c++-sig/">The Python
C++-sig</a></b> mailing list is a forum for discussing Python/C++
interoperability, and Boost.Python in particular.<br>
&nbsp;</dt>
<dt>The <b>Boost.Python <a href=
"http://www.python.org/cgi-bin/moinmoin/boost_2epython">Wiki
Pages</a></b> established by Mike Rovner as part of the <a href=
"http://www.python.org/cgi-bin/moinmoin">PythonInfo Wiki</a> serves as
a forum to gather peoples' experience and as a cookbook.<br>
&nbsp;</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
17 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,77 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Basic Interface</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="object_interface.html">
<link rel="next" href="derived_object_types.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Basic Interface</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="object_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="derived_object_types.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Class <tt>object</tt> wraps <tt>PyObject*</tt>. All the intricacies of dealing with
<tt>PyObject</tt>s such as managing reference counting are handled by the
<tt>object</tt> class. C++ object interoperability is seamless. Boost.Python C++
<tt>object</tt>s can in fact be explicitly constructed from any C++ object.</p>
<p>
To illustrate, this Python code snippet:</p>
<code><pre>
<span class=identifier>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=literal>'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=literal>'bar'
</span><span class=keyword>else</span><span class=special>:
</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>items </span><span class=special>+= </span><span class=identifier>y</span><span class=special>(</span><span class=number>3</span><span class=special>, </span><span class=identifier>x</span><span class=special>)
</span><span class=keyword>return </span><span class=identifier>x
</span><span class=identifier>def </span><span class=identifier>getfunc</span><span class=special>():
</span><span class=keyword>return </span><span class=identifier>f</span><span class=special>;
</span></pre></code>
<p>
Can be rewritten in C++ using Boost.Python facilities this way:</p>
<code><pre>
<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>&quot;foo&quot;</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>&quot;bar&quot;</span><span class=special>;
</span><span class=keyword>else
</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;items&quot;</span><span class=special>) </span><span class=special>+= </span><span class=identifier>y</span><span class=special>(</span><span class=number>3</span><span class=special>, </span><span class=identifier>x</span><span class=special>);
</span><span class=keyword>return </span><span class=identifier>x</span><span class=special>;
</span><span class=special>}
</span><span class=identifier>object </span><span class=identifier>getfunc</span><span class=special>() </span><span class=special>{
</span><span class=keyword>return </span><span class=identifier>object</span><span class=special>(</span><span class=identifier>f</span><span class=special>);
</span><span class=special>}
</span></pre></code>
<p>
Apart from cosmetic differences due to the fact that we are writing the
code in C++, the look and feel should be immediately apparent to the Python
coder.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="object_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="derived_object_types.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,186 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Building an Extension Module </title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_data_members.html">
<link rel="next" href="inheritance.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><strong>Building
an Extension Module</strong></font> </td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr.gif" border="0"></td>
<td width="20"><img src="theme/r_arr.gif" border="0"></td>
</tr>
</table>
<h2>Building Boost.Python</h2>
<p>Every Boost.Python extension module must be linked with the boost_python shared
library. To build boost_python, use <a href="file:///C:/dev/boost/tools/build/index.html">Boost.Build</a>
in the usual way from the <tt>libs/python/build</tt> subdirectory of your boost
installation (if you have already built boost from the top level this may have
no effect, since the work is already done).</p>
<h2>Configuration</h2>
<p>You may need to configure the following variables to point Boost.Build at your
Python installation:</p>
<table width="95%" border="0" align="center">
<tr class="table_title">
<td width="24%">Variable Name</td>
<td width="20%">Semantics</td>
<td width="21%">Default</td>
<td width="35%">Notes</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_ROOT</tt></td>
<td> The root directory of your Python installation</td>
<td>Windows: <tt><br>
c:/tools/python <br>
Unix: /usr/local</tt></td>
<td>On Unix, this is the <tt>--with-prefix=</tt> directory used to configure
Python</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_VERSION</tt></td>
<td> The The 2-part python Major.Minor version number</td>
<td>Windows: 2.1 Unix: 1.5</td>
<td>Be sure not to include a third number, e.g. not &quot;2.2.1&quot;, even
if that's the version you have.</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_INCLUDES</tt></td>
<td> path to Python <span class="preprocessor">#include</span> directories</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td>&nbsp;</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_LIB_PATH</tt></td>
<td>path to Python library object.</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td>&nbsp;</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_STDLIB_PATH</tt></td>
<td>path to Python standard library modules</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td>&nbsp;</td>
</tr>
<tr class="table_cells">
<td height="129"><tt>CYGWIN_ROOT</tt></td>
<td> path to the user's Cygwin installation</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the following
two settings are useful when building with multiple toolsets on Windows,
since Cygwin requires a different build of Python.</td>
</tr>
<tr class="table_cells">
<td height="21"><tt>GCC_PYTHON_ROOT</tt></td>
<td>path to the user's Cygwin Python installation</td>
<td><tt>$(CYGWIN_ROOT)<br>
/usr/local</tt></td>
<td> <a href="http://www.cygwin.com">Cygwin</a> only</td>
</tr>
<tr class="table_cells">
<td><tt>GCC_DEBUG_PYTHON_ROOT</tt></td>
<td> path to the user's Cygwin <a href="#variants">pydebug</a>
build</td>
<td><tt>$(CYGWIN_ROOT)<br>
/usr/local/pydebug</tt></td>
<td> <a href="http://www.cygwin.com">Cygwin</a> only</td>
</tr>
</table>
<h2>Results</h2>
<p>The build process will create a <tt>libs/python/build/bin-stage</tt> subdirectory
of the boost root (or of <tt>$(ALL_LOCATE_TARGET)</tt>, if you have set that
variable), containing the built libraries. The libraries are actually built
to unique directories for each toolset and variant elsewhere in the filesystem,
and copied to the bin-stage directory as a convenience, so if you build with
multiple toolsets at once, the product of later toolsets will overwrite that
of earlier toolsets in bin-stage.</p>
<h2>Testing</h2>
<p>To build and test Boost.Python from within the <tt>libs/python/build directory</tt>,
invoke</p>
<pre> bjam -sTOOLS=<a href="../../../tools/build/index.html">toolset</a> test</pre>
<p>This will update all of the Boost.Python v1 test and example targets. The tests
are relatively quiet by default. To get more-verbose output, you might try</p>
<pre> bjam -sTOOLS=<a href="../../../tools/build/index.html">toolset</a> -sPYTHON_TEST_ARGS=-v test</pre>
<p>which will print each test's Python code with the expected output as it passes.</p>
<h2>Building your Extension Module</h2>
<p>Though there are other approaches, the easiest way to build an extension module
using Boost.Python is with Boost.Build. Until Boost.Build v2 is released, cross-project
build dependencies are not supported, so it works most smoothly if you add a
new subproject to your boost installation. The <tt>libs/python/example</tt>
subdirectory of your boost installation contains a minimal example (along with
many extra sources). To copy the example subproject:</p>
<ol>
<li> Create a new subdirectory in,<tt> libs/python</tt>, say <tt>libs/python/my_project</tt>.</li>
<li> Copy <a href="../example/Jamfile"><tt>libs/python/example/Jamfile</tt></a>
to your new directory.</li>
<li> Edit the Jamfile as appropriate for your project. You'll want to change
the <tt>subproject</tt> rule invocation at the top, and the names of some
of the source files and/or targets.</li>
</ol>
<p>If you can't modify or copy your boost installation, the alternative is to
create your own Boost.Build project. A similar example you can use as a starting
point is available in <a href="../example/project.zip">this archive</a>. You'll
need to edit the Jamfile and Jamrules files, depending on the relative location
of your Boost installation and the new project. Note that automatic testing
of extension modules is not available in this configuration.</p>
<h2>Build Variants</h2>
<p>Three variant configurations of all python-related targets are supported, and
can be selected by setting the BUILD variable:</p>
<p> * <tt>release</tt> (optimization, <tt>-DNDEBUG</tt>)<br>
* <tt>debug</tt> (no optimization <tt>-D_DEBUG</tt>)<br>
* <tt>debug-python</tt> (no optimization, <tt>-D_DEBUG -DBOOST_DEBUG_PYTHON</tt>)</p>
<p>The first two variants of the boost_python library are built by default, and
are compatible with the default Python distribution. The debug-python variant
corresponds to a specially-built debugging version of Python. On Unix platforms,
this python is built by adding <tt>--with-pydebug</tt> when configuring the
Python build. On Windows, the debugging version of Python is generated by the
&quot;Win32 Debug&quot; target of the PCBuild.dsw Visual C++ 6.0 project in
the PCBuild subdirectory of your Python distribution. Extension modules built
with Python debugging enabled are not link-compatible with a non-debug build
of Python. Since few people actually have a debug build of Python (it doesn't
come with the standard distribution), the normal debug variant builds modules
which are compatible with ordinary Python.</p>
<p>On many windows compilers, when extension modules are built with <tt>-D_DEBUG</tt>,
Python defaults to force linking with a special debugging version of the Python
DLL. Since this debug DLL isn't supplied with the default Python installation
for Windows, Boost.Python uses <a href="../../../boost/python/detail/wrap_python.hpp"><tt>boost/python/detail/wrap_python.hpp</tt></a>
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is <span class="preprocessor">#included</span>
- unless <tt>BOOST_DEBUG_PYTHON</tt> is defined.</p>
<p>If you want the extra runtime checks available with the debugging version of
the library, <span class="preprocessor">#define</span> <tt>BOOST_DEBUG_PYTHON</tt>
to re-enable python debuggin, and link with the debug-python variant of boost_python.</p>
<p>If you do not <span class="preprocessor">#define</span> <tt>BOOST_DEBUG_PYTHON</tt>,
be sure that any source files in your extension module <span class="preprocessor">#include</span>
<tt>&lt;boost/python/detail/wrap_python.hpp&gt;</tt> instead of the usual <tt>Python.h</tt>,
or you will have link incompatibilities.</p>
<code></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr.gif" border="0"></td>
<td width="20"><img src="theme/r_arr.gif" border="0"></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,191 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Building Hello World</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="quickstart.html">
<link rel="next" href="exposing_classes.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Building Hello World</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="quickstart.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exposing_classes.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<a name="from_start_to_finish"></a><h2>From Start To Finish</h2><p>
Now the first thing you'd want to do is to build the Hello World module and
try it for yourself in Python. In this section, we shall outline the steps
necessary to achieve that. We shall use the build tool that comes bundled
with every boost distribution: <b>bjam</b>.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/lens.gif"></img> <b>Building without bjam</b><br><br>
Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as &quot;the one and only way&quot;.
There are of course other build tools apart from <tt>bjam</tt>.
</td>
</tr>
</table>
<p>
We shall skip over the details. Our objective will be to simply create the
hello world module and run it in Python. For a complete reference to
building Boost.Python, check out: <a href="../../building.html">
building.html</a>.
After this brief <i>bjam</i> tutorial, we should have built two DLLs:</p>
<ul><li>boost_python.dll</li><li>hello.pyd</li></ul><p>
if you are on Windows, and</p>
<ul><li>libboost_python.so</li><li>hello.so</li></ul><p>
if you are on Unix.</p>
<p>
The tutorial example can be found in the directory:
<tt>libs/python/example/tutorial</tt>. There, you can find:</p>
<ul><li>hello.cpp</li><li>Jamfile</li></ul><p>
The <tt>hello.cpp</tt> file is our C++ hello world example. The <tt>Jamfile</tt> is a
minimalist <i>bjam</i> script that builds the DLLs for us.</p>
<p>
Before anything else, you should have the bjam executable in your boost
directory or somewhere in your path such that <tt>bjam</tt> can be executed in
the command line. Pre-built Boost.Jam executables are available for most
platforms. For example, a pre-built Microsoft Windows bjam executable can
be downloaded <a href="http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip">
here</a>.
The complete list of bjam pre-built
executables can be found <a href="../../../../../tools/build/index.html#Jam">
here</a>.</p>
<a name="lets_jam_"></a><h2>Lets Jam!</h2><p>
<img src="theme/jam.png"></img></p>
<p>
Here is our minimalist Jamfile:</p>
<code><pre>
subproject libs/python/example/tutorial ;
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
extension hello # Declare a Python extension called hello
: hello.cpp # source
&lt;dll&gt;../../build/boost_python # dependencies
;
</pre></code><p>
First, we need to specify our location in the boost project hierarchy.
It so happens that the tutorial example is located in <tt>/libs/python/example/tutorial</tt>.
Thus:</p>
<code><pre>
subproject libs/python/example/tutorial ;
</pre></code><p>
Then we will include the definitions needed by Python modules:</p>
<code><pre>
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
</pre></code><p>
Finally we declare our <tt>hello</tt> extension:</p>
<code><pre>
extension hello # Declare a Python extension called hello
: hello.cpp # source
&lt;dll&gt;../../build/boost_python # dependencies
;
</pre></code><a name="running_bjam"></a><h2>Running bjam</h2><p>
<i>bjam</i> is run using your operating system's command line interpreter.</p>
<blockquote><p>Start it up.</p></blockquote><p>
Make sure that the environment is set so that we can invoke the C++
compiler. With MSVC, that would mean running the <tt>Vcvars32.bat</tt> batch
file. For instance:</p>
<code><pre>
<span class=identifier>C</span><span class=special>:\</span><span class=identifier>Program </span><span class=identifier>Files</span><span class=special>\</span><span class=identifier>Microsoft </span><span class=identifier>Visual </span><span class=identifier>Studio</span><span class=special>\</span><span class=identifier>VC98</span><span class=special>\</span><span class=identifier>bin</span><span class=special>\</span><span class=identifier>Vcvars32</span><span class=special>.</span><span class=identifier>bat
</span></pre></code>
<p>
Some environment variables will have to be setup for proper building of our
Python modules. Example:</p>
<code><pre>
<span class=identifier>set </span><span class=identifier>PYTHON_ROOT</span><span class=special>=</span><span class=identifier>c</span><span class=special>:/</span><span class=identifier>dev</span><span class=special>/</span><span class=identifier>tools</span><span class=special>/</span><span class=identifier>python
</span><span class=identifier>set </span><span class=identifier>PYTHON_VERSION</span><span class=special>=</span><span class=number>2.2
</span></pre></code>
<p>
The above assumes that the Python installation is in <tt>c:/dev/tools/python</tt>
and that we are using Python version 2.2. You'll have to tweak this path
appropriately. <img src="theme/note.gif"></img> Be sure not to include a third number, e.g. <b>not</b> &quot;2.2.1&quot;,
even if that's the version you have.</p>
<p>
Now we are ready... Be sure to <tt>cd</tt> to <tt>libs/python/example/tutorial</tt>
where the tutorial <tt>&quot;hello.cpp&quot;</tt> and the <tt>&quot;Jamfile&quot;</tt> is situated.</p>
<p>
Finally:</p>
<code><pre>
<span class=identifier>bjam </span><span class=special>-</span><span class=identifier>sTOOLS</span><span class=special>=</span><span class=identifier>msvc
</span></pre></code>
<p>
We are again assuming that we are using Microsoft Visual C++ version 6. If
not, then you will have to specify the appropriate tool. See
<a href="../../../../../tools/build/index.html">
Building Boost Libraries</a> for
further details.</p>
<p>
It should be building now:</p>
<code><pre>
cd C:\dev\boost\libs\python\example\tutorial
bjam -sTOOLS=msvc
...patience...
...found 1703 targets...
...updating 40 targets...
</pre></code><p>
And so on... Finally:</p>
<code><pre>
vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
runtime-link-dynamic\hello.obj
hello.cpp
vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\
hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\
msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\
example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
...updated 40 targets...
</pre></code><p>
If all is well, you should now have:</p>
<ul><li>boost_python.dll</li><li>hello.pyd</li></ul><p>
if you are on Windows, and</p>
<ul><li>libboost_python.so</li><li>hello.so</li></ul><p>
if you are on Unix.</p>
<p>
<tt>boost_python.dll</tt> can be found somewhere in <tt>libs\python\build\bin</tt>
while <tt>hello.pyd</tt> can be found somewhere in
<tt>libs\python\example\tutorial\bin</tt>. After a successful build, you can just
link in these DLLs with the Python interpreter. In Windows for example, you
can simply put these libraries inside the directory where the Python
executable is.</p>
<p>
You may now fire up Python and run our hello module:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>hello
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>hello</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></code>
<blockquote><p><b>There you go... Have fun!</b></p></blockquote><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="quickstart.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exposing_classes.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,169 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Call Policies</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="functions.html">
<link rel="next" href="default_arguments.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Call Policies</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
In C++, we often deal with arguments and return types such as pointers
and references. Such primitive types are rather, ummmm, low level and
they really don't tell us much. At the very least, we don't know the
owner of the pointer or the referenced object. No wonder languages
such as Java and Python never deal with such low level entities. In
C++, it's usually considered a good practice to use smart pointers
which exactly describe ownership semantics. Still, even good C++
interfaces use raw references and pointers sometimes, so Boost.Python
must deal with them. To do this, it may need your help. Consider the
following C++ function:</p>
<code><pre>
<span class=identifier>X</span><span class=special>&amp; </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>Y</span><span class=special>&amp; </span><span class=identifier>y</span><span class=special>, </span><span class=identifier>Z</span><span class=special>* </span><span class=identifier>z</span><span class=special>);
</span></pre></code>
<p>
How should the library wrap this function? A naive approach builds a
Python X object around result reference. This strategy might or might
not work out. Here's an example where it didn't</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>) </span>#<span class=identifier>x </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>some </span><span class=identifier>C</span><span class=special>++ </span><span class=identifier>X
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>del </span><span class=identifier>y
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>some_method</span><span class=special>() </span>#<span class=identifier>CRASH</span><span class=special>!
</span></pre></code>
<p>
What's the problem?</p>
<p>
Well, what if f() was implemented as shown below:</p>
<code><pre>
<span class=identifier>X</span><span class=special>&amp; </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>Y</span><span class=special>&amp; </span><span class=identifier>y</span><span class=special>, </span><span class=identifier>Z</span><span class=special>* </span><span class=identifier>z</span><span class=special>)
</span><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=keyword>return </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>x</span><span class=special>;
</span><span class=special>}
</span></pre></code>
<p>
The problem is that the lifetime of result X&amp; is tied to the lifetime
of y, because the f() returns a reference to a member of the y
object. This idiom is is not uncommon and perfectly acceptable in the
context of C++. However, Python users should not be able to crash the
system just by using our C++ interface. In this case deleting y will
invalidate the reference to X. We have a dangling reference.</p>
<p>
Here's what's happening:</p>
<ol><li><tt>f</tt> is called passing in a reference to <tt>y</tt> and a pointer to <tt>z</tt></li><li>A reference to <tt>y.x</tt> is returned</li><li><tt>y</tt> is deleted. <tt>x</tt> is a dangling reference</li><li><tt>x.some_method()</tt> is called</li><li><b>BOOM!</b></li></ol><p>
We could copy result into a new object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </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=identifier>Result </span><span class=identifier>disappears
</span><span class=special>&gt;&gt;&gt; </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=identifier>No </span><span class=identifier>crash</span><span class=special>, </span><span class=identifier>but </span><span class=identifier>still </span><span class=identifier>bad
</span><span class=number>3.14
</span></pre></code>
<p>
This is not really our intent of our C++ interface. We've broken our
promise that the Python interface should reflect the C++ interface as
closely as possible.</p>
<p>
Our problems do not end there. Suppose Y is implemented as follows:</p>
<code><pre>
<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><span class=keyword>int </span><span class=identifier>z_value</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>z</span><span class=special>-&gt;</span><span class=identifier>value</span><span class=special>(); </span><span class=special>}
</span><span class=special>};
</span></pre></code>
<p>
Notice that the data member <tt>z</tt> is held by class Y using a raw
pointer. Now we have a potential dangling pointer problem inside Y:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>) </span>#<span class=identifier>y </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>z
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>del </span><span class=identifier>z </span>#<span class=identifier>Kill </span><span class=identifier>the </span><span class=identifier>z </span><span class=identifier>object
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>z_value</span><span class=special>() </span>#<span class=identifier>CRASH</span><span class=special>!
</span></pre></code>
<p>
For reference, here's the implementation of <tt>f</tt> again:</p>
<code><pre>
<span class=identifier>X</span><span class=special>&amp; </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>Y</span><span class=special>&amp; </span><span class=identifier>y</span><span class=special>, </span><span class=identifier>Z</span><span class=special>* </span><span class=identifier>z</span><span class=special>)
</span><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=keyword>return </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>x</span><span class=special>;
</span><span class=special>}
</span></pre></code>
<p>
Here's what's happening:</p>
<ol><li><tt>f</tt> is called passing in a reference to <tt>y</tt> and a pointer to <tt>z</tt></li><li>A pointer to <tt>z</tt> is held by <tt>y</tt></li><li>A reference to <tt>y.x</tt> is returned</li><li><tt>z</tt> is deleted. <tt>y.z</tt> is a dangling pointer</li><li><tt>y.z_value()</tt> is called</li><li><tt>z-&gt;value()</tt> is called</li><li><b>BOOM!</b></li></ol><a name="call_policies"></a><h2>Call Policies</h2><p>
Call Policies may be used in situations such as the example detailed above.
In our example, <tt>return_internal_reference</tt> and <tt>with_custodian_and_ward</tt>
are our friends:</p>
<code><pre>
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>,
</span><span class=identifier>return_internal_reference</span><span class=special>&lt;</span><span class=number>1</span><span class=special>,
</span><span class=identifier>with_custodian_and_ward</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>&gt; </span><span class=special>&gt;());
</span></pre></code>
<p>
What are the <tt>1</tt> and <tt>2</tt> parameters, you ask?</p>
<code><pre>
<span class=identifier>return_internal_reference</span><span class=special>&lt;</span><span class=number>1
</span></pre></code>
<p>
Informs Boost.Python that the first argument, in our case <tt>Y&amp; y</tt>, is the
owner of the returned reference: <tt>X&amp;</tt>. The &quot;<tt>1</tt>&quot; simply specifies the
first argument. In short: &quot;return an internal reference <tt>X&amp;</tt> owned by the
1st argument <tt>Y&amp; y</tt>&quot;.</p>
<code><pre>
<span class=identifier>with_custodian_and_ward</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>&gt;
</span></pre></code>
<p>
Informs Boost.Python that the lifetime of the argument indicated by ward
(i.e. the 2nd argument: <tt>Z* z</tt>) is dependent on the lifetime of the
argument indicated by custodian (i.e. the 1st argument: <tt>Y&amp; y</tt>).</p>
<p>
It is also important to note that we have defined two policies above. Two
or more policies can be composed by chaining. Here's the general syntax:</p>
<code><pre>
<span class=identifier>policy1</span><span class=special>&lt;</span><span class=identifier>args</span><span class=special>...,
</span><span class=identifier>policy2</span><span class=special>&lt;</span><span class=identifier>args</span><span class=special>...,
</span><span class=identifier>policy3</span><span class=special>&lt;</span><span class=identifier>args</span><span class=special>...&gt; </span><span class=special>&gt; </span><span class=special>&gt;
</span></pre></code>
<p>
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">
here</a>.</p>
<ul><li><b>with_custodian_and_ward</b><br> Ties lifetimes of the arguments</li><li><b>with_custodian_and_ward_postcall</b><br> Ties lifetimes of the arguments and results</li><li><b>return_internal_reference</b><br> Ties lifetime of one argument to that of result</li><li><b>return_value_policy&lt;T&gt; with T one of:</b><br></li><li><b>reference_existing_object</b><br>naïve (dangerous) approach</li><li><b>copy_const_reference</b><br>Boost.Python v1 approach</li><li><b>copy_non_const_reference</b><br></li><li><b>manage_new_object</b><br> Adopt a pointer and hold the instance</li></ul><table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/smiley.gif"></img> <b>Remember the Zen, Luke:</b><br><br>
&quot;Explicit is better than implicit&quot;<br>
&quot;In the face of ambiguity, refuse the temptation to guess&quot;<br> </td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,77 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Class Data Members</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="constructors.html">
<link rel="next" href="class_properties.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Data Members</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="constructors.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_properties.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<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 <b>read-only</b> or
<b>read-write</b>. Consider this class <tt>Var</tt>:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Var
</span><span class=special>{
</span><span class=identifier>Var</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>name</span><span class=special>) </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>value</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=keyword>const </span><span class=identifier>name</span><span class=special>;
</span><span class=keyword>float </span><span class=identifier>value</span><span class=special>;
</span><span class=special>};
</span></pre></code>
<p>
Our C++ <tt>Var</tt> class and its data members can be exposed to Python:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Var</span><span class=special>&gt;(</span><span class=string>&quot;Var&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;name&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>name</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def_readwrite</span><span class=special>(</span><span class=string>&quot;value&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>value</span><span class=special>);
</span></pre></code>
<p>
Then, in Python:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>Var</span><span class=special>(</span><span class=literal>'pi'</span><span class=special>)
</span><span class=special>&gt;&gt;&gt; </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>&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>name</span><span class=special>, </span><span class=literal>'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=identifier>is </span><span class=identifier>around </span><span class=number>3.14
</span></pre></code>
<p>
Note that <tt>name</tt> is exposed as <b>read-only</b> while <tt>value</tt> is exposed
as <b>read-write</b>.</p>
<code><pre>
&gt;&gt;&gt; x.name = 'e' # can't change name
Traceback (most recent call last):
File &quot;&lt;stdin&gt;&quot;, line 1, in ?
AttributeError: can't set attribute
</pre></code><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="constructors.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_properties.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,109 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Class Operators/Special Functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_virtual_functions.html">
<link rel="next" href="functions.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Operators/Special Functions</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<a name="python_operators"></a><h2>Python Operators</h2><p>
C is well known for the abundance of operators. C++ extends this to the
extremes by allowing operator overloading. Boost.Python takes advantage of
this and makes it easy to wrap C++ operator-powered classes.</p>
<p>
Consider a file position class <tt>FilePos</tt> and a set of operators that take
on FilePos instances:</p>
<code><pre>
<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><span class=identifier>FilePos </span><span class=keyword>operator</span><span class=special>+(</span><span class=keyword>int</span><span class=special>, </span><span class=identifier>FilePos</span><span class=special>);
</span><span class=keyword>int </span><span class=keyword>operator</span><span class=special>-(</span><span class=identifier>FilePos</span><span class=special>, </span><span class=identifier>FilePos</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><span class=identifier>FilePos</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>+=(</span><span class=identifier>FilePos</span><span class=special>&amp;, </span><span class=keyword>int</span><span class=special>);
</span><span class=identifier>FilePos</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>-=(</span><span class=identifier>FilePos</span><span class=special>&amp;, </span><span class=keyword>int</span><span class=special>);
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>&lt;(</span><span class=identifier>FilePos</span><span class=special>, </span><span class=identifier>FilePos</span><span class=special>);
</span></pre></code>
<p>
The class and the various operators can be mapped to Python rather easily
and intuitively:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>FilePos</span><span class=special>&gt;(</span><span class=string>&quot;FilePos&quot;</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>// __rsub__
</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>&lt;</span><span class=keyword>int</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>&lt; </span><span class=identifier>self</span><span class=special>); </span><span class=comment>// __lt__
</span></pre></code>
<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>self</tt> refers to FilePos object. Also, not every class <tt>T</tt> that
you might need to interact with in an operator expression is (cheaply)
default-constructible. You can use <tt>other&lt;T&gt;()</tt> in place of an actual
<tt>T</tt> instance when writing &quot;self expressions&quot;.</p>
<a name="special_methods"></a><h2>Special Methods</h2><p>
Python has a few more <i>Special Methods</i>. Boost.Python supports all of the
standard special method names supported by real Python class instances. A
similar set of intuitive interfaces can also be used to wrap C++ functions
that correspond to these Python <i>special functions</i>. Example:</p>
<code><pre>
<span class=keyword>class </span><span class=identifier>Rational
</span><span class=special>{ </span><span class=keyword>operator </span><span class=keyword>double</span><span class=special>() </span><span class=keyword>const</span><span class=special>; </span><span class=special>};
</span><span class=identifier>Rational </span><span class=identifier>pow</span><span class=special>(</span><span class=identifier>Rational</span><span class=special>, </span><span class=identifier>Rational</span><span class=special>);
</span><span class=identifier>Rational </span><span class=identifier>abs</span><span class=special>(</span><span class=identifier>Rational</span><span class=special>);
</span><span class=identifier>ostream</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>&lt;&lt;(</span><span class=identifier>ostream</span><span class=special>&amp;,</span><span class=identifier>Rational</span><span class=special>);
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Rational</span><span class=special>&gt;()
</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>&lt;</span><span class=identifier>Rational</span><span class=special>&gt;)) </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></code>
<p>
Need we say more?</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/lens.gif"></img> What is the business of <tt>operator&lt;&lt;</tt> <tt>.def(str(self))</tt>?
Well, the method <tt>str</tt> requires the <tt>operator&lt;&lt;</tt> to do its work (i.e.
<tt>operator&lt;&lt;</tt> is used by the method defined by def(str(self)). </td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,83 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Class Properties</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_data_members.html">
<link rel="next" href="inheritance.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Properties</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_data_members.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="inheritance.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
In C++, classes with public data members are usually frowned
upon. Well designed classes that take advantage of encapsulation hide
the class' data members. The only way to access the class' data is
through access (getter/setter) functions. Access functions expose class
properties. Here's an example:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Num
</span><span class=special>{
</span><span class=identifier>Num</span><span class=special>();
</span><span class=keyword>float </span><span class=identifier>get</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=keyword>float </span><span class=identifier>value</span><span class=special>);
</span><span class=special>...
</span><span class=special>};
</span></pre></code>
<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>Num</tt> class using Boost.Python:</p>
<code>
<pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Num</span><span class=special>&gt;(</span><span class=string>&quot;Num&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;rovalue&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Num</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
</span><span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;value&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Num</span><span class=special>::</span><span class=identifier>get</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>set</span><span class=special>);
</span></pre>
</code>
<p>
And at last, in Python:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>Num</span><span class=special>()
</span><span class=special>&gt;&gt;&gt; </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>&gt;&gt;&gt; </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>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>rovalue </span><span class=special>= </span><span class=number>2.17 </span>#<span class=identifier>error</span><span class=special>!
</span></pre></code>
<p>
Take note that the class property <tt>rovalue</tt> is exposed as <b>read-only</b>
since the <tt>rovalue</tt> setter member function is not passed in:</p>
<code><pre>
<span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;rovalue&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_data_members.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="inheritance.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,237 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Class Virtual Functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="inheritance.html">
<link rel="next" href="class_operators_special_functions.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Virtual Functions</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
In this section, we shall learn how to make functions behave
polymorphically through virtual functions. Continuing our example, let us
add a virtual function to our <tt>Base</tt> class:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>= </span><span class=number>0</span><span class=special>;
</span><span class=special>};
</span></pre></code>
<p>
Since <tt>f</tt> is a pure virtual function, <tt>Base</tt> is now an abstract
class. Given an instance of our class, the free function <tt>call_f</tt>
calls some implementation of this virtual function in a concrete
derived class:</p>
<code><pre>
<span class=keyword>int </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>&amp; </span><span class=identifier>b</span><span class=special>) </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>.</span><span class=identifier>f</span><span class=special>(); </span><span class=special>}
</span></pre></code>
<p>
To allow this function to be implemented in a Python derived class, we
need to create a class wrapper:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
</span><span class=special>{
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
</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=special>{}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); </span><span class=special>}
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
</span><span class=special>};
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/lens.gif"></img> <b>member function and methods</b><br><br> Python, like
many object oriented languages uses the term <b>methods</b>. Methods
correspond roughly to C++'s <b>member functions</b> </td>
</tr>
</table>
<p>
Our class wrapper <tt>BaseWrap</tt> is derived from <tt>Base</tt>. Its overridden
virtual member function <tt>f</tt> in effect calls the corresponding method
of the Python object <tt>self</tt>, which is a pointer back to the Python
<tt>Base</tt> object holding our <tt>BaseWrap</tt> instance.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> <b>Why do we need BaseWrap?</b><br><br>
<i>You may ask</i>, &quot;Why do we need the <tt>BaseWrap</tt> derived class? This could
have been designed so that everything gets done right inside of
Base.&quot;<br><br>
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. To unintrusively
hook into the virtual functions so that a Python override may be called, we
must use a derived class.<br><br>
Note however that you don't need to do this to get methods overridden
in Python to behave virtually when called <i>from</i> <b>Python</b>. The only
time you need to do the <tt>BaseWrap</tt> dance is when you have a virtual
function that's going to be overridden in Python and called
polymorphically <i>from</i> <b>C++</b>. </td>
</tr>
</table>
<p>
Wrapping <tt>Base</tt> and the free function <tt>call_f</tt>:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</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>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>, </span><span class=identifier>no_init</span><span class=special>)
</span><span class=special>;
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;call_f&quot;</span><span class=special>, </span><span class=identifier>call_f</span><span class=special>);
</span></pre></code>
<p>
Notice that we parameterized the <tt>class_</tt> template with <tt>BaseWrap</tt> as the
second parameter. What is <tt>noncopyable</tt>? Without it, the library will try
to create code for converting Base return values of wrapped functions to
Python. To do that, it needs Base's copy constructor... which isn't
available, since Base is an abstract class.</p>
<p>
In Python, let us try to instantiate our <tt>Base</tt> class:</p>
<code>
<pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
</span>RuntimeError: This class cannot be instantiated from Python</pre>
</code>
<p>
Why is it an error? <tt>Base</tt> is an abstract class. As such it is advisable
to define the Python wrapper with <tt>no_init</tt> as we have done above. Doing
so will disallow abstract base classes such as <tt>Base</tt> to be instantiated.</p>
<a name="deriving_a_python_class"></a><h2>Deriving a Python class</h2>
<p> Now, at last, we can even derive from our base class <tt>Base</tt> in Python.
Before we can do that, we have to set up our <tt>class_</tt> wrapper as:</p>
<pre> <code><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</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>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
</span><span class=special>;</span></code></pre>
<p>Otherwise, we have to suppress the Base class' <tt>no_init</tt> by adding an
<tt>__init__()</tt> method to all our derived classes. <tt>no_init </tt>actually
adds an <tt>__init__</tt> method that raises a Python RuntimeError exception.</p>
<code>
<pre>
<span class=special>&gt;&gt;&gt; </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=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=special>... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
</span></pre>
</code>
<p>
Cool eh? A Python class deriving from a C++ class!</p>
<p>
Let's now make an instance of our Python class <tt>Derived</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Will yield the expected result. Finally, calling calling the free function
<tt>call_f</tt> with <tt>derived</tt> as argument:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<p>
Will also yield the expected result.</p>
<p>
Here's what's happening:</p>
<ol><li><tt>call_f(derived)</tt> is called in Python</li><li>This corresponds to <tt>def(&quot;call_f&quot;, call_f);</tt>. Boost.Python dispatches this call.</li><li><tt>int call_f(Base&amp; b) { return b.f(); }</tt> accepts the call.</li><li>The overridden virtual function <tt>f</tt> of <tt>BaseWrap</tt> is called.</li><li><tt>call_method&lt;int&gt;(self, &quot;f&quot;);</tt> dispatches the call back to Python.</li><li><tt>def f(self): return 42</tt> is finally called.</li></ol><p>
Rewind back to our <tt>Base</tt> class, if its member function <tt>f</tt> was not
declared as pure virtual:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=number>0</span><span class=special>; </span><span class=special>}
</span><span class=special>};
</span></pre></code>
<p>
And instead is implemented to return <tt>0</tt>, as shown above.</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
</span><span class=special>{
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
</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=special>{}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); </span><span class=special>}
</span><span class=keyword>static </span><span class=keyword>int </span><span class=identifier>default_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>* </span><span class=identifier>b</span><span class=special>) </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>-&gt;</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=comment>// &lt;&lt;=== added
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
</span><span class=special>};
</span></pre></code>
<p>
then, our Boost.Python wrapper:</p>
<code>
<pre> <span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap, boost::non_copyable</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>BaseWrap</span><span class=special>::</span><span class=identifier>default_f</span><span class=special>)
</span><span class=special>;
</span></pre>
</code>
<p>
Note that we are allowing <tt>Base</tt> objects to be instantiated this time,
unlike before where we specifically defined the <tt>class_&lt;Base&gt;</tt> with
<tt>no_init</tt>.</p>
<p>
In Python, the results would be as expected:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
</span><span class=special>&gt;&gt;&gt; </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=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=special>... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>base.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>base</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>base</span><span class=special>)
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>derived</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,102 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Constructors</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="exposing_classes.html">
<link rel="next" href="class_data_members.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Constructors</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exposing_classes.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_data_members.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Our previous example didn't have any explicit constructors.
Since <tt>World</tt> is declared as a plain struct, it has an implicit default
constructor. Boost.Python exposes the default constructor by default,
which is why we were able to write</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </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></pre></code>
<p>
We may wish to wrap a class with a non-default constructor. Let us
build on our previous example:</p>
<code><pre>
<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>-&gt;</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></code>
<p>
This time <tt>World</tt> has no default constructor; our previous
wrapping code would fail to compile when the library tried to expose
it. We have to tell <tt>class_&lt;World&gt;</tt> about the constructor we want to
expose instead.</p>
<code><pre>
<span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>python</span><span class=special>;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>hello</span><span class=special>)
</span><span class=special>{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>World</span><span class=special>&gt;(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
</span><span class=special>;
</span><span class=special>}
</span></pre></code>
<p>
<tt>init&lt;std::string&gt;()</tt> exposes the constructor taking in a
<tt>std::string</tt> (in Python, constructors are spelled
&quot;<tt>&quot;__init__&quot;</tt>&quot;).</p>
<p>
We can expose additional constructors by passing more <tt>init&lt;...&gt;</tt>s to
the <tt>def()</tt> member function. Say for example we have another World
constructor taking in two doubles:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>World</span><span class=special>&gt;(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
</span><span class=special>;
</span></pre></code>
<p>
On the other hand, if we do not wish to expose any constructors at
all, we may use <tt>no_init</tt> instead:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Abstract</span><span class=special>&gt;(</span><span class=string>&quot;Abstract&quot;</span><span class=special>, </span><span class=identifier>no_init</span><span class=special>)
</span></pre></code>
<p>
This actually adds an <tt>__init__</tt> method which always raises a
Python RuntimeError exception.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exposing_classes.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_data_members.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,118 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Default Arguments</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="call_policies.html">
<link rel="next" href="object_interface.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Default Arguments</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
pointers carry no default argument info. Take a function <tt>f</tt> with default
arguments:</p>
<code><pre>
<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>&quot;hello&quot;</span><span class=special>);
</span></pre></code>
<p>
But the type of a pointer to the function <tt>f</tt> has no information
about its default arguments:</p>
<code><pre>
<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></code>
<p>
When we pass this function pointer to the <tt>def</tt> function, there is no way
to retrieve the default arguments:</p>
<code><pre>
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>); </span><span class=comment>// defaults lost!
</span></pre></code>
<p>
Because of this, when wrapping C++ code in earlier versions of
Boost.Python, we had to resort to writing thin wrappers:</p>
<code><pre>
<span class=comment>// write &quot;thin wrappers&quot;
</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><span class=comment>/*...*/
// in module init
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</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>&quot;f&quot;</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>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f1</span><span class=special>); </span><span class=comment>// one argument
</span></pre></code>
<p>
When you want to wrap functions (or member functions) that either:</p>
<ul><li>have default arguments, or</li><li>are overloaded with a common sequence of initial arguments</li></ul><p>
Boost.Python now has a way to make it easier.</p>
<p>
For instance, given a function:</p>
<code><pre>
<span class=keyword>int </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>b </span><span class=special>= </span><span class=number>1</span><span class=special>, </span><span class=keyword>unsigned </span><span class=identifier>c </span><span class=special>= </span><span class=number>2</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>d </span><span class=special>= </span><span class=number>3</span><span class=special>);
</span></pre></code>
<p>
The macro invocation:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>foo_overloads</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>4</span><span class=special>)
</span></pre></code>
<p>
Will automatically create the thin wrappers for us. This macro will create
a class <tt>foo_overloads</tt> that can be passed on to <tt>def(...)</tt>. The third
and fourth macro argument are the minimum arguments and maximum arguments,
respectively. In our <tt>foo</tt> function the minimum number of arguments is 1
and the maximum number of arguments is 4. The <tt>def(...)</tt> function will
automatically add all the foo variants for us:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
</span></pre></code>
<p>
A similar facility is provided for class constructors, again, with
default arguments or a sequence of overloads. Remember init&lt;...&gt;? For example,
given a class X with a constructor:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>X
</span><span class=special>{
</span><span class=identifier>X</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>b </span><span class=special>= </span><span class=literal>'D'</span><span class=special>, </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>c </span><span class=special>= </span><span class=string>&quot;constructor&quot;</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>d </span><span class=special>= </span><span class=number>0.0</span><span class=special>);
</span><span class=comment>/*...*/
</span><span class=special>}
</span></pre></code>
<p>
You can easily add this constructor to Boost.Python in one shot:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>, </span><span class=identifier>optional</span><span class=special>&lt;</span><span class=keyword>char</span><span class=special>, </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt; </span><span class=special>&gt;())
</span></pre></code>
<p>
Notice the use of <tt>init&lt;...&gt;</tt> and <tt>optional&lt;...&gt;</tt> to signify the default
(optional arguments).</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,117 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Derived Object types</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="basic_interface.html">
<link rel="next" href="extracting_c___objects.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Derived Object types</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="basic_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="extracting_c___objects.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Boost.Python comes with a set of derived <tt>object</tt> types corresponding to
that of Python's:</p>
<ul><li>list</li><li>dict</li><li>tuple</li><li>str</li><li>long_</li><li>enum</li></ul><p>
These derived <tt>object</tt> types act like real Python types. For instance:</p>
<code><pre>
<span class=identifier>str</span><span class=special>(</span><span class=number>1</span><span class=special>) </span><span class=special>==&gt; </span><span class=string>&quot;1&quot;
</span></pre></code>
<p>
Wherever appropriate, a particular derived <tt>object</tt> has corresponding
Python type's methods. For instance, <tt>dict</tt> has a <tt>keys()</tt> method:</p>
<code><pre>
<span class=identifier>d</span><span class=special>.</span><span class=identifier>keys</span><span class=special>()
</span></pre></code>
<p>
<tt>make_tuple</tt> is provided for declaring <i>tuple literals</i>. Example:</p>
<code><pre>
<span class=identifier>make_tuple</span><span class=special>(</span><span class=number>123</span><span class=special>, </span><span class=literal>'D'</span><span class=special>, </span><span class=string>&quot;Hello, World&quot;</span><span class=special>, </span><span class=number>0.0</span><span class=special>);
</span></pre></code>
<p>
In C++, when Boost.Python <tt>object</tt>s are used as arguments to functions,
subtype matching is required. For example, when a function <tt>f</tt>, as
declared below, is wrapped, it will only accept instances of Python's
<tt>str</tt> type and subtypes.</p>
<code><pre>
<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>&quot;upper&quot;</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>&quot;%s is bigger than %s&quot; </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></code>
<p>
In finer detail:</p>
<code><pre>
<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></pre></code>
<p>
Illustrates that we provide versions of the str type's methods as C++
member functions.</p>
<code><pre>
<span class=identifier>object </span><span class=identifier>msg </span><span class=special>= </span><span class=string>&quot;%s is bigger than %s&quot; </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></code>
<p>
Demonstrates that you can write the C++ equivalent of <tt>&quot;format&quot; % x,y,z</tt>
in Python, which is useful since there's no easy way to do that in std C++.</p>
<p>
<img src="theme/alert.gif"></img> <b>Beware</b> the common pitfall of forgetting that the constructors
of most of Python's mutable types make copies, just as in Python.</p>
<p>
Python:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </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=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
</span></pre></code>
<p>
C++:</p>
<code><pre>
<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>&quot;__dict__&quot;</span><span class=special>)); </span>#<span class=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span><span class=special>= </span><span class=number>3</span><span class=special>; </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
</span></pre></code>
<a name="class__lt_t_gt__as_objects"></a><h2>class_&lt;T&gt; as objects</h2><p>
Due to the dynamic nature of Boost.Python objects, any <tt>class_&lt;T&gt;</tt> may
also be one of these types! The following code snippet wraps the class
(type) object.</p>
<p>
We can use this to create wrapped instances. Example:</p>
<code><pre>
<span class=identifier>object </span><span class=identifier>vec345 </span><span class=special>= </span><span class=special>(
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Vec2</span><span class=special>&gt;(</span><span class=string>&quot;Vec2&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Point</span><span class=special>::</span><span class=identifier>length</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;angle&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Point</span><span class=special>::</span><span class=identifier>angle</span><span class=special>)
</span><span class=special>)(</span><span class=number>3.0</span><span class=special>, </span><span class=number>4.0</span><span class=special>);
</span><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>&quot;length&quot;</span><span class=special>) </span><span class=special>== </span><span class=number>5.0</span><span class=special>);
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="basic_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="extracting_c___objects.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,95 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Enums</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="extracting_c___objects.html">
<link rel="next" href="iterators.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Enums</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extracting_c___objects.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Boost.Python has a nifty facility to capture and wrap C++ enums. While
Python has no <tt>enum</tt> type, we'll often want to expose our C++ enums to
Python as an <tt>int</tt>. Boost.Python's enum facility makes this easy while
taking care of the proper conversions from Python's dynamic typing to C++'s
strong static typing (in C++, ints cannot be implicitly converted to
enums). To illustrate, given a C++ enum:</p>
<code><pre>
<span class=keyword>enum </span><span class=identifier>choice </span><span class=special>{ </span><span class=identifier>red</span><span class=special>, </span><span class=identifier>blue </span><span class=special>};
</span></pre></code>
<p>
the construct:</p>
<code><pre>
<span class=identifier>enum_</span><span class=special>&lt;</span><span class=identifier>choice</span><span class=special>&gt;(</span><span class=string>&quot;choice&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;red&quot;</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>&quot;blue&quot;</span><span class=special>, </span><span class=identifier>blue</span><span class=special>)
</span><span class=special>;
</span></pre></code>
<p>
can be used to expose to Python. The new enum type is created in the
current <tt>scope()</tt>, which is usually the current module. The snippet above
creates a Python class derived from Python's <tt>int</tt> type which is
associated with the C++ type passed as its first parameter.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/lens.gif"></img> <b>what is a scope?</b><br><br> The scope is a class that has an
associated global Python object which controls the Python namespace in
which new extension classes and wrapped functions will be defined as
attributes. Details can be found <a href="../../v2/scope.html">
here</a>. </td>
</tr>
</table>
<p>
You can access those values in Python as</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </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></code>
<p>
where my_module is the module where the enum is declared. You can also
create a new scope around a class:</p>
<code><pre>
<span class=identifier>scope </span><span class=identifier>in_X</span><span class=special>(</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>X</span><span class=special>&gt;(</span><span class=string>&quot;X&quot;</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>&lt;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>nested</span><span class=special>&gt;(</span><span class=string>&quot;nested&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;red&quot;</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>&quot;blue&quot;</span><span class=special>, </span><span class=identifier>blue</span><span class=special>)
</span><span class=special>;
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extracting_c___objects.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,60 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Exception Translation</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="iterators.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Exception Translation</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<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 handler that translates selected standard exceptions,
then gives up:</p>
<code><pre>
<span class=identifier>raise </span><span class=identifier>RuntimeError</span><span class=special>, </span><span class=literal>'unidentifiable C++ Exception'
</span></pre></code>
<p>
Users may provide custom translation. Here's an example:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>PodBayDoorException</span><span class=special>;
</span><span class=keyword>void </span><span class=identifier>translator</span><span class=special>(</span><span class=identifier>PodBayDoorException</span><span class=special>&amp; </span><span class=identifier>x</span><span class=special>) </span><span class=special>{
</span><span class=identifier>PyErr_SetString</span><span class=special>(</span><span class=identifier>PyExc_UserWarning</span><span class=special>, </span><span class=string>&quot;I'm sorry Dave...&quot;</span><span class=special>);
</span><span class=special>}
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>kubrick</span><span class=special>) </span><span class=special>{
</span><span class=identifier>register_exception_translator</span><span class=special>&lt;
</span><span class=identifier>PodBayDoorException</span><span class=special>&gt;(</span><span class=identifier>translator</span><span class=special>);
</span><span class=special>...
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,79 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Exposing Classes</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="building_hello_world.html">
<link rel="next" href="constructors.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Exposing Classes</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="building_hello_world.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="constructors.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Now let's expose a C++ class to Python.</p>
<p>
Consider a C++ class/struct that we want to expose to Python:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>World
</span><span class=special>{
</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>-&gt;</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></code>
<p>
We can expose this to Python by writing a corresponding Boost.Python
C++ Wrapper:</p>
<code><pre>
<span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>python</span><span class=special>;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>hello</span><span class=special>)
</span><span class=special>{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>World</span><span class=special>&gt;(</span><span class=string>&quot;World&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
</span><span class=special>;
</span><span class=special>}
</span></pre></code>
<p>
Here, we wrote a C++ class wrapper that exposes the member functions
<tt>greet</tt> and <tt>set</tt>. Now, after building our module as a shared library, we
may use our class <tt>World</tt> in Python. Here's a sample Python session:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>hello
</span><span class=special>&gt;&gt;&gt; </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>&gt;&gt;&gt; </span><span class=identifier>planet</span><span class=special>.</span><span class=identifier>set</span><span class=special>(</span><span class=literal>'howdy'</span><span class=special>)
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>planet</span><span class=special>.</span><span class=identifier>greet</span><span class=special>()
</span><span class=literal>'howdy'
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="building_hello_world.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="constructors.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,79 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Extracting C++ objects</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="derived_object_types.html">
<link rel="next" href="enums.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Extracting C++ objects</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="derived_object_types.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="enums.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
At some point, we will need to get C++ values out of object instances. This
can be achieved with the <tt>extract&lt;T&gt;</tt> function. Consider the following:</p>
<code><pre>
<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>&quot;length&quot;</span><span class=special>); </span><span class=comment>// compile error
</span></pre></code>
<p>
In the code above, we got a compiler error because Boost.Python
<tt>object</tt> can't be implicitly converted to <tt>double</tt>s. Instead, what
we wanted to do above can be achieved by writing:</p>
<code><pre>
<span class=keyword>double </span><span class=identifier>l </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt;(</span><span class=identifier>o</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>));
</span><span class=identifier>Vec2</span><span class=special>&amp; </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=identifier>Vec2</span><span class=special>&amp;&gt;(</span><span class=identifier>o</span><span class=special>);
</span><span class=identifier>assert</span><span class=special>(</span><span class=identifier>l </span><span class=special>== </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>length</span><span class=special>());
</span></pre></code>
<p>
The first line attempts to extract the &quot;length&quot; attribute of the
Boost.Python <tt>object</tt> <tt>o</tt>. The second line attempts to <i>extract</i> the
<tt>Vec2</tt> object from held by the Boost.Python <tt>object</tt> <tt>o</tt>.</p>
<p>
Take note that we said &quot;attempt to&quot; above. What if the Boost.Python
<tt>object</tt> <tt>o</tt> does not really hold a <tt>Vec2</tt> type? This is certainly
a possibility considering the dynamic nature of Python <tt>object</tt>s. To
be on the safe side, if the C++ type can't be extracted, an
appropriate exception is thrown. To avoid an exception, we need to
test for extractibility:</p>
<code><pre>
<span class=identifier>extract</span><span class=special>&lt;</span><span class=identifier>Vec2</span><span class=special>&amp;&gt; </span><span class=identifier>x</span><span class=special>(</span><span class=identifier>o</span><span class=special>);
</span><span class=keyword>if </span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>check</span><span class=special>()) </span><span class=special>{
</span><span class=identifier>Vec2</span><span class=special>&amp; </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>x</span><span class=special>(); </span><span class=special>...
</span></pre></code>
<p>
<img src="theme/bulb.gif"></img> The astute reader might have noticed that the <tt>extract&lt;T&gt;</tt>
facility in fact solves the mutable copying problem:</p>
<code><pre>
<span class=identifier>dict </span><span class=identifier>d </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=identifier>dict</span><span class=special>&gt;(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;__dict__&quot;</span><span class=special>));
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span><span class=special>= </span><span class=number>3</span><span class=special>; </span>#<span class=identifier>modifies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__ </span><span class=special>!
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="derived_object_types.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="enums.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,73 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_operators_special_functions.html">
<link rel="next" href="call_policies.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Functions</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_operators_special_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="call_policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
In this chapter, we'll look at Boost.Python powered functions in closer
detail. We shall see some facilities to make exposing C++ functions to
Python safe from potential pifalls such as dangling pointers and
references. We shall also see facilities that will make it even easier for
us to expose C++ functions that take advantage of C++ features such as
overloading and default arguments.</p>
<blockquote><p><i>Read on...</i></p></blockquote><p>
But before you do, you might want to fire up Python 2.2 or later and type
<tt>&gt;&gt;&gt; import this</tt>.</p>
<code><pre>
&gt;&gt;&gt; import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
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 *right* 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></code><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_operators_special_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="call_policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,98 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Inheritance</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_properties.html">
<link rel="next" href="class_virtual_functions.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Inheritance</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_properties.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_virtual_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
In the previous examples, we dealt with classes that are not polymorphic.
This is not often the case. Much of the time, we will be wrapping
polymorphic classes and class hierarchies related by inheritance. We will
often have to write Boost.Python wrappers for classes that are derived from
abstract base classes.</p>
<p>
Consider this trivial inheritance structure:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base </span><span class=special>{ </span><span class=keyword>virtual </span><span class=special>~</span><span class=identifier>Base</span><span class=special>(); </span><span class=special>};
</span><span class=keyword>struct </span><span class=identifier>Derived </span><span class=special>: </span><span class=identifier>Base </span><span class=special>{};
</span></pre></code>
<p>
And a set of C++ functions operating on <tt>Base</tt> and <tt>Derived</tt> object
instances:</p>
<code><pre>
<span class=keyword>void </span><span class=identifier>b</span><span class=special>(</span><span class=identifier>Base</span><span class=special>*);
</span><span class=keyword>void </span><span class=identifier>d</span><span class=special>(</span><span class=identifier>Derived</span><span class=special>*);
</span><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></code>
<p>
We've seen how we can wrap the base class <tt>Base</tt>:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
</span><span class=comment>/*...*/
</span><span class=special>;
</span></pre></code>
<p>
Now we can inform Boost.Python of the inheritance relationship between
<tt>Derived</tt> and its base class <tt>Base</tt>. Thus:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Derived</span><span class=special>, </span><span class=identifier>bases</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>&gt; </span><span class=special>&gt;(</span><span class=string>&quot;Derived&quot;</span><span class=special>)
</span><span class=comment>/*...*/
</span><span class=special>;
</span></pre></code>
<p>
Doing so, we get some things for free:</p>
<ol><li>Derived automatically inherits all of Base's Python methods (wrapped C++ member functions)</li><li><b>If</b> Base is polymorphic, <tt>Derived</tt> objects which have been passed to Python via a pointer or reference to <tt>Base</tt> can be passed where a pointer or reference to <tt>Derived</tt> is expected.</li></ol><p>
Now, we shall expose the C++ free functions <tt>b</tt> and <tt>d</tt> and <tt>factory</tt>:</p>
<code><pre>
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;b&quot;</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>&quot;d&quot;</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>&quot;factory&quot;</span><span class=special>, </span><span class=identifier>factory</span><span class=special>);
</span></pre></code>
<p>
Note that free function <tt>factory</tt> is being used to generate new
instances of class <tt>Derived</tt>. In such cases, we use
<tt>return_value_policy&lt;manage_new_object&gt;</tt> to instruct Python to adopt
the pointer to <tt>Base</tt> and hold the instance in a new Python <tt>Base</tt>
object until the the Python object is destroyed. We shall see more of
Boost.Python <a href="call_policies.html">
call policies</a> later.</p>
<code><pre>
<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>&quot;factory&quot;</span><span class=special>, </span><span class=identifier>factory</span><span class=special>,
</span><span class=identifier>return_value_policy</span><span class=special>&lt;</span><span class=identifier>manage_new_object</span><span class=special>&gt;());
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_properties.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_virtual_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,101 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Iterators</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="enums.html">
<link rel="next" href="exception_translation.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Iterators</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
In C++, and STL in particular, we see iterators everywhere. Python also has
iterators, but these are two very different beasts.</p>
<p>
<b>C++ iterators:</b></p>
<ul><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></ul><p>
<b>Python Iterators:</b></p>
<ul><li>1 category (forward)</li><li>1 operation category (next())</li><li>Raises StopIteration exception at end</li></ul><p>
The typical Python iteration protocol: <tt><b>for y in x...</b></tt> is as follows:</p>
<code><pre>
<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=identifier>get </span><span class=identifier>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=identifier>get </span><span class=identifier>each </span><span class=identifier>item
</span><span class=special>... </span>#<span class=identifier>process </span><span class=identifier>y
</span><span class=identifier>except </span><span class=identifier>StopIteration</span><span class=special>: </span><span class=identifier>pass </span>#<span class=identifier>iterator </span><span class=identifier>exhausted
</span></pre></code>
<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 __iter__ function from C++ iterators that is compatible
with the Python iteration protocol. For example:</p>
<code><pre>
<span class=identifier>object </span><span class=identifier>get_iterator </span><span class=special>= </span><span class=identifier>iterator</span><span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; </span><span class=special>&gt;();
</span><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></pre></code>
<p>
Or for use in class_&lt;&gt;:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;__iter__&quot;</span><span class=special>, </span><span class=identifier>iterator</span><span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; </span><span class=special>&gt;())
</span></pre></code>
<p>
<b>range</b></p>
<p>
We can create a Python savvy iterator using the range function:</p>
<ul><li>range(start, finish)</li><li>range&lt;Policies,Target&gt;(start, finish)</li></ul><p>
Here, start/finish may be one of:</p>
<ul><li>member data pointers</li><li>member function pointers</li><li>adaptable function object (use Target parameter)</li></ul><p>
<b>iterator</b></p>
<ul><li>iterator&lt;T, Policies&gt;()</li></ul><p>
Given a container <tt>T</tt>, iterator is a shortcut that simply calls <tt>range</tt>
with &amp;T::begin, &amp;T::end.</p>
<p>
Let's put this into action... Here's an example from some hypothetical
bogon Particle accelerator code:</p>
<code><pre>
<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=identifier>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><span class=keyword>for </span><span class=identifier>y </span><span class=identifier>in </span><span class=identifier>f</span><span class=special>.</span><span class=identifier>bogons</span><span class=special>:
</span><span class=identifier>count</span><span class=special>(</span><span class=identifier>y</span><span class=special>)
</span></pre></code>
<p>
Now, our C++ Wrapper:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>F</span><span class=special>&gt;(</span><span class=string>&quot;Field&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>property</span><span class=special>(</span><span class=string>&quot;pions&quot;</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>p_begin</span><span class=special>, </span><span class=special>&amp;</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>&quot;bogons&quot;</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_begin</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_end</span><span class=special>));
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,54 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Object Interface</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="default_arguments.html">
<link rel="next" href="basic_interface.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Object Interface</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<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>object</tt>. We shall see in
this chapter how to deal with Python objects.</p>
<p>
As mentioned, one of the goals of Boost.Python is to provide a
bidirectional mapping between C++ and Python while maintaining the Python
feel. Boost.Python C++ <tt>object</tt>s are as close as possible to Python. This
should minimize the learning curve significantly.</p>
<p>
<img src="theme/python.png"></img></p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,79 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>QuickStart</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="next" href="building_hello_world.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>QuickStart</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
<td width="20"><a href="building_hello_world.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
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. It is designed to wrap C++ interfaces
non-intrusively, so that you should not have to change the C++ code at
all in order to wrap it, making Boost.Python ideal for exposing
3rd-party libraries to Python. The library's use of advanced
metaprogramming techniques simplifies its syntax for users, so that
wrapping code takes on the look of a kind of declarative interface
definition language (IDL).</p>
<a name="hello_world"></a><h2>Hello World</h2><p>
Following C/C++ tradition, let's start with the &quot;hello, world&quot;. A C++
Function:</p>
<code><pre>
<span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>greet</span><span class=special>()
</span><span class=special>{
</span><span class=keyword>return </span><span class=string>&quot;hello, world&quot;</span><span class=special>;
</span><span class=special>}
</span></pre></code>
<p>
can be exposed to Python by writing a Boost.Python wrapper:</p>
<code><pre>
<span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>python</span><span class=special>;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>hello</span><span class=special>)
</span><span class=special>{
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=identifier>greet</span><span class=special>);
</span><span class=special>}
</span></pre></code>
<p>
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>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>hello
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>hello</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></code>
<blockquote><p><i><b>Next stop... Building your Hello World module from start to finish...</b></i></p></blockquote><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
<td width="20"><a href="building_hello_world.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 879 B

View File

@@ -1,170 +0,0 @@
body
{
background-image: url(bkd.gif);
background-color: #FFFFFF;
margin: 1em 2em 1em 2em;
}
h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; }
h2 { font: 140% sans-serif; font-weight: bold; text-align: left; }
h3 { font: 120% sans-serif; font-weight: bold; text-align: left; }
h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; }
h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; }
h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; }
pre
{
border-top: gray 1pt solid;
border-right: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
padding-top: 2pt;
padding-right: 2pt;
padding-left: 2pt;
padding-bottom: 2pt;
display: block;
font-family: "courier new", courier, mono;
background-color: #eeeeee; font-size: small
}
code
{
font-family: "Courier New", Courier, mono;
font-size: small
}
tt
{
display: inline;
font-family: "Courier New", Courier, mono;
color: #000099;
font-size: small
}
p
{
text-align: justify;
font-family: Georgia, "Times New Roman", Times, serif
}
ul
{
list-style-image: url(bullet.gif);
font-family: Georgia, "Times New Roman", Times, serif
}
ol
{
font-family: Georgia, "Times New Roman", Times, serif
}
a
{
font-weight: bold;
color: #003366;
text-decoration: none;
}
a:hover { color: #8080FF; }
.literal { color: #666666; font-style: italic}
.keyword { color: #000099}
.identifier {}
.comment { font-style: italic; color: #990000}
.special { color: #800040}
.preprocessor { color: #FF0000}
.string { font-style: italic; color: #666666}
.copyright { color: #666666; font-size: small}
.white_bkd { background-color: #FFFFFF}
.dk_grey_bkd { background-color: #999999}
.quotes { color: #666666; font-style: italic; font-weight: bold}
.note_box
{
display: block;
border-top: gray 1pt solid;
border-right: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
padding-right: 12pt;
padding-left: 12pt;
padding-bottom: 12pt;
padding-top: 12pt;
font-family: Arial, Helvetica, sans-serif;
background-color: #E2E9EF;
font-size: small; text-align: justify
}
.table_title
{
background-color: #648CCA;
font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF;
font-weight: bold
; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px
}
.table_cells
{
background-color: #E2E9EF;
font-family: Geneva, Arial, Helvetica, san-serif;
font-size: small
; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px
}
.toc
{
DISPLAY: block;
background-color: #E2E9EF
font-family: Arial, Helvetica, sans-serif;
border-top: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
border-right: gray 1pt solid;
padding-top: 24pt;
padding-right: 24pt;
padding-left: 24pt;
padding-bottom: 24pt;
}
.toc_title
{
background-color: #648CCA;
padding-top: 4px;
padding-right: 4px;
padding-bottom: 4px;
padding-left: 4px;
font-family: Geneva, Arial, Helvetica, san-serif;
color: #FFFFFF;
font-weight: bold
}
.toc_cells
{
background-color: #E2E9EF;
padding-top: 4px;
padding-right: 4px;
padding-bottom: 4px;
padding-left: 4px;
font-family: Geneva, Arial, Helvetica, san-serif;
font-size: small
}
div.logo
{
float: right;
}
.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

View File

@@ -1,126 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Boost Python Tutorial</title>
<link rel="stylesheet" href="doc/theme/style.css" type="text/css">
<link rel="next" href="quickstart.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="doc/theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Boost Python Tutorial</b></font>
</td>
</tr>
</table>
<br>
<table width="80%" border="0" align="center">
<tr>
<td class="toc_title">Table of contents</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/quickstart.html">QuickStart</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/building_hello_world.html">Building Hello World</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/exposing_classes.html">Exposing Classes</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/constructors.html">Constructors</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/class_data_members.html">Class Data Members</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/class_properties.html">Class Properties</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/inheritance.html">Inheritance</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/class_virtual_functions.html">Class Virtual Functions</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/class_operators_special_functions.html">Class Operators/Special Functions</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/functions.html">Functions</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/call_policies.html">Call Policies</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/default_arguments.html">Default Arguments</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/object_interface.html">Object Interface</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/basic_interface.html">Basic Interface</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/derived_object_types.html">Derived Object types</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/extracting_c___objects.html">Extracting C++ objects</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/enums.html">Enums</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/iterators.html">Iterators</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/exception_translation.html">Exception Translation</a>
</td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,163 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - April 2002 Progress Report</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">April 2002 Progress Report</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="#accomplishments">Accomplishments</a></dt>
<dl class="index">
<dt><a href="#arity">Arbitrary Arity Support</a></dt>
<dt><a href="#callbacks">New Callback Interface</a></dt>
<dt><a href="#policies">Call Policies for Construtors</a></dt>
<dt><a href="#bugs">Real Users, Real Bugs</a></dt>
<dt><a href="#insights">New Insights</a></dt>
<dt><a href="#v1">Boost.Python V1 Maintenance</a></dt>
</dl>
<dt><a href="#missing">What's Missing</a></dt>
</dl>
<h2><a name="accomplishments">Accomplishments</a></h2>
April was a short month as far as Boost.Python was concerned, since
the spring ISO C++ Committee Meeting (and associated vacation)
occupied me for the 2nd half of the month. However, a suprising amount
of work got done...
<h3><a name="arity">Arbitrary Arity Support</a></h3>
I began using the <a
href="../../../preprocessor/doc/index.htm">Boost.Preprocessor</a>
metaprogramming library to generate support for functions and member
functions of arbitrary arity, which was, to say the least, quite an
adventure. The feedback cycle resulting from my foray into
Boost.Preprocessor resulted in several improvements to the library,
most notably in its documentation.
<p>
Boost.Python now supports calls of up to 17 arguments on most
compilers. Because most EDG-based compilers have dismal preprocessor
performance, I had to &quot;manually&quot; expand the metaprograms for
arities from zero to fifteen arguments, and EDG-based compilers with
<code>__EDG_VERSION__&nbsp;&lt;=&nbsp;245</code> only support 15
arguments by default. If some crazy program finds a need for more than
the default arity support, users can increase the base support by
setting the <code>BOOST_PYTHON_MAX_ARITY</code> preprocessor symbol.
<h3><a name="callbacks">New Callback Interface</a></h3>
I mentioned in <a href="Mar2002.html">last month's report</a> that I
wasn't pleased with the interface for the interface for calling into
Python, so now it has been redesigned. The new interface is outlined
in <a
href="http://mail.python.org/pipermail/c++-sig/2002-April/000953.html">this
message</a> (though the GCC 2.95.3 bugs have been fixed).
<h3><a name="policies">Call Policies for Constructors</a></h3>
On April 2nd, I <a
href="http://mail.python.org/pipermail/c++-sig/2002-April/000916.html">announced</a>
support for the use of call policies with constructors.
<h3><a name="bugs">Real Users, Real Bugs</a></h3>
At least two people outside of Kull began actually using Boost.Python
v2 in earnest this month. Peter Bienstman and Pearu Pearson both
provided valuable real-world bug reports that helped me to improve the
library's robustness.
<h3><a name="insights">New Insights</a></h3>
<a
href="http://mail.python.org/pipermail/c++-sig/2002-May/001010.html"
>Answering some of Pearu's questions</a> about explicitly converting
objects between Python and C++ actually led me to a new understanding
of the role of the current conversion facilities. In Boost.Python v1,
all conversions between Python and C++ were handled by a single family
of functions, called <code>to_python()</code> and
<code>from_python()</code>. Since the primary role of Boost.Python is
to wrap C++ functions in Python, I used these names for the first kind
of converters I needed: those that extract C++ objects to be used as
function arguments and which C++ function return values to
Python. The better-considered approach in Boost.Python v2 uses a
completely different mechanism for conversions used when calling
Python from C++, as in wrapped virtual function implementations. I
usually think of this as a &quot;callback&quot;, as in &quot;calling
back into Python&quot;, and I named the converters used in callbacks
accordingly: <code>to_python_callback</code> and
<code>from_python_callback</code>. However, as it turns out, the
behavior of the &quot;callback&quot; converters is the appropriate one
for users who want to explicitly extract a C++ value from a Python
object, or create a Python object from a C++ value. The upshot is that
it probably makes sense to change the name of the existing <code>to_python</code> and
<code>from_python</code> so those names are available for the
user-friendly explicit converters.
<p>
<a
href="http://mail.python.org/pipermail/c++-sig/2002-May/001013.html">Another
of Pearu's questions</a> pushes momentum further in the direction of a
more-sophisticated overloading mechanism than the current
simple-minded &quot;first match&quot; approach, as I suggested <a
href="Mar2002.html#implicit_conversions">last month</a>.
<h3><a name="v1">Boost.Python V1 Maintenance</a></h3>
As much as I'm looking forward to retiring Boost.Python v1, a
significant amount of effort has been being spent dealing with support
problems; the saying that code rots when left alone is true, and
Boost.Python is no exception. Eventually it became obvious to me that
we were going to have to invest some effort in keeping V1 healthy
while working on V2. Ralf and I have expanded support for various
compilers and stabilized the V1 codebase considerably. We discarded
the obsolete Visual Studio projects which were causing so much
confusion. Still to do before the next Boost release:
<ol>
<li>Update the build/test documentation with detailed instructions for
configuring various toolsets.
<li>Provide some links to Boost.Python v2 to let people know what's
coming.
</ol>
<h2><a name="missing">What's Missing</a></h2>
Last month I announced that I would implement the following which are
not yet complete:
<ol>
<li>Document all implemented features
<li>Implement conversions for <code>char</code> types. This is
implemented but not tested, so we have to assume it doesn't work.
</ol>
These are my first priority for this month (especially the
documentation).
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,153 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Python - CallPolicies Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">CallPolicies Concept</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#composition">CallPolicies Composition</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#CallPolicies-concept">CallPolicies Concept</a></dt>
</dl>
</dd>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>Models of the CallPolicies concept are used to specialize the behavior
of Python callable objects generated by Boost.Python to wrapped C++
objects like function and member function pointers, providing three
behaviors:</p>
<ol>
<li><code>precall</code> - Python argument tuple management before the
wrapped object is invoked</li>
<li><code>result_converter</code> - C++ return value handling</li>
<li><code>postcall</code> - Python argument tuple and result management
after the wrapped object is invoked</li>
</ol>
<h2><a name="composition"></a>CallPolicies Composition</h2>
In order to allow the use of multiple models of CallPolicies in the same
callable object, Boost.Python's CallPolicies class templates provide a
chaining interface which allows them to be recursively composed. This
interface takes the form of an optional template parameter,
<code>Base</code> which defaults to <a href=
"default_call_policies.html#default_call_policies-spec"><code>default_call_policies</code></a>.
By convention, the <code>precall</code> function of the <code>Base</code>
is invoked <i>after</i> the <code>precall</code> function supplied by the
outer template, and the <code>postcall</code> function of the
<code>Base</code> is invoked <i>before</i> the <code>postcall</code>
function of the outer template. If a <code>result_converter</code> is
supplied by the outer template, it <i>replaces</i> any
<code>result_converter</code> supplied by the <code>Base</code>. For an
example, see <a href=
"return_internal_reference.html#return_internal_reference-spec"><code>return_internal_reference</code></a>.
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="CallPolicies-concept"></a>CallPolicies Concept</h3>
<p>In the table below, <code><b>x</b></code> denotes an object whose type
<code><b>P</b></code> is a model of CallPolicies, <code><b>a</b></code>
denotes a <code>PyObject*</code> pointing to a Python argument tuple
object, and <code><b>r</b></code> denotes a <code>PyObject*</code>
referring to a "preliminary" result object.</p>
<table summary="CallPolicies expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Type</b></td>
<td><b>Result/Semantics</b></td>
</tr>
<tr>
<td valign="top"><code>x.precall(a)</code></td>
<td>convertible to <code>bool</code></td>
<td>returns <code>false</code> and <code><a href=
"http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>
upon failure, <code>true</code> otherwise.</td>
</tr>
<tr>
<td valign="top"><code>P::result_converter</code></td>
<td>A model of <a href=
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>.</td>
<td>An MPL unary <a href=
"../../../mpl/doc/paper/html/usage.html#metafunctions.classes">Metafunction
Class</a> used produce the "preliminary" result object.</td>
</tr>
<tr>
<td valign="top"><code>x.postcall(a, r)</code></td>
<td>convertible to <code>PyObject*</code></td>
<td>0 <code>0</code> and <code><a href=
"http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>
upon failure. Must "conserve references" even in the event of an
exception. In other words, if <code>r</code> is not returned, its
reference count must be decremented; if another existing object is
returned, its reference count must be incremented.</td>
</tr>
</table>
Models of CallPolicies are required to be <a href=
"../../../utility/CopyConstructible.html">CopyConstructible</a>.
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
<p>Permission to copy, use, modify, sell and distribute this software is
granted provided this copyright notice appears in all copies. This
software is provided "as is" without express or implied warranty, and
with no claim as to its suitability for any purpose.</p>
</body>
</html>

View File

@@ -1,66 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Python - Dereferenceable Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Dereferenceable Concept</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dl class="page-index">
<dt><a href="#Dereferenceable-concept">Dereferenceable Concept</a></dt>
</dl>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>Instances of a dereferenceable type can be used like a pointer to access an lvalue.
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="Dereferenceable-concept"></a>Dereferenceable Concept</h3>
<p>In the table below, <code><b>x</b></code> denotes an object whose
type is a model of Dereferenceable.
<table summary="Dereferenceable expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Requirements</b></td>
</tr>
<tr>
<td valign="top"><code>*x</code></td>
<td>An lvalue
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>
<p>Permission to copy, use, modify, sell
and distribute this software is granted provided this copyright notice appears
in all copies. This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
</body>
</html>

View File

@@ -1,93 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Python - Extractor Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Extractor Concept</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dl class="page-index">
<dt><a href="#Extractor-concept">Extractor Concept</a></dt>
</dl>
<dt><a href="#notes">Notes</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>An Extractor is a class which Boost.Python can use to extract C++
objects from Python objects, and is typically used by facilities that
define <code>from_python</code> conversions for
&quot;traditional&quot; Python extension types.
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="Extractor-concept"></a>Extractor Concept</h3>
<p>In the table below, <code><b>X</b></code> denotes a model of
Extractor and <code><b>a</b></code> denotes an instance of a Python
object type.
<table summary="Extractor expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Type</b></td>
<td><b>Semantics</b></td>
</tr>
<tr>
<td valign="top"><code>X::execute(a)</code></td>
<td>non-void
<td>Returns the C++ object being extracted. The
<code>execute</code> function must not be overloaded.
</tr>
<tr>
<td valign="top"><code>&amp;a.ob_type</code>
<td><code><a
href="http://www.python.org/doc/2.2/ext/dnt-type-methods.html">PyTypeObject</a>**</code>
<td>Points to the <code>ob_type</code> field of an object which is
layout-compatible with <code>PyObject</code>
</tr>
</tr>
</table>
<h2><a name="notes"></a>Notes</h2>
Informally, an Extractor's <code>execute</code> member must be a
non-overloaded static function whose single argument is a Python
object type. Acceptable Python object types include those publicly (and
unambiguously) derived from <code>PyObject</code>, and POD types which
are layout-compatible with PyObject.
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>
<p>Permission to copy, use, modify, sell
and distribute this software is granted provided this copyright notice appears
in all copies. This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
</body>
</html>

View File

@@ -1,71 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Python - Holder Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">HolderGenerator Concept</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dl class="page-index">
<dt><a href="#HolderGenerator-concept">HolderGenerator Concept</a></dt>
</dl>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>A HolderGenerator is a unary metafunction class which returns types
suitable for holding instances of its argument in a wrapped C++ class
instance.
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="HolderGenerator-concept"></a>HolderGenerator Concept</h3>
<p>In the table below, <code><b>G</b></code> denotes an type which
models HolderGenerator, and <code><b>X</b></code> denotes a class
type.
<table summary="Holder expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Requirements</b></td>
</tr>
<tr>
<td valign="top"><code>G::apply&lt;X&gt;::type</code></td>
<td>A concrete subclass of <a
href="instance_holder.html#instance_holder-spec">instance_holder</a>
which can hold objects of type <code>X</code>.
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>
<p>Permission to copy, use, modify, sell
and distribute this software is granted provided this copyright notice appears
in all copies. This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
</body>
</html>

View File

@@ -1,226 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - June 2002 Progress Report</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">June 2002 Progress Report</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="#intro">Introduction</a></dt>
<dt><a href="#handle"><code>handle&lt;T&gt;</code></a></dt>
<dt><a href="#object"><code>object</code></a></dt>
<dl class="index">
<dt><a href="#operators"><code>object</code> operators</a></dt>
<dt><a href="#conversions"><code>object</code> conversions</a></dt>
</dl>
<dt><a href="#list"><code>list</code></a></dt>
<dt><a href="#numerics"><code>Numerics</code></a></dt>
<dt><a href="#community">Community</a></dt>
<dt><a href="#next">What's Next</a></dt>
</dl>
<h2><a name="intro">Introduction</a></h2>
July was mostly focused on allowing expressive manipulation of
individual Python objects, or what Ralf Grosse-Kunstleve calls
&quot;Writing Python in C++&quot;. The work began with this <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001311.html">posting</a>,
which outlines the issues and intention.
<h2><a name="handle"><code>handle&lt;T&gt;</code></a></h2>
The most basic element needed was a replacement for the
<code>reference&lt;&gt;</code> class template and the
<code>ref</code> typedef from Boost.Python v1, a simple smart
pointer to a Python object. The old v1 typedef
&quot;<code>ref</code>&quot; (for
<code>reference&lt;PyObject&gt;</code>) had to be retired because I
thought it would be too confusing given the importance of <code><a
href="../../../bind/ref.html">boost::ref</a>()</code> to this
library. I began a <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001311.html">discussion</a>of
possible names, and it was eventually <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001337.html">decided</a>
to rename <code>reference</code> to <code>handle</code> and supply a
default argument so that <code>ref</code> could be spelled
<code>handle&lt;&gt;</code> without an additional typedef. There
were also some interface changes to make it safer and more-efficient
to interface with the raw
<code>PyObject*</code>s forced on us by Python's 'C' API. A
discussion of those protocols can be found <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001401.html">here</a>.
<h2><a name="handle"><code>object</code></a></h2>
It is intended that users will seldom need or want to work with
<code>handle&lt;&gt;</code>; its major distinguishing features are
that it gives direct access to the underlying object representation
through <code>operator*</code> and <code>operator-&gt;</code>, and
that can be <code>NULL</code>, both sources of danger. Instead the
library provides a class called <code>object</code>, which
encapsulates a valid Python object and provides a similar interface to
Python's.
<h3><a name="operators"><code>object</code> operators</a></h3>
The first challenge was to provide support for object manipulations
using a Python-like syntax, mostly in the form of operator overloads:
<table border="1">
<tr><th>Python <th>C++
<tr>
<td><code>y = x.foo</code> <td><code>y = x.attr(&quot;foo&quot;);
<tr>
<td><code>x.foo = 1</code> <td><code>x.attr(&quot;foo&quot;) = 1;
<tr>
<td><code>y = x[z]</code> <td><code>y = x[z];
<tr>
<td><code>x[z] = 1</code> <td><code>x[z] = 1;
<tr>
<td><code>y = x[3:-1]</code> <td><code>y = x.slice(3,-1);
<tr>
<td><code>y = x[3:]</code> <td><code>y = x.slice(3,_);
<tr>
<td><code>y = x[:-2]</code> <td><code>y = x.slice(_,-2);
<tr>
<td><code>z = x(1, y)</code> <td><code>z = x(1, y);
<tr>
<td><code>z = x.f(1, y)</code> <td><code>z = x.attr(&quot;f&quot;)(1, y);
<tr>
<td><code>not x</code> <td><code>!x
<tr>
<td><code>x and y</code> <td><code>x and y
</table>
I'm still a unsatisfied with the interface for attribute access. There
original proposal used a syntax like this one:
<pre>
y = x._(&quot;foo&quot;);
x._(&quot;foo&quot;) = 1;
</pre>
which was only marginally better than what we've got. Niki Spahiev
then <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001447.html">pointed
out</a> a potential conflict with the macro which GNU Gettext <a
href="http://www.gnu.org/manual/gettext/html_mono/gettext.html#SEC6">suggests</a>
people define. This unfortunate state of affairs forced us into using
<code>attr</code> instead. I'd still like to find a better interface,
but the lack of overloadable C++ operators which aren't already used
in Python is an obstacle. The comma operator is still a possibility,
but it has the wrong precedence:
<pre>
y = x,&quot;foo&quot; // error
x,&quot;foo&quot; = 1; // error
y = (x,&quot;foo&quot;); // ok
(x,&quot;foo&quot;) = 1; // ok
</pre>
Well, I guess we could consider adding that to the interface without
removing <code>attr()</code>, to see how it plays out...
<h3><a name="operators"><code>object</code> conversions</a></h3>
The <code>object</code> class also provided an opportunity to replace
Boost.Python v1's <code>to_python()</code> as a user-level
interface. Instead, <code>object</code> has a templated constructor
which can be used to convert any C++ object to Python using the same
underlying mechanisms used for the arguments to <code><a
href="call.html">call</a>&lt;&gt;</code>.
<p>Incidentally, the implementation of operator and conversion support
for object uncovered an inordinate number of compiler bugs in our
targeted platforms. It was a lot more &quot;interesting&quot; than it
should have been.
<h2><a name="list"><code>list</code></a></h2>
With <code>object</code> implemented, it was time to begin replacing
the ad-hoc implementations of <code>list</code>, <code>string</code>,
and <code>dictionary</code> supplied by Boost.Python v1 with something
more robust. I started with <code>list</code> as an example. Because
<code>object</code> already provides all of the requisite operators,
publicly deriving <code>list</code> from object seemed like a good
choice. The remaining issues were what do do about the one-argument
list constructor (which in Python attempts to convert its argument to
a list), and how to deal converting with <code>list</code> arguments
to wrapped functions. Some of the issues are laid out in <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001551.html">this
thread</a>. Ultimately, it was decided that <code>list(x)</code>
should do the same thing in C++ as in Python (conversion), while
<code>list</code> arguments should only match Python
<code>list</code>s (and <code>list</code> subclasses). The
implementation worked well, and provided a <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001586.html">roadmap</a>
for the protocol to be used for implementation of the other built-in
types.
<h2><a name="numerics">Numerics</a></h2>
Support for C++ <code>long long</code> and <code>unsigned long
long</code>
(and <code>__int64</code> on MSVC) to/from python conversions was
added this month. We also improved handling of numeric overflows when
converting, e.g., a Python int to a type with a more limited range of
representation.
<h2><a name="community">Community</a></h2>
<ul>
<li>Ralf W. Grosse-Kunstleve and Nick Sauter have implemented
<a href="http://cci.lbl.gov/boost/">multiplatform nightly
build-and-test</a> runs for Boost.Python V2 at LBL.
<li>Dave Hawkes has made significant progress on generating the
Python <a
href="http://mail.python.org/pipermail/c++-sig/2002-June/001503.html">built-in
function and API wrappers</a>
<li>Achim Domma has agreed to take up the job of implementing the
<code>str</code>, <code>dict</code>, and <code>tuple</code> classes.
</ul>
Deep thanks to all the Boost.Python contributors! This project
wouldn't be possible without your participation.
<h2><a name="next">What's Next</a></h2>
As I write this we are already well into the month of July, so I
suggest you consult the <a
href="http://mail.python.org/pipermail/c++-sig/2002-July/">Mailing
List Archive</a> if you want to know what's been happening. Otherwise
you'll just have to wait till next month (hopefully the beginning).
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,234 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - March 2002 Progress Report</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">March 2002 Progress Report</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="#accomplishments">Accomplishments</a></dt>
<dl class="index">
<dt><a href="#calling_python">Calling Python from C++</a></dt>
<dt><a href="#virtual_functions">Virtual Functions</a></dt>
<dt><a href="#abstract_classes">Abstract Classes</a></dt>
<dt><a href="#implicit_conversions">C++ Implicit Conversions</a></dt>
<dt><a href="#data_members">C++ Data Members</a></dt>
<dt><a href="#miscellaneous">Miscellaneous</a></dt>
</dl>
<dt><a href="#future">The Near future</a></dt>
<dt><a href="#notes">Notes</a></dt>
</dl>
<h2><a name="accomplishments">Accomplishments</a></h2>
March was mostly devoted to the reimplementation of features from
Boost.Python v1, and some new features. Re-examination of the features
from Boost.Python v1 allowed me to make significant improvements.
<h3><a name="calling_python">Calling Python from C++</a></h3>
The ability to call Python from C++ is crucial for virtual function
support. Implementing this feature well for V2 proved to be more
interesting than I expected. You can review most of the relevant
design decisions
<a href="callbacks.txt">here</a>.
<p>
One point which <i>isn't</i> emphasized in that document is that there
are subtle differences in the way <code>from_python</code> conversions
work when used for C++ function arguments and Python function return
values. In particular, while <code>T const&amp;</code> arguments may
invoke rvalue converters, a reference-to-const return value requires
an lvalue converter, since a temporary conversion result would leave
the returned reference dangling.
<p>I'm not particularly pleased with the current callback interface,
since it usually results in constructs like:
<pre>
<u>return returning</u>&lt;X&amp;&gt;::call(f, obj);
</pre>
However, I think the following may be possible and I plan to investigate:
<pre>
return apply&lt;X&amp;&gt;(f, obj);
</pre>
I'm open to suggestion for better names (and syntaxes)!
<h3><a name="virtual_functions">Virtual Functions</a></h3>
Once Python callbacks were implemented, it was just a short step to
implementing virtual functions. Python extension class exposing a C++
class whose virtual functions are overridable in Python must actually
hold a C++ instance of a class <i>derived</i> from the one exposed to
Python. Needing some way for users to specify that class, I added an
optional template argument to <code>value_holder_generator</code> and
<code>pointer_holder_generator&lt;&gt;</code> to specify the class
actually held. This move began to put pressure on the
<code>class_&lt;&gt;</code> interface, since the need for the user to
produce complicated instantations of
<code>class_&lt;&gt;</code> was increased:
<pre>
class&lt;Foo, bases&lt;&gt;, value_holder_generator&lt;Foo_callback&gt; &gt;(&quot;Foo&quot;)
.def(&quot;hello&quot;, &amp;Foo::hello)
...
</pre>
<h3><a name="abstract_classes">Abstract Classes</a></h3>
Normally when a C++ class is exposed to Python, the library registers
a conversion function which allows users to wrap functions returning
values of that type. Naturally, these return values are temporaries,
so the conversion function must make a copy in some
dynamically-allocated storage (a &quot;holder&quot;) which is managed
by the corresponding Python object.
<p>Unfortunately, in the case of abstract classes (and other types
without a publicly-accessible copy constructor), instantiating this
conversion function causes a compilation error. In order to support
non-copyable classes, there had to be some way to prevent the library
from trying to instantiate the conversion function. The only practical
approach I could think of was to add an additional template parameter
to the <code>class_&lt;&gt;</code> interface. When the number of
template parameters with useful defaults begins to grow, it is often
hard to choose an order which allows users to take advantage of the
defaults.
<p>
This was the straw that broke the
<code>class_&lt;&gt;</code> interface's back and caused the redesign
whose outcome is detailed <a
href="http://mail.python.org/pipermail/c++-sig/2002-March/000892.html">here</a>.
The approach allows the user to supply the optional parameters in an
arbitrary order. It was inspired by the use of <a
href="../../../utility/iterator_adaptors.htm#named_tempalte_parameters">named
template parameters</a> in the <a
href="../../../utility/iterator_adaptors.htm">Boost Iterator Adaptor
Library</a>, though in this case it is possible to deduce the meaning
of the template parameters entirely from their type properties,
resulting in a simpler interface. Although the move from a
policy-based design to what resembles a configuration DSL usually
implies a loss of flexibility, in this case I think any costs are far
outweighed by the advantages.
<p>Note: working around the limitations of the various compilers I'm
supporting was non-trivial, and resulted in a few messy implementation
details. It might be a good idea to switch to a more-straightforward
approach once Metrowerks CodeWarrior Pro8 is released.
<h3><a name="implicit_conversions">C++ Implicit Conversions</a></h3>
Support for C++ implicit conversion involves creating
<code>from_python</code> converters for a type <code>U</code> which in
turn use <code>from_python</code> converters registered for a type
<code>T</code> where there exists a implicit conversion from
<code>T</code> to <code>U</code>. The current implementation is
subject to two inefficiencies:
<ol>
<li>Because an rvalue <code>from_python</code> converter produces two
pieces of data (a function and a <code>void*</code>) from its
<code>convertible()</code> function, we end up calling the function
for <code>T</code> twice: once when the converter is looked up in the
registry, and again when the conversion is actually performed.
<li>A vector is used to mark the "visited" converters, preventing
infinite recursion as <code>T</code> to
<code>U</code> and <code>U</code> to <code>T</code> converters
continually search through one-another.
</ol>
I consider the former to be a minor issue. The second may or may not
prove to be computationally significant, but I believe that
architecturally, it points toward a need for more sophisticated
overload resolution. It may be that we want CLOS-style multimethod
dispatching along with C++ style rules that prevent more than one
implicit conversion per argument.
<h3><a name="data_members">C++ Data Members</a></h3>
To supply the ability to directly access data members, I was able to
hijack the new Python <a
href="http://www.python.org/2.2/descrintro.html#property">property</a>
type. I had hoped that I would also be able to re-use the work of <a
href="make_function.html">make_function</a> to create callable python
objects from C++ functions which access a data member of a given
class. C++ facilities for specifying data member pointer non-type
template arguments require the user to explicitly specify the type of
the data member and this under-utilized feature is also not
well-implemented on all compilers, so passing the member pointer as a
runtime value is the only practical approach. The upshot is that any
such entity would actually have to be a function <i>object</i>, and I
haven't implemented automatic wrapping of C++ callable function
objects yet, so there is less re-use in the implementation than I'd
like. I hope to implement callable object wrapping and refactor this
code one day. I also hope to implement static data member support,
for which Python's property will not be an appropriate descriptor.
<h3><a name="miscellaneous">Miscellaneous</a></h3>
<ul>
<li>Moved <code>args&lt;&gt;</code> and <code>bases&lt;&gt;</code> from unnamed namespace to <code>boost::python</code> in their own header files.
<li>Convert <code>NULL</code> pointers returned from wrapped C++ functions to <code>None</code>.
<li>Improved some compile-time error checks.
<li>Eliminated <code>boost/python/detail/eval.hpp</code> in favor of
more-general <code>boost/mpl/apply.hpp</code>.
<li>General code cleanup and refactoring.
<li>Works with Microsoft Visual C++ 7.0
<li>Warning suppression for many compilers
<li>Elegant interface design for exporting <code>enum</code> types.
</ul>
<hr>
<h2><a name="future">The Near Future</a></h2>
Before April 15th I plan to
<ol>
<li>Document all implemented features
<li>Implement a <code>CallPolicy</code> interface for constructors of wrapped
classes
<li>Implement conversions for <code>char</code> types.
<li>Implement automated code generation for all headers containing
families of overloaded functions to handle arbitrary arity.
</ol>
I also hope to implement a mechanism for generating conversions
between arbitrary Python sequences and C++ containers, if time permits
(and others haven't already done it)!
<h2><a name="notes">Notes</a></h2>
The older version of KCC used by Kull is generating lots of warnings
about a construct I use to instantiate static members of various class
templates. I'm thinking of moving to an idiom which uses a function
template to suppress it, but worry about bloating the size of debug
builds. Since KCC users may be moving to GCC, I'm not sure that it's
worth doing anything about it.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,309 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - May 2002 Progress Report</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">May 2002 Progress Report</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="#intro">Introduction</a></dt>
<dt><a href="#features">New Features</a></dt>
<dl>
<dt><a href="#aix_shared">Shared Library Support for AIX</a><dd>
<dt><a href="#class_enhancements">Class Enhancements</a><dd>
<dl>
<dt><a href="#operators">Operators</a><dd>
<dt><a href="#iterators">Iterators</a><dd>
<dt><a href="#properties">Properties</a><dd>
<dt><a href="#setattr">setattr</a><dd>
<dt><a href="#module">__module__ Attribute</a><dd>
</dl>
<dt><a href="#back_reference">back_reference</a><dd>
</dl>
<dt><a href="#documentation">Documentation</a></dt>
<dt><a href="#misc">Miscellaneous</a></dt>
<dl class="index">
<dt><a href="#converters">Converters</a></dt>
<dt><a href="#checkins">Checkins Mailing List</a></dt>
<dt><a href="#shared">Shared Libraries</a></dt>
</dl>
<dt><a href="#next">What's Next</a></dt>
</dl>
<h2><a name="intro">Introduction</a></h2>
Aside from library development, work on Boost.Python in May was
focused on reducing the support burden. In recent weeks, responding to
requests for support, espcially surrounding building the library, had
begun to impede progress on development. There was a major push to
release a stable 1.28.0 of Boost, including documentation of <a
href="../../../../tools/build/index.html">Boost.Build</a> and specific
<a href="../building.html">instructions</a> for building Boost.Python
v1. The documentation for Boost.Python v2 was also updated as
described <a href="#documentation">here</a>.
<h2><a name="features">New Features</a></h2>
<h3><a name="aix_shared">Shared Library Support for AIX</a></h3>
The Kull group required the ability to build and test Boost.Python
extensions on AIX, a platform with &quot;creatively designed&quot;
shared library semantics. Making this work was a multi-pronged
effort, involving changes to Boost.Build and some great research by
Martin Casado which uncovered the key mechanism required to allow
shared libraries to use functions from the Python executable. The
current solution used in Boost.Build relies on a <a
href="../../../../tools/build/gen_aix_import_file.py">Python
Script</a> as part of the build process. This is not a problem for
Boost.Python, as Python will be available. However, the commands
issued by the script are so simple that a 100%-pure-Boost.Jam
solution is surely possible. Linking on AIX is sufficiently
interesting to have skewed the Boost.Python development schedule a
bit.
<h3><a name="class_enhancements">Class Enhancements</a></h3>
<h4><a name="operators">Operators</a></h4>
Support for exposing C++ operators and functions as the corresponding
Python special methods was added. Thinking that the Boost.Python
<a href="../special.html#numeric">v1 interface</a> was a little too
esoteric (especially the use of
<code>left_operand&lt;...&gt;/right_operand&lt;...&gt;</code> for
asymmetric operands), I introduced a simple form of <a
href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">expression
templates</a> which allow users to simply write the expressions that
should be wrapped, as in this <a href="operators.html#examples">example</a>.
<h4><a name="iterators">Iterators</a></h4>
Python iterator support as required by the Kull project resulted in a
highly flexible interface allowing:
<dl>
<dt>Direct exposure of a class' <code>begin()</code> and
<code>end()</code> functions:
<pre>
...
.def(&quot;__iter__&quot;, iterator&lt;list_int&gt;())
</pre>
<dd>
<dt>Creation of iterators from member functions...
<pre>
...
.def(&quot;__iter__&quot;
, range(&amp;my_class::x_begin, &amp;my_class::x_end))
)
</pre>
<dd>
<dt>...and member data:
<pre>
...
.def(&quot;__iter__&quot;
, range(&amp;std::pair&lt;char*,char*&gt;::first, &amp;std::pair&lt;char*,char*&gt;::second))
)
</pre>
<dd>
<dt>The ability to specify <a
href="CallPolicies.html">CallPolicies</a>, e.g. to prevent copying of
heavyweight values:
<pre>
...
.def(&quot;__iter__&quot;,
, range&lt;return_value_policy&lt;copy_non_const_reference&gt; &gt;(
&amp;my_sequence&lt;heavy&gt;::begin
, &amp;my_sequence&lt;heavy&gt;::end))
</pre>
<dd>
</dl>
<h4><a name="properties">Properties</a></h4>
The Kull iteration interfaces also required the ability to iterate
over a sequence specified by an instance's attribute:
<pre>
&gt;&gt;&gt; f = field()
&gt;&gt;&gt; for e in f.elements:
... print e,
</pre>
This forced the exposure of the <a
href="http://www.python.org/2.2/descrintro.html#property"><code>property</code></a>
interface used internally to implement the data member exposure
facility described in <a
href="Mar2002#data_members">March</a>. Properties are an
incredibly useful idiom, so it's good to be able to provide them
at little new development cost.
<h4><a name="setattr">setattr</a></h4>
<code>class_&lt;&gt;</code> acquired a <code>setattr</code> member
function which allows users to easily add new Python objects as class
attributes.
<h4><a name="module">__module__ Attribute</a></h4>
Ralf Grosse-Kunstleve has been working on pickling support for v2. To
make it work correctly, he had to make sure that a class'
<code>__module__</code> attribute was set correctly.
<h3><a name="back_reference"><code>back_reference</code></a></h3>
The new <code>back_reference&lt;T&gt;</code> template can be used as a
function parameter when the user needs access to both a <code>T</code>
argument and to the Python object which manages it. The function will
only match in the overload resolution process if it would match the
same function signature with <code>T</code> substituted for
<code>back_reference&lt;T&gt;</code>. This feature is not yet
documented.
<h2><a name="documentation">Documentation</a></h2>
In a major effort to prepare Boost.Python v2 to replace v1, many pages
of new reference documentation were added:
<blockquote>
<dl>
<dt><a href="CallPolicies.html">CallPolicies.html</a><dd>
<dt><a href="Dereferenceable.html">Dereferenceable.html</a><dd>
<dt><a href="Extractor.html">Extractor.html</a><dd>
<dt><a href="HolderGenerator.html">HolderGenerator.html</a><dd>
<dt><a href="ResultConverter.html">ResultConverter.html</a><dd>
<dt><a href="call_method.html">call_method.html</a><dd>
<dt><a href="callbacks.html">callbacks.html</a><dd>
<dt><a href="data_members.html">data_members.html</a><dd>
<dt><a href="has_back_reference.html">has_back_reference.html</a><dd>
<dt><a href="implicit.html">implicit.html</a><dd>
<dt><a href="instance_holder.html">instance_holder.html</a><dd>
<dt><a href="operators.html">operators.html</a><dd>
<dt><a href="ptr.html">ptr.html</a><dd>
<dt><a href="type_id.html">type_id.html</a><dd>
<dt><a href="with_custodian_and_ward.html">with_custodian_and_ward.html</a><dd>
</dl>
</blockquote>
Major updates were made to the following pages:
<blockquote>
<dl>
<dt><a href="call.html">call.html</a><dd> <dt><a href="updated">updated</a><dd>
<dt><a href="class.html">class.html</a><dd>
<dt><a href="reference.html">reference.html</a><dd>
</dl>
</blockquote>
As usual, careful documentation forces one to consider the
interface again, and there were many interface changes
associated with this effort, including the elevation of the
following components from implementation detail to
first-class library citizen:
<blockquote>
<dl>
<dt>type_id.hpp<dd>
<dt>pointee.hpp<dd>
<dt>lvalue_from_pytype.hpp<dd></dl>
</dl>
</blockquote>
<h2><a name="misc">Miscellaneous</a></h2>
<h3><a name="converters">Converters</a></h3>
It appears that the world of C++ &lt;==&gt; Python conversion rules is
an endlessly-rich area of exploration. Completing the conversions for
<code>char</code> and <code>char const*</code> types, as described at
the end of <a href="Apr2002.html#missing">April's report</a>,
uncovered some interesting new shades to the problem. It turns out to
be worth distinguishing mutable and immutable lvalue conversions,
because despite the fact that Python doesn't understand
<code>const</code>, it does understand immutability (c.f. Python
strings, which expose an immutable <code>char</code> pointer). It is
also worth recognizing types which represent lvalue <i>sequences</i>,
to prevent Python <code>&quot;foobar&quot;</code> from being silently
truncated to C++ <code>'f'</code>. More details on this insight can be
found in the mailing list <a
href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">
archive</a>. I don't plan to do anything about this immediately, but I
do think it's the right direction to go in the long run.
<h3><a name="checkins">Checkins Mailing List</a></h3>
In order to better coordinate changes made by multiple developers, I
enabled <a
href="http://sourceforge.net/docman/display_doc.php?docid=772&group_id=1">syncmail</a>
for the Boost.Python CVS trees, and established an associated <a
href="http://lists.sourceforge.net/lists/listinfo/boost-python-cvs">mailing
list</a>. Subscribe to this list to receive notices of each new
checkin.
<h3><a name="shared">Shared Libraries</a></h3>
Beyond the vagaries of dynamic linking on AIX, I have been
participating in a more-general discussion of dynamic linking for
C++. Needless to say, C++ dynamic linking is of critical importance to
Boost.Python: all extension modules are normally built as shared
libraries, and Boost.Python extension modules share a common library
as well.
In fact, there are at least two separate conversations. One
in the C++ standard extensions mailing list concerns what can be
standardized for C++ and shared libraries; the other, mostly on the <a
href="http://gcc.gnu.org/ml/gcc/">gcc</a> mailing list, concerns the
behavior of GCC on Posix/ELF platforms.
Some of the GCC threads are here:
<blockquote>
<a
href="http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html">http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html</a><br>
<a
href="http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html">http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html</a><br>
<a href="http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html">http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html</a>
</blockquote>
<h2><a name="next">What's Next</a></h2>
Development is focused on what's needed to be able to retire
Boost.Python v1. At the moment, that means deciding the user-friendly
interfaces for to_/from_python conversion, and formally exposing the
Python object smart pointers and object wrapper classes. Quite a few
questions have also been showing up recently about how to embed Python
with Boost.Python, and how to link with it statically; the solutions
to these issues will probably have to be formalized before long.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,156 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - ObjectWrapper Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">ObjectWrapper and TypeWrapper Concepts</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#ObjectWrapper-concept">ObjectWrapper Concept</a></dt>
<dt><a href="#TypeWrapper-concept">TypeWrapper Concept</a></dt>
</dl>
</dd>
<dt><a href="#caveat">Caveat</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>This page defines two concepts used to describe classes which manage a
Python objects, and which are intended to support usage with a
Python-like syntax.</p>
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="ObjectWrapper-concept"></a>ObjectWrapper Concept</h3>
Models of the ObjectWrapper concept have <a href=
"object.html#object-spec">object</a> as a publicly-accessible base class,
and are used to supply special construction behavior and/or additional
convenient functionality through (often templated) member functions.
Except when the return type <code>R</code> is itself an <a href=
"#TypeWrapper-concept">TypeWrapper</a>, a member function invocation of
the form
<pre>
x.<i>some_function</i>(<i>a<small>1</small>, a<small>2</small>,...a<small>n</small></i>)
</pre>
always has semantics equivalent to:
<pre>
<a href=
"extract.html#extract-spec">extract</a>&lt;R&gt;(x.attr("<i>some_function</i>")(<a
href=
"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
href=
"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
href="object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)))()
</pre>
When the <code>R</code> is an <a href=
"#TypeWrapper-concept">TypeWrapper</a>, the result type may be
constructed by taking direct posession of:
<pre>
x.attr("<i>some_function</i>")(<a href=
"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
href=
"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
href=
"object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)).ptr()
</pre>
[see <a href="#caveat">caveat</a> below]
<h3><a name="TypeWrapper-concept"></a>TypeWrapper Concept</h3>
TypeWrapper is a refinement of ObjectWrapper which is associated with a
particular Python type <code>X</code>. For a given TypeWrapper
<code>T</code>, a valid constructor expression
<pre>
T(<i>a<small>1</small>, a<small>2</small>,...a<small>n</small></i>)
</pre>
builds a new <code>T</code> object managing the result of invoking
<code>X</code> with arguments corresponding to
<pre>
<a href=
"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
href=
"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
href=
"object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)
</pre>
When used as arguments to wrapped C++ functions, or as the template
parameter to <code><a
href="extract.html#extract-spec">extract</a>&lt;&gt;</code>, only
instances of the associated Python type will be considered a match.
<h3><a name="caveat">Caveat</a></h3>
The upshot of the special member function invocation rules when the
return type is a TypeWrapper is that it is possible for the returned
object to manage a Python object of an inappropriate type. This is not
usually a serious problem; the worst-case result is that errors will be
detected at runtime a little later than they might otherwise be. For an
example of how this can occur, note that the <code><a href=
"dict.html#dict-spec">dict</a></code> member function <code>items</code>
returns an object of type <code><a href=
"list.html#list-spec">list</a></code>. Now suppose the user defines this
<code>dict</code> subclass in Python:
<pre>
&gt;&gt;&gt; class mydict(dict):
... def items(self):
... return tuple(dict.items(self)) # return a tuple
</pre>
Since an instance of <code>mydict</code> is also an instance of
<code>dict</code>, when used as an argument to a wrapped C++ function,
<code><a href="dict.html#dict-spec">boost::python::dict</a></code> can
accept objects of Python type <code>mydict</code>. Invoking
<code>items()</code> on this object can result in an instance of <code><a
href="list.html#list-spec">boost::python::list</a></code> which actually
holds a Python tuple. Subsequent attempts to use list methods (e.g.
<code>append</code>, or any other mutating operation) on this object will
raise the same exception that would occur if you tried to do it from
Python.
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
<p>Permission to copy, use, modify, sell and distribute this software is
granted provided this copyright notice appears in all copies. This
software is provided "as is" without express or implied warranty, and
with no claim as to its suitability for any purpose.</p>
</body>
</html>

View File

@@ -1,110 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Python - ResultConverter Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">ResultConverter Concept</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
<dl class="page-index">
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
</dl>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>A ResultConverter for a type <code>T</code> is a type whose
instances can be used to convert C++ return values of type
<code>T</code> <code>to_python</code>. A ResultConverterGenerator is
an MPL unary metafunction class which, given the return type of a C++
function, returns a ResultConverter for that type. ResultConverters in
Boost.Python generally inspect library's registry of converters to
find a suitable converter, but converters which don't use the registry
are also possible.
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="ResultConverter-concept"></a>ResultConverter Concept</h3>
<p>In the table below, <code><b>C</b></code> denotes a ResultConverter
type for a type <b><code>R</code></b> , <code><b>c</b></code> denotes
an object of type <code><b>C</b></code> , and <code><b>r</b></code>
denotes an object of type <code><b>R</b></code>.
<table summary="ResultConverter expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Type</b></td>
<td><b>Semantics</b></td>
</tr>
<tr>
<td valign="top"><code>C c;</code></td>
<td>
<td>Constructs a <code>C</code> object.
</tr>
<tr>
<td valign="top"><code>c.convertible()</code></td>
<td>convertible to <code>bool</code></td>
<td><code>false</code> iff no conversion from any <code>R</code> value
to a Python object is possible.</td>
</tr>
<tr>
<td valign="top"><code>c(r)</code></td>
<td>convertible to <code>PyObject*</code></td>
<td>A pointer to a Python object corresponding to <code>r</code>,
or <code>0</code> iff <code>r</code> could not be converted
<code>to_python</code>, in which case <a
href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
should return non-zero.</td>
</tr>
</table>
<h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>
<p>In the table below, <code><b>G</b></code> denotes a
ResultConverterGenerator type and <code><b>R</b></code> denotes a possible
C++ function return type.
<table summary="ResultConverterGenerator expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Requirements</b></td>
</tr>
<tr>
<td valign="top"><code>G::apply&lt;R&gt;::type</code></td>
<td>A ResultConverter type for <code>R</code>.</td>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
09 May, 2002 <!--Luann's birthday! -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>
<p>Permission to copy, use, modify, sell
and distribute this software is granted provided this copyright notice appears
in all copies. This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
</body>
</html>

View File

@@ -1,103 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Acknowledgments</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Acknowledgments</h2>
</td>
</tr>
</table>
<hr>
<p><a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a> is
the architect, designer, and implementor of <b>Boost.Python</b>.</p>
<p>Joel de Guzman implemented the <a href="overloads.html">default
argument support</a> and wrote the excellent <a href=
"../tutorial/index.html">tutorial documentation</a>.</p>
<p><a href="../../../../people/ralf_w_grosse_kunstleve.htm">Ralf W.
Grosse-Kunstleve</a> implemented the <a href="pickle.html">pickle
support</a>, and has enthusiastically supported the library since its
birth, contributing to design decisions and providing invaluable
real-world insight into user requirements. Ralf has written some <a href=
"faq.html#question2">extensions</a> for converting C++ containers that I
hope will be incorporated into the library soon. He also implemented the
cross-module support in the first version of Boost.Python. More
importantly, Ralf makes sure nobody forgets the near-perfect synergy of
C++ and Python for solving the problems of large-scale software
construction.</p>
<p><a href="../../../../people/aleksey_gurtovoy.htm">Aleksey Gurtovoy</a>
wrote an incredible C++ <a href="http://www.mywikinet.com/mpl">Template
Metaprogramming Library</a> which allows Boost.Python to perform much of
its compile-time magic. In addition, Aleksey very generously contributed
his time and deep knowledge of the quirks of various buggy compilers to
help us get around problems at crucial moments.</p>
<p><a href="../../../../people/paul_mensonides.htm">Paul Mensonides</a>,
building on the work <a href="../../../../people/vesa_karvonen.htm">Vesa
Karvonen</a>, wrote a similarly amazing <a href=
"../../../preprocessor/doc/index.html">Preprocessor Metaprogramming
Library</a>, and generously contributed the time and expertise to get it
working in the Boost.Python library, rewriting much of Boost.Python to
use the new preproccessor metaprogramming constructs and helping us to
work around buggy and slow C++ preprocessors.</p>
<p><a href="mailto:achim@procoders.net">Achim Domma</a> contributed some
of the <a href="reference.html#object_wrappers">Object Wrappers</a> and
HTML templates for this documentation. Dave Hawkes contributed
inspiration for the use of the <code><a href=
"scope.html#scope-spec">scope</a></code> class to simplify module
definition syntax. Pearu Pearson wrote some of the test cases that are in
the current test suite.</p>
<p>Martin Casado solved some sticky problems which allow us to build the
Boost.Python shared library for AIX's crazy dynamic linking model.</p>
<p>The development of this version of Boost.Python was funded in part by
the <a href="http://www.llnl.gov/">Lawrence Livermore National
Laboratories</a> and by the <a href="http://cci.lbl.gov/">Computational
Crystallography Initiative</a> at Lawrence Berkeley National
Laboratories.</p>
<p><a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/">Ullrich
Koethe</a> provided the implementation of inheritance and special
method/operator support in the first version of Boost.Python.</p>
<p>The first version of Boost.Python would not have been possible without
the support of Dragon Systems, which supported its development and
release as a Boost library.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,103 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/args.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/args.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#keyword-expression"><i>keyword-expressions</i></a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><code><a href=
"#args-spec">args</a>(</code>...<code>)</code></dt>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Supplies a family of overloaded functions for specifying argument
keywords for wrapped C++ functions.</p>
<h2><a name="keyword-expression"></a><i>keyword-expressions</i></h2>
<p>A <b>keyword-expression</b> results in an object which holds a
sequence of <a href="definitions.html#ntbs">ntbs</a>es, and whose type
encodes the number of keywords specified.</p>
<h2><a name="functions"></a>Functions</h2>
<h3><a name="args-spec"></a><code>args(</code>...<code>)</code></h3>
<pre>
<i>unspecified1</i> args(char const*);
<i>unspecified2</i> args(char const*, char const*);
.
.
.
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> Every argument must be a <a href=
"definitions.html#ntbs">ntbs</a>.</dt>
<dt><b>Returns:</b> an object representing a <a href=
"#keyword-expression"><i>keyword-expression</i></a> encapsulating the
arguments passed.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<pre>
#include &lt;boost/python/def.hpp&gt;
using namespace boost::python;
int f(int x, int y, int z);
BOOST_PYTHON_MODULE(xxx)
{
def("f", f, args("x", "y", "z"));
}
</pre>
<p>Revised 05 November, 2001</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,32 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Bibliography</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Bibliography</h2>
</td>
</tr>
</table>
<hr>
{{bibliographical information}}
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,82 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;call.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;call.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dl class="page-index">
<dt><a href="#call-spec">call</a></dt>
</dl>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>
<code>&lt;boost/python/call.hpp&gt;</code> defines the <a
href="#call-spec"><code>call</code></a> family of overloaded function
templates, used to invoke Python callable objects from C++.
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="call-spec">template &lt;class R, class A1, class A2, ... class A<i>n</i>&gt;</a>
R call(PyObject* callable, A1 const&amp;, A2 const&amp;, ... A<i>n</i> const&amp;)
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>R</code> is a pointer type, reference
type, or a complete type with an accessible copy constructor</dt>
<dt><b>Effects:</b> Invokes <code>callable(a1,&nbsp;a2,&nbsp;...a<i>n</i>)</code> in
Python, where <code>a1</code>...<code>a<i>n</i></code> are the arguments to
<code>call()</code>, converted to Python objects.
<dt><b>Returns:</b> The result of the Python call, converted to the C++ type <code>R</code>.</dt>
</dt>
<dt><b>Rationale:</b> For a complete semantic description and
rationale, see <a href="callbacks.html">this page</a>.
</dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
The following C++ function applies a Python callable object to its two
arguments and returns the result. If a Python exception is raised or
the result can't be converted to a <code>double</code>, an exception
is thrown.
<pre>
double apply2(PyObject* func, double x, double y)
{
return boost::python::call&lt;double&gt;(func, x, y);
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
9 May, 2002 <!-- Luann's birthday! -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,159 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;call_method.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;call_method.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#call_method-spec">call_method</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/call_method.hpp&gt;</code> defines the <a href=
"#call_method-spec"><code>call_method</code></a> family of overloaded
function templates, used to invoke callable attributes of Python objects
from C++.</p>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name=
"call_method-spec">template &lt;class R, class A1, class A2, ... class A<i>n</i>&gt;</a>
R call_method(PyObject* self, char const* method, A1 const&amp;, A2 const&amp;, ... A<i>n</i> const&amp;)
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>R</code> is a pointer type, reference type,
or a complete type with an accessible copy constructor</dt>
<dt><b>Effects:</b> Invokes
<code>self.<i>method</i>(a1,&nbsp;a2,&nbsp;...a<i>n</i>)</code> in
Python, where <code>a1</code>...<code>a<i>n</i></code> are the
arguments to <code>call_method()</code>, converted to Python objects.
For a complete semantic description, see <a href="callbacks.html">this
page</a>.</dt>
<dt><b>Returns:</b> The result of the Python call, converted to the C++
type <code>R</code>.</dt>
<dt><b>Rationale:</b> <code>call_method</code> is critical to
implementing C++ virtual functions which are overridable in Python, as
shown by the example below.</dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
The following C++ illustrates the use of <code>call_method</code> in
wrapping a class with a virtual function that can be overridden in
Python:
<h3>C++ Module Definition</h3>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/utility.hpp&gt;
#include &lt;cstring&gt;
// class to be wrapped
class Base
{
public:
virtual char const* class_name() const { return "Base"; }
virtual ~Base();
};
bool is_base(Base* b)
{
return !std::strcmp(b-&gt;class_name(), "Base");
}
// Wrapper code begins here
using namespace boost::python;
// Callback class
class Base_callback : public Base
{
public:
Base_callback(PyObject* self) : m_self(self) {}
char const* class_name() const { return <b>call_method</b>&lt;char const*&gt;(m_self, "class_name"); }
char const* Base_name() const { return Base::class_name(); }
private:
PyObject* const m_self;
};
using namespace boost::python;
BOOST_PYTHON_MODULE(my_module)
{
def("is_base", is_base);
class_&lt;Base,Base_callback, noncopyable&gt;("Base")
.def("class_name", &amp;Base_callback::Base_name)
;
}
</pre>
<h3>Python Code</h3>
<pre>
&gt;&gt;&gt; from my_module import *
&gt;&gt;&gt; class Derived(Base):
... def __init__(self):
... Base.__init__(self)
... def class_name(self):
... return self.__class__.__name__
...
&gt;&gt;&gt; is_base(Base()) # calls the class_name() method from C++
1
&gt;&gt;&gt; is_base(Derived())
0
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,252 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Calling Python Functions and Methods</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Calling Python Functions and Methods</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#argument_handling">Argument Handling</a></dt>
<dt><a href="#result_handling">Result Handling</a></dt>
<dt><a href="#result_handling">Rationale</a></dt>
</dl>
<hr>
<h2><a name="introduction">Introduction</a></h2>
The simplest way to call a Python function from C++, given an <code><a
href="object.html#object-spec">object</a></code> instance <code>f</code>
holding the function, is simply to invoke its function call operator.
<pre>
f("tea", 4, 2) // In Python: f('tea', 4, 2)
</pre>
And of course, a method of an <code><a href=
"object.html#object-spec">object</a></code> instance <code>x</code> can
be invoked by using the function-call operator of the corresponding
attribute:
<pre>
x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
</pre>
<p>If you don't have an <code>object</code> instance, Boost.Python
provides two families of function templates, <code><a href=
"call.html#call-spec">call</a></code> and <code><a href=
"call_method.html#call_method-spec">call_method</a></code>, for invoking
Python functions and methods respectively on <code>PyObject*</code>s. The
interface for calling a Python function object (or any Python callable
object) looks like:</p>
<pre>
call&lt;ResultType&gt;(callable_object, a1, a2... a<i>N</i>);
</pre>
Calling a method of a Python object is similarly easy:
<pre>
call_method&lt;ResultType&gt;(self_object, "<i>method-name</i>", a1, a2... a<i>N</i>);
</pre>
This comparitively low-level interface is the one you'll use when
implementing C++ virtual functions that can be overridden in Python.
<h2><a name="argument_handling">Argument Handling</a></h2>
<p>Arguments are converted to Python according to their type. By default,
the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
new Python objects, but this behavior can be overridden by the use of
<code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a href=
"../../../bind/ref.html#reference_wrapper">ref()</a>:</p>
<pre>
class X : boost::noncopyable
{
...
};
void apply(PyObject* callable, X&amp; x)
{
// Invoke callable, passing a Python object which holds a reference to x
boost::python::call&lt;void&gt;(callable, boost::ref(x));
}
</pre>
In the table below, <code><b>x</b></code> denotes the actual argument
object and <code><b>cv</b></code> denotes an optional
<i>cv-qualification</i>: "<code>const</code>", "<code>volatile</code>",
or "<code>const volatile</code>".
<table border="1" summary="class_ template parameters">
<tr>
<th>Argument Type</th>
<th>Behavior</th>
</tr>
<tr>
<td><code>T cv&amp;</code><br>
<code>T cv</code></td>
<td>The Python argument is created by the same means used for the
return value of a wrapped C++ function returning <code>T</code>. When
<code>T</code> is a class type, that normally means <code>*x</code>
is copy-constructed into the new Python object.</td>
</tr>
<tr>
<td><code>T*</code></td>
<td>If <code>x&nbsp;==&nbsp;0</code>, the Python argument will be
<code><a href=
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
Otherwise, the Python argument is created by the same means used for
the return value of a wrapped C++ function returning <code>T</code>.
When <code>T</code> is a class type, that normally means
<code>*x</code> is copy-constructed into the new Python object.</td>
</tr>
<tr>
<td><code><a href=
"../../../bind/ref.html#reference_wrapper">boost::reference_wrapper</a>&lt;T&gt;</code></td>
<td>The Python argument contains a pointer to, rather than a copy of,
<code>x.get()</code>. Note: failure to ensure that no Python code
holds a reference to the resulting object beyond the lifetime of
<code>*x.get()</code> <b>may result in a crash!</b></td>
</tr>
<tr>
<td><code><a href=
"ptr.html#pointer_wrapper-spec">pointer_wrapper</a>&lt;T&gt;</code></td>
<td>If <code>x.get()&nbsp;==&nbsp;0</code>, the Python argument will
be <code><a href=
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
Otherwise, the Python argument contains a pointer to, rather than a
copy of, <code>*x.get()</code>. Note: failure to ensure that no
Python code holds a reference to the resulting object beyond the
lifetime of <code>*x.get()</code> <b>may result in a crash!</b></td>
</tr>
</table>
<h2><a name="result_handling">Result Handling</a></h2>
In general, <code>call&lt;ResultType&gt;()</code> and
<code>call_method&lt;ResultType&gt;()</code> return
<code>ResultType</code> by exploiting all lvalue and rvalue
<code>from_python</code> converters registered for ResultType and
returning a copy of the result. However, when <code>ResultType</code> is
a pointer or reference type, Boost.Python searches only for lvalue
converters. To prevent dangling pointers and references, an exception
will be thrown if the Python result object has only a single reference
count.
<h2><a name="rationale">Rationale</a></h2>
In general, to get Python arguments corresponding to
<code>a1</code>...<code>a<i>N</i></code>, a new Python object must be
created for each one; should the C++ object be copied into that Python
object, or should the Python object simply hold a reference/pointer to
the C++ object? In general, the latter approach is unsafe, since the
called function may store a reference to the Python object somewhere. If
the Python object is used after the C++ object is destroyed, we'll crash
Python.
<p>In keeping with the philosophy that users on the Python side shouldn't
have to worry about crashing the interpreter, the default behavior is to
copy the C++ object, and to allow a non-copying behavior only if the user
writes <code><a href="../../../bind/ref.html">boost::ref</a>(a1)</code>
instead of a1 directly. At least this way, the user doesn't get dangerous
behavior "by accident". It's also worth noting that the non-copying
("by-reference") behavior is in general only available for class types,
and will fail at runtime with a Python exception if used otherwise[<a
href="#1">1</a>].</p>
<p>However, pointer types present a problem: one approach is to refuse to
compile if any aN has pointer type: after all, a user can always pass
<code>*aN</code> to pass "by-value" or <code>ref(*aN)</code> to indicate
a pass-by-reference behavior. However, this creates a problem for the
expected null pointer to <code>None</code> conversion: it's illegal to
dereference a null pointer value.</p>
<p>The compromise I've settled on is this:</p>
<ol>
<li>The default behavior is pass-by-value. If you pass a non-null
pointer, the pointee is copied into a new Python object; otherwise the
corresponding Python argument will be None.</li>
<li>if you want by-reference behavior, use <code>ptr(aN)</code> if
<code>aN</code> is a pointer and <code>ref(aN)</code> otherwise. If a
null pointer is passed to <code>ptr(aN)</code>, the corresponding
Python argument will be <code>None</code>.</li>
</ol>
<p>As for results, we have a similar problem: if <code>ResultType</code>
is allowed to be a pointer or reference type, the lifetime of the object
it refers to is probably being managed by a Python object. When that
Python object is destroyed, our pointer dangles. The problem is
particularly bad when the <code>ResultType</code> is char const* - the
corresponding Python String object is typically uniquely-referenced,
meaning that the pointer dangles as soon as <code>call&lt;char
const*&gt;(...)</code> returns.</p>
<p>The old Boost.Python v1 deals with this issue by refusing to compile
any uses of <code>call&lt;char const*&gt;()</code>, but this goes both
too far and not far enough. It goes too far because there are cases where
the owning Python string object survives beyond the call (just for
instance, when it's the name of a Python class), and it goes not far
enough because we might just as well have the same problem with a
returned pointer or reference of any other type.</p>
<p>In Boost.Python v2 this is dealt with by:</p>
<ol>
<li>lifting the compile-time restriction on const char* callback
returns</li>
<li>detecting the case when the reference count on the result Python
object is 1 and throwing an exception inside of
<code>call&lt;U&gt;(...)</code> when <code>U</code> is a pointer or
reference type.</li>
</ol>
This should be acceptably safe because users have to explicitly specify a
pointer/reference for <code>U</code> in <code>call&lt;U&gt;</code>, and
they will be protected against dangles at runtime, at least long enough
to get out of the <code>call&lt;U&gt;(...)</code> invocation.
<hr>
<a name="1">[1]</a> It would be possible to make it fail at compile-time
for non-class types such as int and char, but I'm not sure it's a good
idea to impose this restriction yet.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,88 +0,0 @@
Here's the plan:
I aim to provide an interface similar to that of Boost.Python v1's
callback<>::call(...) for dealing with callbacks. The interface will
look like:
returning<ResultType>::call("method_name", self_object, a1, a2...);
or
returning<ResultType>::call(callable_object, a1, a2...);
ARGUMENT HANDLING
There is an issue concerning how to make Python objects from the
arguments a1...aN. A new Python object must be created; should the C++
object be copied into that Python object, or should the Python object
simply hold a reference/pointer to the C++ object? In general, the
latter approach is unsafe, since the called function may store a
reference to the Python object somewhere. If the Python object is used
after the C++ object is destroyed, we'll crash Python.
I plan to make the copying behavior the default, and to allow a
non-copying behavior if the user writes boost::ref(a1) instead of a1
directly. At least this way, the user doesn't get dangerous behavior "by
accident". It's also worth noting that the non-copying ("by-reference")
behavior is in general only available for class types, and will fail at
runtime with a Python exception if used otherwise**
However, pointer types present a problem: My first thought is to refuse
to compile if any aN has pointer type: after all, a user can always pass
*aN to pass "by-value" or ref(*aN) to indicate a pass-by-reference
behavior. However, this creates a problem for the expected NULL pointer
=> None conversion: it's illegal to dereference a null pointer value.
We could use another construct, say "ptr(aN)", to deal with null
pointers, but then what does it mean? We know what it does when aN is
NULL, but it might either have by-value or by-reference behavior when aN
is non-null.
The compromise I've settled on is this:
1. The default behavior is pass-by-value. If you pass a non-null
pointer, the pointee is copied into a new Python object; otherwise
the corresponding Python argument will be None.
2. if you want by-reference behavior, use ptr(aN) if aN is a pointer
and ref(aN) otherwise. If a null pointer is passed to ptr(aN), the
corresponding Python argument will be None.
RESULT HANDLING
As for results, we have a similar problem: if ResultType is allowed to
be a pointer or reference type, the lifetime of the object it refers to
is probably being managed by a Python object. When that Python object is
destroyed, our pointer dangles. The problem is particularly bad when the
ResultType is char const* - the corresponding Python String object is
typically uniquely-referenced, meaning that the pointer dangles as soon
as returning<char const*>::call() returns.
Boost.Python v1 deals with this issue by refusing to compile any uses of
callback<char const*>::call(), but IMO this goes both too far and not
far enough. It goes too far because there are cases where the owning
String object survives beyond the call (just for instance when it's the
name of a Python class), and it goes not far enough because we might
just as well have the same problem with any returned pointer or
reference.
I propose to address this in Boost.Python v2 by
1. lifting the compile-time restriction on const
char* callback returns
2. detecting the case when the reference count on the
result Python object is 1 and throwing an exception
inside of returning<U>::call() when U is a pointer or
reference type.
I think this is acceptably safe because users have to explicitly specify
a pointer/reference for U in returning<U>, and they will be protected
against dangles at runtime, at least long enough to get out of the
returning<U>::call() invocation.
-Dave
**It would be possible to make it fail at compile-time for non-class
types such as int and char, but I'm not sure it's a good idea to impose
this restriction yet.

View File

@@ -1,697 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/class.hpp&gt;,
&lt;boost/python/class_fwd.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Headers &lt;boost/python/class.hpp&gt;,
&lt;boost/python/class_fwd.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#class_-spec">Class template
<code>class_</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#class_-spec-synopsis">Class <code>class_</code>
synopsis</a></dt>
<dt><a href="#class_-spec-ctors">Class <code>class_</code>
constructors</a></dt>
<dt><a href="#class_-spec-modifiers">Class <code>class_</code>
modifier functions</a></dt>
</dl>
</dd>
<dt><a href="#bases-spec">Class template
<code>bases</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#bases-spec-synopsis">Class template
<code>bases</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/class.hpp&gt;</code> defines the interface
through which users expose their C++ classes to Python. It declares the
<code>class_</code> class template, which is parameterized on the class
type being exposed. It also exposes the <code>init</code>,
<code>optional</code> and <code>bases</code> utility class templates,
which are used in conjunction with <code>class_</code>.</p>
<p><code>&lt;boost/python/class_fwd.hpp&gt;</code> contains a forward
declaration of the <code>class_</code> class template.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class_-spec"></a>Class template
<code>class_&lt;T,&nbsp;<font color="#007F00">Bases,&nbsp;HeldType,
NonCopyable</font>&gt;</code></h3>
<p>Creates a Python class associated with the C++ type passed as its
first parameter. Although it has four template parameters, only the first
one is required. The three optional arguments can actually be supplied
<font color="#007F00"><b>in any order</b></font>; Boost.Python determines
the role of the argument from its type.<br>
<br>
</p>
<table border="1" summary="class_ template parameters">
<tr>
<th>Template Parameter</th>
<th>Requirements</th>
<th>Semantics</th>
<th>Default</th>
</tr>
<tr>
<td><code>T</code></td>
<td>A class type.</td>
<td>The class being wrapped</td>
</tr>
<tr>
<td><code><font color="#007F00">Bases</font></code></td>
<td>A specialization of <a href=
"#bases-spec"><code>bases&lt;</code>...<code>&gt;</code></a> which
specifies previously-exposed C++ base classes of <code>T</code><a
href="#footnote_1">[1]</a>.</td>
<td>Registers <code>from_python</code> conversions from wrapped
<code>T</code> instances to each of its exposed direct and indirect
bases. For each polymorphic base <code>B</code>, registers
conversions from indirectly-held wrapped <code>B</code> instances to
<code>T</code>.</td>
<td><code><a href="#bases">bases&lt;&gt;</a></code></td>
</tr>
<tr>
<td><code><font color="#007F00">HeldType</font></code></td>
<td>Must be <code>T</code>, a class derived from <code>T</code>, or a
<a href="Dereferenceable.html">Dereferenceable</a> type for which
<code><a href=
"pointee.html#pointee-spec">pointee</a>&lt;HeldType&gt;::type</code>
is <code>T</code> or a class derived from <code>T</code>.</td>
<td>Specifies the type which is actually embedded in a Python object
wrapping a <code>T</code> instance. More details <a href=
"#HeldType">below</a>.</td>
<td><code>T</code></td>
</tr>
<tr>
<td><code><font color="#007F00">NonCopyable</font></code></td>
<td>If supplied, must be <a href=
"../../../utility/utility.htm#Class%20noncopyable">boost::noncopyable</a>.</td>
<td>Suppresses automatic registration of <code>to_python</code>
conversions which copy <code>T</code> instances. Required when
<code>T</code> has no publicly-accessible copy constructor.</td>
<td>An unspecified type other than
<code>boost::noncopyable</code>.</td>
</tr>
</table>
<h4><a name="#HeldType">HeldType Semantics</a></h4>
<ol>
<li>If <code>HeldType</code> is derived from T, its exposed
constructor(s) must accept an initial <code>PyObject*</code> argument
which refers back to the Python object that contains the
<code>HeldType</code> instance, as shown in <a href=
"call_method.html#example">this example</a>. This argument is not
included in the <em><a href=
"init.html#init-expressions">init-expression</a></em> passed to <a
href="#class-spec-modifiers"><code>def(init_expr)</code></a>, below,
nor is it passed explicitly by users when Python instances of
<code>T</code> are created. This idiom allows C++ virtual functions
which will be overridden in Python to access the Python object so the
Python method can be invoked. Boost.Python automatically registers
additional converters which allow wrapped instances of <code>T</code>
to be passed to wrapped C++ functions expecting <code>HeldType</code>
arguments.</li>
<li>Because Boost.Python will always allow wrapped instances of
<code>T</code> to be passed in place of <code>HeldType</code>
arguments, specifying a smart pointer for <code>HeldType</code> allows
users to pass Python <code>T</code> instances where a smart
pointer-to-<code>T</code> is expected. Smart pointers such as
<code>std::auto_ptr&lt;&gt;</code> or <code><a href=
"../../../smart_ptr/shared_ptr.htm">boost::shared_ptr&lt;&gt;</a></code>
which contain a nested type <code>element_type</code> designating the
referent type are automatically supported; additional smart pointer
types can be supported by specializing <a href=
"pointee.html#pointee-spec">pointee&lt;HeldType&gt;</a>.</li>
<li>As in case 1 above, when <code>HeldType</code> is a smart pointer
to a class derived from <code>T</code>, the initial
<code>PyObject*</code> argument must be supplied by all of
<code>HeldType</code>'s exposed constructors.</li>
<li>Except in cases 1 and 3, users may optionally specify that T itself
gets initialized with a similar initial <code>PyObject*</code> argument
by specializing <a href=
"has_back_reference.html#has_back_reference-spec">has_back_reference&lt;T&gt;</a>.</li>
</ol>
<h4><a name="class_-spec-synopsis"></a>Class template <code>class_</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T
<font color="#007F00"> , class Bases = bases&lt;&gt;
, class HeldType = T
, class NonCopyable = <i>unspecified</i>
&gt;
</font> class class_ : public <a href="object.html#object-spec">object</a>
{
// Constructors with default __init__
class_(char const* name);
class_(char const* name, char const* docstring);
// Constructors, specifying non-default __init__
template &lt;class Init&gt;
class_(char const* name, Init);
template &lt;class Init&gt;
class_(char const* name, char const* docstring, Init);
// Exposing additional __init__ functions
template &lt;class Init&gt;
class_&amp; def(Init);
// defining methods
template &lt;class F&gt;
class_&amp; def(char const* name, F f);
template &lt;class Fn, class A1&gt;
class_&amp; def(char const* name, Fn fn, A1 const&amp;);
template &lt;class Fn, class A1, class A2&gt;
class_&amp; def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;);
template &lt;class Fn, class A1, class A2, class A3&gt;
class_&amp; def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
// exposing operators
template &lt;<i>unspecified</i>&gt;
class_&amp; def(<a href=
"operators.html#operator_-spec">detail::operator_</a>&lt;unspecified&gt;);
// Raw attribute modification
template &lt;class U&gt;
class_&amp; setattr(char const* name, U const&amp;);
// exposing data members
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D T::*pm);
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D T::*pm);
// property creation
template &lt;class Get&gt;
void add_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_property(char const* name, Get const&amp; fget, Set const&amp; fset);
// pickle support
template &lt;typename PickleSuite&gt;
self&amp; def_pickle(PickleSuite const&amp;);
};
}}
</pre>
<h4><a name="class_-spec-ctors"></a>Class template <code>class_</code>
constructors</h4>
<pre>
class_(char const* name);
class_(char const* name, char const* docstring);
template &lt;class Init&gt;
class_(char const* name, Init init_spec);
template &lt;class Init&gt;
class_(char const* name, char const* docstring, Init init_spec);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>. If <code>docstring</code> is supplied, it must be an
<a href="definitions.html#ntbs">ntbs</a>. If <code>init_spec</code> is
supplied, it must be either the special enumeration constant
<code>no_init</code> or an <a href=
"init.html#init-expression">init-expression</a> compatible with
<code>T</code>.</dt>
<dt><b>Effects:</b> Constructs a <code>class_</code> object holding a
Boost.Python extension class named <code>name</code>. The
<code>name</code>d attribute of the <a href=
"scope.html#introduction">current scope</a> is bound to the new
extension class.</dt>
<dd>
<ul>
<li>If supplied, the value of <code>docstring</code> is bound to
the <code>__doc__</code> attribute of the extension class.</li>
<li>If <code>init_spec</code> is <code>no_init</code>, a special
<code>__init__</code> function is generated which always raises a
Python exception. Otherwise, <code>this-&gt;def(init_spec)</code>
is called.</li>
<li>If <code>init_spec</code> is not supplied,
<code>this-&gt;def(init&lt;&gt;())</code> is called.</li>
</ul>
</dd>
<dt><b>Rationale:</b>Allowing the user to specify constructor arguments
in the <code>class_&lt;&gt;</code> constructor helps her to avoid the
common run-time errors which result from invoking wrapped member
functions without having exposed an <code>__init__</code> function
which creates the requisite <code>T</code> instance. Types which are
not default-constructible will cause a compile-time error unless
<code>Init</code> is supplied. The user must always supply
<code>name</code> as there is currently no portable method to derive
the text of the class name from its type.</dt>
</dl>
<h4><a name="class_-spec-modifiers"></a>Class template
<code>class_</code> modifier functions</h4>
<pre>
template &lt;class Init&gt;
class_&amp; def(Init init_expr);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>init_expr</code> is the result of an <a
href="init.html#init-expression">init-expression</a> compatible with
<code>T</code>.</dt>
<dt><b>Effects:</b> For each <a href="init.html#init-expressions">valid
prefix</a> <em>P</em> of <code>Init</code>, adds an
<code>__init__(</code>...<code>)</code> function overload to the
extension class accepting <em>P</em> as arguments. Each overload
generated constructs an object of <code>HeldType</code> according to
the semantics described <a href="#HeldType">above</a>, using a copy of
<code>init_expr</code>'s <a href="CallPolicies.html">call policies</a>.
If the longest <a href="init.html#init-expressions">valid prefix</a> of <code>Init</code> contains <em>N</em>
types and <code>init_expr</code> holds <em>M</em> keywords, an initial
sequence of the keywords are used for all but the first
<em>N</em>&nbsp;-&nbsp;<em>M</em> arguments of each overload.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose a class'
constructor to Python.</dt>
</dl>
<br>
<pre>
template &lt;class F&gt;
class_&amp; def(char const* name, Fn fn);
template &lt;class Fn, class A1&gt;
class_&amp; def(char const* name, Fn fn, A1 const&amp; a1);
template &lt;class Fn, class A1, class A2&gt;
class_&amp; def(char const* name, Fn fn, A1 const&amp; a1, A2 const&amp; a2);
template &lt;class Fn, class A1, class A2, class A3&gt;
class_&amp; def(char const* name, Fn fn, A1 const&amp; a1, A2 const&amp; a2, A3 const&amp; a3);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.</dt>
<dd>
<ul>
<li>
If <code>a1</code> is the result of an <a href=
"overloads.html#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>,
only the second form is allowed and fn must be a pointer
to function or pointer to member function whose <a
href="definitions.html#arity">arity</a> is the same as A1's <a href=
"overloads.html#overload-dispatch-expression"><em>maximum arity</em></a>.
<dl>
<dt><b>Effects:</b> For each prefix <em>P</em> of
<code>Fn</code>'s sequence of argument types, beginning
with the one whose length is <code>A1</code>'s <a href=
"overloads.html#overload-dispatch-expression"><em>minimum
arity</em></a>, adds a
<code><em>name</em>(</code>...<code>)</code> method
overload to the extension class. Each overload generated
invokes
<code>a1</code>'s call-expression with <em>P</em>, using a copy
of <code>a1</code>'s <a href="CallPolicies.html">call
policies</a>. If the longest valid prefix of <code>A1</code>
contains <em>N</em> types and <code>a1</code> holds <em>M</em>
keywords, an initial sequence of the keywords are used for all
but the first <em>N</em>&nbsp;-&nbsp;<em>M</em> arguments of
each overload.<br>
</dt>
</dl>
</li>
<li>
Otherwise, a single method overload is built around fn, which
must not be null:
<ul>
<li>If fn is a function pointer, its first argument must be of
the form <code>U</code>, <code>U&nbsp;<em>cv</em>&amp;</code>,
<code>U&nbsp;<em>cv</em>*</code>, or
<code>U&nbsp;<em>cv</em>*&nbsp;const&amp;</code>, where
<code>T*</code> is convertible to <code>U*</code>, and
<code>a1</code>-<code>a3</code>, if supplied, may be selected
in any order from the table below.</li>
<li>Otherwise, if fn is a member function pointer, its target
must be <code>T</code> or one of its public base classes, and
<code>a1</code>-<code>a3</code>, if supplied, may be selected
in any order from the table below.</li>
<li>Otherwise, <code>Fn</code> must be [derived from] <code><a
href="object.html#object-spec">object</a></code>, and
<code>a1-a2</code>, if supplied, may be selcted in any order
from the first two rows of the table below. To be useful,
<code>fn</code> should be <a href=
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">
callable</a>.</li>
</ul>
<table border="1" summary="def() optional arguments">
<tr>
<th>Memnonic Name</th>
<th>Requirements/Type properties</th>
<th>Effects</th>
</tr>
<tr>
<td>docstring</td>
<td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
<td>Value will be bound to the <code>__doc__</code> attribute
of the resulting method overload.</td>
</tr>
<tr>
<td>policies</td>
<td>A model of <a href=
"CallPolicies.html">CallPolicies</a></td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
<tr>
<td>keywords</td>
<td>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>fn</code>.</td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
</table>
</li>
</ul>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
</dl>
<pre>
template &lt;<i>unspecified</i>&gt;
class_&amp; def(<a href=
"operators.html#operator_-spec">detail::operator_</a>&lt;unspecified&gt;);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Adds a Python <a href=
"http://www.python.org/doc/ref/specialnames.html">special method</a> as
described <a href="operators.html">here</a>.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
</dl>
<pre>
template &lt;class U&gt;
class_&amp; setattr(char const* name, U const&amp; u);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.</dt>
<dt><b>Effects:</b> Converts u to Python and adds it to the attribute
dictionary of the extension class:</dt>
<dd>
<blockquote>
<code><a href=
"http://www.python.org/doc/current/api/object.html#l2h-166">PyObject_SetAttrString</a>(this-&gt;ptr(),&nbsp;name,&nbsp;<a
href="object.html#object-spec-ctors">object</a>(u).ptr());</code>
</blockquote>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
</dl>
<br>
<pre>
template &lt;class Get&gt;
void add_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_property(char const* name, Get const&amp; fget, Set const&amp; fset);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.</dt>
<dt><b>Effects:</b> Creates a new Python <a href=
"http://www.python.org/2.2.2/descrintro.html#property"><code>property</code></a>
class instance, passing <code><a href=
"object.html#object-spec-ctors">object</a>(fget)</code> (and <code><a
href="object.html#object-spec-ctors">object</a>(fset)</code> in the
second form) to its constructor, then adds that property to the Python
class object under construction with the given attribute
<code>name</code>.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose functions that can
be invoked from Python with attribute access syntax.</dt>
</dl>
<br>
<pre>
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D T::*pm);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.</dt>
<dt><b>Effects:</b></dt>
<dd>
<pre>
this-&gt;add_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm));
</pre>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data
member such that it can be inspected from Python with a natural
syntax.</dt>
</dl>
<pre>
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D T::*pm);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b></dt>
<dd>
<pre>
this-&gt;add_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
"data_members.html#make_setter-spec">make_setter</a>(pm));
</pre>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data
member such that it can be inspected and set from Python with a natural
syntax.</dt>
</dl>
<pre>
template &lt;typename PickleSuite&gt;
class_&amp; def_pickle(PickleSuite const&amp;);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> PickleSuite must be publically derived from
<a href="pickle.html"
><code>pickle_suite</code></a>.</dt>
<dt><b>Effects:</b> Defines a legal combination of the special
attributes and methods:
<code>__getinitargs__</code>,
<code>__getstate__</code>,
<code>__setstate__</code>,
<code>__getstate_manages_dict__</code>,
<code>__safe_for_unpickling__</code>,
<code>__reduce__</code>
</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Provides an
<a href="pickle.html"
>easy to use high-level interface</a>
for establishing complete pickle support for the wrapped class.
The user is protected by compile-time consistency checks.</dt>
</dl>
<br>
<h3><a name="bases-spec"></a>Class template
<code>bases&lt;T1,&nbsp;T2,</code>...<code>TN&gt;</code></h3>
<p>An <a href="../../../mpl/doc/ref/Sequences.html">MPL sequence</a>
which can be used in <code>class_&lt;</code>...<code>&gt;</code>
instantiations indicate a list of base classes.</p>
<h4><a name="bases-spec-synopsis"></a>Class template <code>bases</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;T1 = <i>unspecified</i>,...T<i>n</i> = <i>unspecified</i>&gt;
struct bases
{};
}}
</pre>
<h2><a name="examples"></a>Example(s)</h2>
<p>Given a C++ class declaration:</p>
<pre>
class Foo : public Bar, public Baz
{
public:
Foo(int x, char const* y);
Foo(double);
std::string const&amp; name() { return m_name; }
void name(char const*);
double value; // public data
private:
...
};
</pre>
A corresponding Boost.Python extension class can be created with:
<pre>
using namespace boost::python;
class_&lt;Foo,bases&lt;Bar,Baz&gt; &gt;("Foo",
"This is Foo's docstring."
"It describes our Foo extension class",
init&lt;int,char const*&gt;(args("x","y"), "__init__ docstring")
)
.def(init&lt;double&gt;())
.def("get_name", &amp;Foo::get_name, return_internal_reference&lt;&gt;())
.def("set_name", &amp;Foo::set_name)
.def_readwrite("value", &amp;Foo::value)
;
</pre>
<hr>
<a name="footnote_1">[1]</a> By "previously-exposed" we mean that the for
each <code>B</code> in <code>bases</code>, an instance of
<code>class_&lt;B<font color="#007F00">, ...</font>&gt;</code> must have
already been constructed.
<pre>
class_&lt;Base&gt;("Base");
class_&lt;Derived, bases&lt;Base&gt; &gt;("Derived");
</pre>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,141 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Configuration</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Configuration</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#app-defined">Application Defined Macros</a></dt>
<dt><a href="#lib-defined-impl">Library Defined Implementation
Macros</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p><b>Boost.Python</b> uses several configuration macros in <a href=
"http://www.boost.org/libs/config/config.htm">&lt;boost/config.hpp&gt;</a>,
as well as configuration macros meant to be supplied by the application.
These macros are documented here.</p>
<h2><a name="app-defined"></a>Application Defined Macros</h2>
<p>These are the macros that may be defined by an application using
<b>Boost.Python</b>. Note that if you extend a strict interpretation of the C++
standard to cover dynamic libraries, using different values of these
macros when compiling different libraries (including extension modules
and the <b>Boost.Python</b> library itself) is a violation of the <a href=
"definitions.html#ODR">ODR</a>. However, we know of no C++
implementations on which this particular violation is detectable or
causes any problems.</p>
<table summary="application defined macros" width="100%" cellpadding=
"10">
<tr>
<th align="left"><b>Macro</b></td>
<th><b>Default</b></td>
<th align="left"><b>Meaning</b></td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_MAX_ARITY</code></td>
<td valign="top" align="center">15</td>
<td valign="top">The maximum <a href="definitions.html#arity">arity</a> of any
function, member function, or constructor to be wrapped, invocation
of a <b>Boost.Python</b> function wich is specified as taking arguments
<code>x1,&nbsp;x2,</code>...<code>X</code><i>n</i>. This includes, in
particular, callback mechanisms such as <code><a href=
"object.html#object-spec">object</a>::operator()(</code>...<code>)</code>
or <code><a href=
"call_method.html#call_method-spec">call_method</a>&lt;R&gt;(</code>...<code>
)</code>.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_MAX_BASES</code></td>
<td valign="top" align="center">10</td>
<td valign="top">The maximum number of template arguments to the <code><a href=
"class.html#bases-spec">bases</a>&lt;</code>...<code>&gt;</code>
class template, which is used to specify the bases of a wrapped C++
class..</td>
</tr>
</table>
<h2><a name="lib-defined-impl"></a>Library Defined Implementation
Macros</h2>
<p>These macros are defined by <b>Boost.Python</b> and are
implementation details of interest only to implementors and those porting
to new platforms.</p>
<table summary="library defined implementation macros" width="100%"
cellpadding="10">
<tr>
<th align="left"><b>Macro</b></td>
<th><b>Default</b></td>
<th align="left"><b>Meaning</b></td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_TYPE_ID_NAME</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, this indicates that the type_info comparison across
shared library boundaries does not work on this platform. In other
words, if shared-lib-1 passes <code>typeid(T)</code> to a function in
shared-lib-2 which compares it to <code>typeid(T)</code>, that
comparison may return <code>false</code>. If this macro is #defined,
Boost.Python uses and compares <code>typeid(T).name()</code> instead
of using and comparing the <code>std::type_info</code> objects
directly.</td>
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,147 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/copy_const_reference.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/copy_const_reference.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#copy_const_reference-spec">Class
<code>copy_const_reference</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#copy_const_reference-spec-synopsis">Class
<code>copy_const_reference</code> synopsis</a></dt>
<dt><a href="#copy_const_reference-spec-metafunctions">Class
<code>copy_const_reference</code> metafunctions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="copy_const_reference-spec"></a>Class
<code>copy_const_reference</code></h3>
<p><code>copy_const_reference</code> is a model of <a href=
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
which can be used to wrap C++ functions returning a reference-to-const
type such that the referenced value is copied into a new Python
object.</p>
<h4><a name="copy_const_reference-spec-synopsis"></a>Class
<code>copy_const_reference</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
struct copy_const_reference
{
template &lt;class T&gt; struct apply;
};
}}
</pre>
<h4><a name="copy_const_reference-spec-metafunctions"></a>Class
<code>copy_const_reference</code> metafunctions</h4>
<pre>
template &lt;class T&gt; struct apply
</pre>
<dl class="metafunction-semantics">
<dt><b>Requires:</b> <code>T</code> is <code>U const&amp;</code> for
some <code>U</code>.</dt>
<dt><b>Returns:</b> <code>typedef <a href=
"to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T&gt;
type;</code></dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<h3>C++ Module Definition</h3>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/copy_const_reference.hpp&gt;
#include &lt;boost/python/return_value_policy.hpp&gt;
// classes to wrap
struct Bar { int x; }
struct Foo {
Foo(int x) : { b.x = x; }
Bar const&amp; get_bar() const { return b; }
private:
Bar b;
};
// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE(my_module)
{
class_&lt;Bar&gt;("Bar");
class_&lt;Foo&gt;("Foo", init&lt;int&gt;())
.def("get_bar", &amp;Foo::get_bar
, return_value_policy&lt;copy_const_reference&gt;())
;
}
</pre>
<h3>Python Code</h3>
<pre>
&gt;&gt;&gt; from my_module import *
&gt;&gt;&gt; f = Foo(3) # create a Foo object
&gt;&gt;&gt; b = f.get_bar() # make a copy of the internal Bar object
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,147 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/copy_non_const_reference.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/copy_non_const_reference.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#copy_non_const_reference-spec">Class
<code>copy_non_const_reference</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#copy_non_const_reference-spec-synopsis">Class
<code>copy_non_const_reference</code> synopsis</a></dt>
<dt><a href=
"#copy_non_const_reference-spec-metafunctions">Class
<code>copy_non_const_reference</code> metafunctions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="copy_non_const_reference-spec"></a>Class
<code>copy_non_const_reference</code></h3>
<p><code>copy_non_const_reference</code> is a model of <a href=
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
which can be used to wrap C++ functions returning a
reference-to-non-const type such that the referenced value is copied into
a new Python object.</p>
<h4><a name="copy_non_const_reference-spec-synopsis"></a>Class
<code>copy_non_const_reference</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
struct copy_non_const_reference
{
template &lt;class T&gt; struct apply;
};
}}
</pre>
<h4><a name="copy_non_const_reference-spec-metafunctions"></a>Class
<code>copy_non_const_reference</code> metafunctions</h4>
<pre>
template &lt;class T&gt; struct apply
</pre>
<dl class="metafunction-semantics">
<dt><b>Requires:</b> <code>T</code> is <code>U&amp;</code> for some
non-const <code>U</code>.</dt>
<dt><b>Returns:</b> <code>typedef <a href=
"to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T&gt;
type;</code></dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<p>C++ code:</p>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/copy_non_const_reference.hpp&gt;
#include &lt;boost/python/return_value_policy.hpp&gt;
// classes to wrap
struct Bar { int x; }
struct Foo {
Foo(int x) : { b.x = x; }
Bar&amp; get_bar() { return b; }
private:
Bar b;
};
// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE(my_module)
{
class_&lt;Bar&gt;("Bar");
class_&lt;Foo&gt;("Foo", init&lt;int&gt;())
.def("get_bar", &amp;Foo::get_bar
, return_value_policy&lt;copy_non_const_reference&gt;())
;
}
</pre>
Python Code:
<pre>
&gt;&gt;&gt; from my_module import *
&gt;&gt;&gt; f = Foo(3) # create a Foo object
&gt;&gt;&gt; b = f.get_bar() # make a copy of the internal Bar object
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,167 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/data_members.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/data_members.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#make_getter-spec">make_getter</a></dt>
<dt><a href="#make_setter-spec">make_setter</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code><a href="#make_getter-spec">make_getter</a>()</code> and
<code><a href="#make_setter-spec">make_setter</a>()</code> are the
functions used internally by <code>class_&lt;&gt;::<a href=
"class.html#class_-spec-modifiers">def_readonly</a></code> and
<code>class_&lt;&gt;::<a href=
"class.html#class_-spec-modifiers">def_readwrite</a></code> to produce
Python callable objects which wrap C++ data members.</p>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="make_getter-spec">template &lt;class C, class D&gt;</a>
<a href="object.html#object-spec">object</a> make_getter(D C::*pm);
template &lt;class C, class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_getter(D C::*pm, Policies const&amp; policies);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>Effects:</b> Creates a Python callable object which accepts a
single argument that can be converted <code>from_python</code> to
<code>C*</code>, and returns the corresponding member <code>D</code>
member of the <code>C</code> object, converted <code>to_python</code>.
If <code>policies</code> is supplied, it will be applied to the
function as described <a href="CallPolicies.html">here</a>. Otherwise,
the library attempts to determine whether <code>D</code> is a
user-defined class type, and if so uses <code><a href=
"return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a>&lt;&gt;</code></dt>
<dt>for <code>Policies</code>. Note that this test may inappropriately
choose <code>return_internal_reference&lt;&gt;</code> in some cases
when <code>D</code> is a smart pointer type. This is a known
defect.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<pre>
<a name="make_setter-spec">template &lt;class C, class D&gt;</a>
<a href="object.html#object-spec">object</a> make_setter(D C::*pm);
template &lt;class C, class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_setter(D C::*pm, Policies const&amp; policies);
</pre>
<dl class="function*-semantics">
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>Effects:</b> Creates a Python callable object which, when called
from Python, expects two arguments which can be converted
<code>from_python</code> to <code>C*</code> and
<code>D&nbsp;const&amp;</code>, respectively, and sets the
corresponding <code>D</code> member of the <code>C</code> object. If
<code>policies</code> is supplied, it will be applied to the function
as described <a href="CallPolicies.html">here</a>.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<p>The code below uses make_getter and make_setter to expose a data
member as functions:</p>
<pre>
#include &lt;boost/python/data_members.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
struct X
{
X(int x) : y(x) {}
int y;
};
using namespace boost::python;
BOOST_PYTHON_MODULE_INIT(data_members_example)
{
class_&lt;X&gt;("X", init&lt;int&gt;())
.def("get", make_getter(&amp;X::y))
.def("set", make_setter(&amp;X::y))
;
}
</pre>
It can be used this way in Python:
<pre>
&gt;&gt;&gt; from data_members_example import *
&gt;&gt;&gt; x = X(1)
&gt;&gt;&gt; x.get()
1
&gt;&gt;&gt; x.set(2)
&gt;&gt;&gt; x.get()
2
</pre>
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,196 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/def.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/def.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#def-spec">def</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code><a href="#def-spec">def</a>()</code> is the function which can
be used to expose C++ functions and callable objects as Python functions
in the current <code><a href="scope.html">scope</a></code>.</p>
<h2><a name="functions"></a>Functions</h2>
<a name="def-spec"></a>def
<pre>
template &lt;class F&gt;
void def(char const* name, F f);
template &lt;class Fn, class A1&gt;
void def(char const* name, Fn fn, A1 const&amp;);
template &lt;class Fn, class A1, class A2&gt;
void def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;);
template &lt;class Fn, class A1, class A2, class A3&gt;
void def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.</dt>
<dd>
<ul>
<li>
If <code>a1</code> is the result of an <a href=
"overloads.html#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>,
only the second form is allowed and fn must be a pointer to
function or pointer to member function whose <a href=
"definitions.html#arity">arity</a> is the same as A1's <a href=
"overloads.html#overload-dispatch-expression"><em>maximum
arity</em></a>.
<dl>
<dt><b>Effects:</b> For each prefix <em>P</em> of
<code>Fn</code>'s sequence of argument types, beginning with
the one whose length is <code>A1</code>'s <a href=
"overloads.html#overload-dispatch-expression"><em>minimum
arity</em></a>, adds a
<code><em>name</em>(</code>...<code>)</code> function overload
to the <a href="scope.html">current scope</a>. Each overload
generated invokes <code>a1</code>'s call-expression with
<em>P</em>, using a copy of <code>a1</code>'s <a href=
"CallPolicies.html">call policies</a>. If the longest valid
prefix of <code>A1</code> contains <em>N</em> types and
<code>a1</code> holds <em>M</em> keywords, an initial sequence
of the keywords are used for all but the first
<em>N</em>&nbsp;-&nbsp;<em>M</em> arguments of each
overload.<br>
</dt>
</dl>
</li>
<li>
Otherwise, a single function overload built around fn (which must
not be null) is added to the <a href="scope.html">current
scope</a>:
<ul>
<li>If fn is a function or member function pointer,
<code>a1</code>-<code>a3</code> (if supplied) may be selected
in any order from the table below.</li>
<li>Otherwise, <code>Fn</code> must be [derived from] <code><a
href="object.html#object-spec">object</a></code>, and
<code>a1-a2</code> (if supplied) may be selcted in any order
from the first two rows of the table below. To be useful,
<code>fn</code> should be <a href=
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">
callable</a>.</li>
</ul>
<table border="1" summary="def() optional arguments">
<tr>
<th>Memnonic Name</th>
<th>Requirements/Type properties</th>
<th>Effects</th>
</tr>
<tr>
<td>docstring</td>
<td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
<td>Value will be bound to the <code>__doc__</code> attribute
of the resulting method overload.</td>
</tr>
<tr>
<td>policies</td>
<td>A model of <a href=
"CallPolicies.html">CallPolicies</a></td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
<tr>
<td>keywords</td>
<td>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>fn</code>.</td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
</table>
</li>
</ul>
</dd>
</dl>
<h2><a name="examples"></a>Example</h2>
<pre>
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/args.hpp&gt;
char const* foo(int x, int y) { return "foo"; }
BOOST_PYTHON_MODULE(def_test)
{
def("foo", foo, args("x", "y"), "foo's docstring");
}
</pre>
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,170 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/default_call_policies.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/default_call_policies.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#default_call_policies-spec">Class
<code>default_call_policies</code></a>
<dd>
<dl class="page-index">
<dt><a href="#default_call_policies-spec-synopsis">Class
<code>default_call_policies</code> synopsis</a>
<dt><a href="#default_call_policies-spec-statics">Class
<code>default_call_policies</code> static functions</a>
</dl>
<dt><a href="#default_result_converter-spec">Class
<code>default_result_converter</code></a>
<dd>
<dl class="page-index">
<dt><a href="#default_result_converter-spec-synopsis">Class
<code>default_result_converter</code> synopsis</a>
<dt><a href="#default_result_converter-spec-metafunctions">Class
<code>default_result_converter</code> metafunctions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="default_call_policies-spec"></a>Class
<code>default_call_policies</code></h3>
<p><code>default_call_policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a> with no <code>precall</code> or
<code>postcall</code> behavior and a <code>result_converter</code> which
handles by-value returns. Wrapped C++ functions and member functions use
<code>default_call_policies</code> unless otherwise specified. You may find
it convenient to derive new models of <a href=
"CallPolicies.html">CallPolicies</a> from
<code>default_call_policies</code>.
<h4><a name="default_call_policies-spec-synopsis"></a>Class
<code>default_call_policies</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
struct default_call_policies
{
static bool precall(PyObject*);
static PyObject* postcall(PyObject*, PyObject* result);
typedef <a href=
"#default_result_converter-spec">default_result_converter</a> result_converter;
};
}}
</pre>
<h4><a name="default_call_policies-spec-statics"></a>Class
<code>default_call_policies</code> static functions</h4>
<pre>
bool precall(PyObject*);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>true</code>
<dt><b>Throws:</b> nothing
</dl>
<pre>
PyObject* postcall(PyObject*, PyObject* result);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>result</code>
<dt><b>Throws:</b> nothing
</dl>
<h3><a name="default_result_converter-spec"></a>Class
<code>default_result_converter</code></h3>
<p><code>default_result_converter</code> is a model of <a href=
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a> which can be
used to wrap C++ functions returning non-pointer types, <code>char
const*</code>, and <code>PyObject*</code>, by-value.
<h4><a name="default_result_converter-spec-synopsis"></a>Class
<code>default_result_converter</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
struct default_result_converter
{
template &lt;class T&gt; struct apply;
};
}}
</pre>
<h4><a name="default_result_converter-spec-metafunctions"></a>Class
<code>default_result_converter</code> metafunctions</h4>
<pre>
template &lt;class T&gt; struct apply
</pre>
<dl class="metafunction-semantics">
<dt><b>Requires:</b> <code>T</code> is not a reference type. If
<code>T</code> is a pointer type, <code>T</code> is <code>const
char*</code> or <code>PyObject*</code>.
<dt><b>Returns:</b> <code>typedef <a href=
"to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T
const&amp;&gt; type;</code>
</dl>
<h2><a name="examples"></a>Example</h2>
<p>This example comes from the Boost.Python implementation itself. Because
the <a href=
"return_value_policy.html#return_value_policy-spec">return_value_policy</a>
class template does not implement <code>precall</code> or
<code>postcall</code> behavior, its default base class is
<code>default_call_policies</code>:
<pre>
template &lt;class Handler, class Base = default_call_policies&gt;
struct return_value_policy : Base
{
typedef Handler result_converter;
};
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>

View File

@@ -1,100 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Definitions</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Definitions</h2>
</td>
</tr>
</table>
<hr>
<dl class="definitions">
<dt><b><a name="arity">arity</a>:</b> The number of arguments accepted
by a function or member function. Unless otherwise specified, the
hidden "<code>this</code>" argument to member functions is not counted
when specifying arity</dt>
<dd><br>
</dd>
<dt><b><a name="ntbs">ntbs</a>:</b> Null-Terminated Byte String, or
`C'-string. C++ string literals are <strong>ntbs</strong>es. An
<strong>ntbs</strong> must never be null.</dt>
<dd><br>
</dd>
<dt><b><a name="raise">raise</a>:</b> Exceptions in Python are
"raised", not "thrown", as they are in C++. When this documentation
says that some Python exception is "raised" in the context of C++ code,
it means that the corresponding Python exception is set via the <a
href=
"http://www.python.org/doc/current/api/exceptionHandling.html">Python/'C'
API</a>, and <code><a href=
"errors.html#throw_error_already_set-spec">throw_error_already_set</a>()</code>
is called.</dt>
<dd><br>
</dd>
<dt><b><a name="POD">POD</a>:</b> A technical term from the C++
standard. Short for "Plain Ol'Data": A POD-struct is an aggregate class
that has no non-static data members of type pointer to member,
non-POD-struct, non-POD-union (or array of such types) or reference,
and has no user-defined copy assign- ment operator and no user-defined
destructor. Similarly, a POD-union is an aggregate union that has no
non-static data members of type pointer to member, non-POD-struct,
non-POD-union (or array of such types) or reference, and has no
user-defined copy assignment operator and no user-defined destructor. A
POD class is a class that is either a POD-struct or a POD-union. An
aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions
(10.3).</dt>
<dd><br>
</dd>
<dt><b><a name="ODR">ODR</a>:</b> The &quot;One Definition
Rule&quot;, which says that any entity in a C++ program must have the same definition in all translation units (object files) which make up a program.
</dt>
<dd><br>
</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,150 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/dict.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/dict.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#dict-spec">Class <code>dict</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#dict-spec-synopsis">Class <code>dict</code>
synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
<a href=
"http://www.python.org/dev/doc/devel/lib/typesmapping.html">dict</a>
type.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="dict-spec"></a>Class <code>dict</code></h3>
<p>Exposes the <a href=
"http://www.python.org/dev/doc/devel/lib/typesmapping.html">mapping
protocol</a> of Python's built-in <code>dict</code> type. The semantics
of the constructors and member functions defined below can be fully
understood by reading the <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
definition. Since <code>dict</code> is publicly derived from <code><a
href="object.html#object-spec">object</a></code>, the public object
interface applies to <code>dict</code> instances as well.</p>
<h4><a name="dict-spec-synopsis"></a>Class <code>dict</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
class dict : public object
{
dict();
template&lt; class T &gt;
dict(T const &amp; data);
// modifiers
void clear();
dict copy();
template &lt;class T1, class T2&gt;
tuple popitem();
template &lt;class T&gt;
object setdefault(T const &amp;k);
template &lt;class T1, class T2&gt;
object setdefault(T1 const &amp; k, T2 const &amp; d);
void update(object_cref E);
template&lt; class T &gt;
void update(T const &amp; E);
// observers
list values() const;
object get(object_cref k) const;
template&lt;class T&gt;
object get(T const &amp; k) const;
object get(object_cref k, object_cref d) const;
object get(T1 const &amp; k, T2 const &amp; d) const;
bool has_key(object_cref k) const;
template&lt; class T &gt;
bool has_key(T const &amp; k) const;
list items() const;
object iteritems() const;
object iterkeys() const;
object itervalues() const;
list keys() const;
};
}}
</pre>
<h2><a name="examples"></a>Example</h2>
<pre>
using namespace boost::python;
dict swap_object_dict(object target, dict d)
{
dict result = extract&lt;dict&gt;(target.attr("__dict__"));
target.attr("__dict__") = d;
return result;
}
</pre>
<p>Revised 30 September, 2002</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,204 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/enum.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/enum.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#enum_-spec">Class template
<code>enum_</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#enum_-spec-synopsis">Class template <code>enum_</code>
synopsis</a></dt>
<dt><a href="#enum_-spec-ctors">Class template <code>enum_</code>
constructors</a></dt>
<dt><a href="#enum_-spec-modifiers">Class template <code>enum_</code>
modifier functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/enum.hpp&gt;</code> defines the
interface through which users expose their C++ enumeration types
to Python. It declares the
<code>enum_</code> class template, which is parameterized on the
enumeration type being exposed. </p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="enum_-spec"></a>Class template
<code>enum_&lt;T&gt;</code></h3>
<p>Creates a Python class derived from Python's <code>int</code>
type which is associated with the C++ type passed as its first
parameter.
<h4><a name="enum_-spec-synopsis"></a>Class template <code>enum_</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T&gt;
class enum_ : public <a href="object.html#object-spec">object</a>
{
enum_(char const* name);
inline enum_&lt;T&gt;&amp; value(char const* name, T);
};
}}
</pre>
<h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
constructors</h4>
<pre>
enum_(char const* name);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.
<dt><b>Effects:</b> Constructs an <code>enum_</code> object
holding a Python extension type derived from <code>int</code>
which is named <code>name</code>. The
<code>name</code>d attribute of the <a href=
"scope.html#introduction">current scope</a> is bound to the new
extension type.</dt>
</dl>
<h4><a name="enum_-spec-modifiers"></a>Class template
<code>enum_</code> modifier functions</h4>
<pre>
inline enum_&lt;T&gt;&amp; value(char const* name, T x);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a
href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.
<dt><b>Effects:</b> adds an instance of the wrapped enumeration
type with value <code>x</code> to the type's dictionary as the
<code>name</code>d attribute</dt>.
<dt><b>Returns:</b> <code>*this</code></dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
<p>C++ module definition
<pre>
#include &lt;boost/python/enum.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
using namespace boost::python;
enum color { red = 1, green = 2, blue = 4 };
color identity_(color x) { return x; }
BOOST_PYTHON_MODULE(enums)
{
enum_&lt;color&gt;(&quot;color&quot;)
.value(&quot;red&quot;, red)
.value(&quot;green&quot;, green)
.value(&quot;blue&quot;, blue)
;
def(&quot;identity&quot;, identity_);
}
</pre>
<p>Interactive Python:
<pre>
&gt;&gt;&gt; from enums import *
&gt;&gt;&gt; identity(color.red)
enums.color.red
&gt;&gt;&gt; identity(color.green)
enums.color.green
&gt;&gt;&gt; identity(color.blue)
enums.color.blue
&gt;&gt;&gt; identity(color(1))
enums.color.red
&gt;&gt;&gt; identity(color(2))
enums.color.green
&gt;&gt;&gt; identity(color(3))
enums.color(3)
&gt;&gt;&gt; identity(color(4))
enums.color.blue
&gt;&gt;&gt; identity(1)
Traceback (most recent call last):
File &quot;&lt;stdin&gt;&quot;, line 1, in ?
TypeError: bad argument type for built-in operation
</pre>
<hr>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,287 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/errors.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/errors.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#error_already_set-spec">Class
<code>error_already_set</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#error_already_set-spec-synopsis">Class
<code>error_already_set</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#handle_exception-spec">handle_exception</a></dt>
<dt><a href="#expect_non_null-spec">expect_non_null</a></dt>
<dt><a href=
"#throw_error_already_set-spec">throw_error_already_set</a></dt>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/errors.hpp&gt;</code> provides types and
functions for managing and translating between Python and C++ exceptions.
This is relatively low-level functionality that is mostly used internally
by Boost.Python. Users should seldom need it.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="error_already_set-spec"></a>Class
<code>error_already_set</code></h3>
<p><code>error_already_set</code> is an exception type which can be
thrown to indicate that a Python error has occurred. If thrown, the
precondition is that <a href=
"http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred()</a>
returns a value convertible to <code>true</code>. Portable code shouldn't
throw this exception type directly, but should instead use <code><a href=
"#throw_error_already_set-spec">throw_error_already_set</a>()</code>,
below.</p>
<h4><a name="error_already_set-spec-synopsis"></a>Class error_already_set
synopsis</h4>
<pre>
namespace boost { namespace python
{
class error_already_set {};
}}
</pre>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name=
"handle_exception-spec">template &lt;class T&gt; bool handle_exception</a>(T f) throw();
void handle_exception() throw();
</pre>
<dl class="handle_exception-semantics">
<dt><b>Requires:</b> The first form requires that the expression
<code><a href=
"../../../function/doc/reference.html#functionN">function0</a>&lt;void&gt;(f)</code>
is valid. The second form requires that a C++ exception is currently
being handled (see section 15.1 in the C++ standard).</dt>
<dt><b>Effects:</b> The first form calls <code>f()</code> inside a
<code>try</code> block which first attempts to use all registered <a
href="exception_translator.html">exception translators</a>. If none of
those translates the exception, the <code>catch</code> clauses then set
an appropriate Python exception for the C++ exception caught, returning
<code>true</code> if an exception was thrown, <code>false</code>
otherwise. The second form passes a function which rethrows the
exception currently being handled to the first form.</dt>
<dt><b>Postconditions:</b> No exception is being handled</dt>
<dt><b>Throws:</b> nothing</dt>
<dt><b>Rationale:</b> At inter-language boundaries it is important to
ensure that no C++ exceptions escape, since the calling language
usually doesn't have the equipment neccessary to properly unwind the
stack. Use <code>handle_exception</code> to manage exception
translation whenever your C++ code is called directly from the Python
API. This is done for you automatically by the usual function wrapping
facilities: <code><a href=
"make_function.html#make_function-spec">make_function</a>()</code>,
<code><a href=
"make_function.html#make_constructor-spec">make_constructor</a>()</code>,
<code><a href="def.html#def-spec">def</a>()</code> and <code><a href=
"class.html#def-spec">class_::def</a>()</code>. The second form can be
more convenient to use (see the <a href="#examples">example</a> below),
but various compilers have problems when exceptions are rethrown from
within an enclosing <code>try</code> block.</dt>
</dl>
<pre>
<a name=
"expect_non_null-spec">template &lt;class T&gt; T* expect_non_null(T* x);</a>
</pre>
<dl class="expect_non_null-semantics">
<dt><b>Returns:</b> <code>x</code></dt>
<dt><b>Throws:</b> <code><a href=
"#error_already_set-spec">error_already_set</a>()</code> iff <code>x ==
0</code>.</dt>
<dt><b>Rationale:</b> Simplifies error-handling when calling functions
in the <a href="http://www.python.org/doc/2.2/api/api.html">Python/C
API</a> which return 0 on error.</dt>
</dl>
<pre>
<a name="throw_error_already_set-spec">void throw_error_already_set();</a>
</pre>
<dl class="throw_error_already_set-semantics">
<dt><b>Effects:</b> <code>throw&nbsp;<a href=
"#error_already_set-spec">error_already_set</a>();</code></dt>
</dl>
<dl>
<dt><b>Rationale:</b> Many platforms and compilers are not able to
consistently catch exceptions thrown across shared library boundaries.
Using this function from the Boost.Python library ensures that the
appropriate <code>catch</code> block in <code><a href=
"#handle_exception-spec">handle_exception</a>()</code> can catch the
exception.</dt>
</dl>
<h2><a name="examples"></a>Examples</h2>
<pre>
#include &lt;string&gt;
#include &lt;boost/python/errors.hpp&gt;
#include &lt;boost/python/object.hpp&gt;
#include &lt;boost/python/handle.hpp&gt;
// Returns a std::string which has the same value as obj's "__name__"
// attribute.
std::string get_name(boost::python::object obj)
{
// throws if there's no __name__ attribute
PyObject* p = boost::python::expect_non_null(
PyObject_GetAttrString(obj.ptr(), "__name__"));
char const* s = PyString_AsString(p);
if (s != 0)
Py_DECREF(p);
// throws if it's not a Python string
std::string result(
boost::python::expect_non_null(
PyString_AsString(p)));
Py_DECREF(p); // Done with p
return result;
}
//
// Demonstrate form 1 of handle_exception
//
// Place into result a Python Int object whose value is 1 if a and b have
// identical "__name__" attributes, 0 otherwise.
void same_name_impl(PyObject*&amp; result, boost::python::object a, boost::python::object b)
{
result = PyInt_FromLong(
get_name(a) == get_name(a2));
}
object borrowed_object(PyObject* p)
{
return boost::python::object(
boost::python::handle&lt;&gt;(
boost::python::borrowed(a1)));
}
// This is an example Python 'C' API interface function
extern "C" PyObject*
same_name(PyObject* args, PyObject* keywords)
{
PyObject* a1;
PyObject* a2;
PyObject* result = 0;
if (!PyArg_ParseTuple(args, const_cast&lt;char*&gt;("OO"), &amp;a1, &amp;a2))
return 0;
// Use boost::bind to make an object compatible with
// boost::Function0&lt;void&gt;
if (boost::python::handle_exception(
boost::bind&lt;void&gt;(same_name_impl, boost::ref(result), borrowed_object(a1), borrowed_object(a2))))
{
// an exception was thrown; the Python error was set by
// handle_exception()
return 0;
}
return result;
}
//
// Demonstrate form 2 of handle_exception. Not well-supported by all
// compilers.
//
extern "C" PyObject*
same_name2(PyObject* args, PyObject* keywords)
{
PyObject* a1;
PyObject* a2;
PyObject* result = 0;
if (!PyArg_ParseTuple(args, const_cast&lt;char*&gt;("OO"), &amp;a1, &amp;a2))
return 0;
try {
return PyInt_FromLong(
get_name(borrowed_object(a1)) == get_name(borrowed_object(a2)));
}
catch(...)
{
// If an exception was thrown, translate it to Python
boost::python::handle_exception();
return 0;
}
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,148 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/exception_translator.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/exception_translator.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href=
"#register_exception_translator-spec">register_exception_translator</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>As described <a href="errors.html#handle_exception-spec">here</a>, it
is important to make sure that exceptions thrown by C++ code do not pass
into the Python interpreter core. By default, Boost.Python translates all
C++ exceptions thrown by wrapped functions and module init functions into
Python, but the default translators are extremely limited: most C++
exceptions will appear in Python as a <a href=
"http://www.python.org/doc/current/lib/module-exceptions.html">RuntimeError</a>
exception whose representation is
<code>'Unidentifiable&nbsp;C++&nbsp;Exception'</code>. To produce better
error messages, users can register additional exception translators as
described below.</p>
<h2><a name="functions"></a>Functions</h2>
<h3><code><a name="register_exception_translator-spec">register_exception_translator</a></code></h3>
<pre>
<a name="register_exception_translator-spec">template&lt;class ExceptionType, class Translate&gt;</a>
void register_exception_translator(Translate const&amp; translate);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b></dt>
<dd>
<code>Translate</code> is <a href=
"../../../utility/CopyConstructible.html">Copyconstructible</a>, and
the following code must be well-formed:
<pre>
void f(ExceptionType x) { translate(x); }
</pre>
The expression <code>translate(x)</code> must either throw a C++
exception, or a subsequent call to <code><a href=
"http://www.python.org/doc/current/api/exceptionHandling.html">PyErr_Occurred</a>()</code>
must return 1.
</dd>
<p>
<dt><b>Effects:</b> Adds a copy of <code>translate</code> to the sequence of
exception translators tried when Boost.Python catches an exception that
is about to pass into Python's core interpreter. The new translator
will get "first shot" at translating all exceptions matching the catch
clause shown above. Any subsequently-registered translators will be
allowed to translate the exception earlier. A translator which cannot
translate a given C++ exception can re-throw it, and it will be handled
by a translator which was registered earlier (or by the default
translator).</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/exception_translator.hpp&gt;
#include &lt;exception&gt;
struct my_exception : std::exception
{
char const* what() throw() { return "One of my exceptions"; }
};
void translate(my_exception const&amp; e)
{
// Use the Python 'C' API to set up an exception object
PyErr_SetString(PyExc_RuntimeError, e.what());
}
void something_which_throws()
{
...
throw my_exception();
...
}
BOOST_PYTHON_MODULE(exception_translator_ext)
{
using namespace boost::python;
register_exception_translator&lt;my_exception&gt;(&amp;translate);
def("something_which_throws", something_which_throws);
}
</pre>
<br>
<br>
<hr>
<p>Revised 03 October, 2002</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,230 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/extract.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/extract.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#extract-spec">Class <code>extract</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#extract-spec-synopsis">Class <code>extract</code>
synopsis</a></dt>
<dt><a href="#extract-spec-ctors">Class <code>extract</code>
constructors and destructor</a></dt>
<dt><a href="#extract-spec-observers">Class
<code>extract</code> observer functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a mechanism for extracting C++ object values from
generalized Python objects. Note that
<code>extract&lt;</code>...<code>&gt;</code> can also be used to
&quot;downcast&quot; an <a
href="object.html#object-spec">object</a> to some specific <a
href="ObjectWrapper.html#ObjectWrapper-concept">ObjectWrapper</a>. Because
invoking a mutable python type with an argument of the same type
(e.g. <code>list([1,2])</code> typically makes a <em>copy</em> of
the argument object, this may be the only way to access the <a
href="ObjectWrapper.html#ObjectWrapper-concept">ObjectWrapper</a>'s
interface on the original object.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="extract-spec"></a>Class template <code>extract</code></h3>
<p><code>extract&lt;T&gt;</code> can be used to extract a value of
an arbitrary C++ type from an instance of <code><a
href="object.html#object-spec">object</a></code>. Two usages are supported:
<ol>
<li><b><code>extract&lt;T&gt;(o)</code></b> is a temporary object
which is implicitly convertible to <code>T</code> (explicit conversion
is also available through the object's function-call
operator). However, if no conversion is available which can convert
<code>o</code> to an object of type <code>T</code>, a Python
<code>TypeError</code> exception will be <a
href="definitions.html#raise">raised</a>.
<li><b><code>extract&lt;T&gt; x(o);</code></b> constructs an extractor
whose <code>check()</code> member function can be used to ask whether
a conversion is available without causing an exception to be thrown.
</ol>
<h4><a name="extract-spec-synopsis"></a>Class template <code>extract</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T&gt;
struct extract
{
typedef <i>unspecified</i> result_type;
extract(PyObject*);
extract(object const&amp;);
result_type operator()() const;
operator result_type() const;
bool check() const;
};
}}
</pre>
<h4><a name="extract-spec-ctors"></a>Class <code>extract</code>
constructors and destructor</h4>
<pre>
extract(PyObject* p);
extract(object const&amp;);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The first form requires that <code>p</code> is non-null.</dt>
<dt><b>Effects:</b>Stores a pointer to the Python object managed
by its constructor argument. In particular, the reference
count of the object is not incremented. The onus is on the user
to be sure it is not destroyed before the extractor's conversion
function is called.</dt>
</dl>
<h4><a name="extract-spec-observers"></a>Class <code>extract</code>
observer functions</h4>
<pre>
result_type operator()() const;
operator result_type() const;
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Converts the stored pointer to
<code>result_type</code>, which is either <code>T</code> or
<code>T const&amp;</code>.
</dt>
<dt><b>Returns:</b> An object of <code>result_type</code>
corresponding to the one referenced by the stored pointer.</dt>
<dt><b>Throws:</b> <code><a
href="errors.html#error_already_set-spec">error_already_set</a></code>
and sets a <code>TypeError</code> if no such conversion is
available. May also emit other unspecified exceptions thrown by
the converter which is actually used.</dt>
</dl>
<pre>
bool check() const;
</pre>
<dl class="function-semantics">
<dt><b>Postconditions:</b> None. In particular, note that a
return value of <code>true</code> does not preclude an exception
being thrown from <code>operator result_type()</code> or
<code>operator()()</code>.</dt>
<dt><b>Returns:</b> <code>false</code> <i>only</i> if no conversion from the
stored pointer to <code>T</code> is available.</dt>
</dl>
<h2><a name="examples"></a>Examples</h2>
<pre>
#include &lt;cstdio&gt;
using namespace boost::python;
int Print(str s)
{
// extract a C string from the Python string object
char const* c_str = extract&lt;char const*&gt;(s);
// Print it using printf
std::printf(&quot;%s\n&quot;, c_str);
// Get the Python string's length and convert it to an int
return extract&lt;int&gt;(s.attr(&quot;__len__&quot;)())
}
</pre>
The following example shows how extract can be used along with
<code><a
href="class.html#class_-spec">class_</a>&lt;</code>...<code>&gt;</code>
to create and access an instance of a wrapped C++ class.
<pre>
struct X
{
X(int x) : v(x) {}
int value() { return v; }
private:
int v;
};
BOOST_PYTHON_MODULE(extract_ext)
{
object x_class(
class_&lt;X&gt;(&quot;X&quot;, init&lt;int&gt;())
.def(&quot;value&quot;, &amp;X::value))
;
// Instantiate an X object through the Python interface.
// Its lifetime is now managed by x_obj.
object x_obj = x_class(3);
// Get a reference to the C++ object out of the Python object
X&amp; x = extract&lt;X&amp;&gt;(x_obj);
assert(x.value() == 3);
}
</pre>
<p>Revised 15 November, 2002</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,231 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - FAQ</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Frequently Asked Questions (FAQs)</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#question1">Is return_internal reference
efficient?</a></dt>
<dt><a href="#question2">How can I wrap containers which take C++
containers as arguments?</a></dt>
<dt><a href="#c1204">fatal error C1204:Compiler limit:internal
structure overflow</a></dt>
</dl>
<h2><a name="question1"></a>Is return_internal reference efficient?</h2>
<blockquote>
<b>Q:</b> <i>I have an object composed of 12 doubles. A const&amp; to
this object is returned by a member function of another class. From the
viewpoint of using the returned object in Python I do not care if I get
a copy or a reference to the returned object. In Boost.Python Version 2
I have the choice of using copy_const_reference or
return_internal_reference. Are there considerations that would lead me
to prefer one over the other, such as size of generated code or memory
overhead?</i>
<p><b>A:</b> copy_const_reference will make an instance with storage
for one of your objects, size = base_size + 12 * sizeof(double).
return_internal_reference will make an instance with storage for a
pointer to one of your objects, size = base_size + sizeof(void*).
However, it will also create a weak reference object which goes in the
source object's weakreflist and a special callback object to manage the
lifetime of the internally-referenced object. My guess?
copy_const_reference is your friend here, resulting in less overall
memory use and less fragmentation, also probably fewer total
cycles.</p>
</blockquote>
<h2><a name="question2"></a>How can I wrap functions which take C++
containers as arguments?</h2>
<p>Ralf W. Grosse-Kunstleve provides these notes:</p>
<ol>
<li>
Using the regular <code>class_&lt;&gt;</code> wrapper:
<pre>
class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
.def(...)
...
;
</pre>
This can be moved to a template so that several types (double, int,
long, etc.) can be wrapped with the same code. This technique is used
in the file
<blockquote>
scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h
</blockquote>
in the "scitbx" package. The file could easily be modified for
wrapping std::vector&lt;&gt; instantiations.
<p>This type of C++/Python binding is most suitable for containers
that may contain a large number of elements (&gt;10000).</p>
</li>
<li>
Using custom rvalue converters. Boost.Python "rvalue converters"
match function signatures such as:
<pre>
void foo(std::vector&lt;double&gt; const&amp; array); // pass by const-reference
void foo(std::vector&lt;double&gt; array); // pass by value
</pre>
Some custom rvalue converters are implemented in the file
<blockquote>
scitbx/include/scitbx/boost_python/container_conversions.h
</blockquote>
This code can be used to convert from C++ container types such as
std::vector&lt;&gt; or std::list&lt;&gt; to Python tuples and vice
versa. A few simple examples can be found in the file
<blockquote>
scitbx/array_family/boost_python/regression_test_module.cpp
</blockquote>
Automatic C++ container &lt;-&gt; Python tuple conversions are most
suitable for containers of moderate size. These converters generate
significantly less object code compared to alternative 1 above.
</li>
</ol>
A disadvantage of using alternative 2 is that operators such as
arithmetic +,-,*,/,% are not available. It would be useful to have custom
rvalue converters that convert to a "math_array" type instead of tuples.
This is currently not implemented but is possible within the framework of
Boost.Python V2 as it will be released in the next couple of weeks. [ed.:
this was posted on 2002/03/10]
<p>It would also be useful to also have "custom lvalue converters" such
as std::vector&lt;&gt; &lt;-&gt; Python list. These converters would
support the modification of the Python list from C++. For example:</p>
<p>C++:</p>
<pre>
void foo(std::vector&lt;double&gt;&amp; array)
{
for(std::size_t i=0;i&lt;array.size();i++) {
array[i] *= 2;
}
}
</pre>
Python:
<pre>
&gt;&gt;&gt; l = [1, 2, 3]
&gt;&gt;&gt; foo(l)
&gt;&gt;&gt; print l
[2, 4, 6]
</pre>
Custom lvalue converters require changes to the Boost.Python core library
and are currently not available.
<p>P.S.:</p>
<p>The "scitbx" files referenced above are available via anonymous
CVS:</p>
<pre>
cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
</pre>
<h2><a name="c1204"></a>fatal error C1204:Compiler limit:internal
structure overflow</h2>
<blockquote>
<b>Q:</b> <i>I get this error message when compiling a large source
file. What can I do?</i>
<p><b>A:</b> You have two choices:</p>
<ol>
<li>Upgrade your compiler (preferred)</li>
<li>
Break your source file up into multiple translation units.
<p><code><b>my_module.cpp</b></code>:</p>
<pre>
...
void more_of_my_module();
BOOST_PYTHON_MODULE(my_module)
{
def("foo", foo);
def("bar", bar);
...
more_of_my_module();
}
</pre>
<code><b>more_of_my_module.cpp</b></code>:
<pre>
void more_of_my_module()
{
def("baz", baz);
...
}
</pre>
If you find that a <code><a href=
"class.html#class_-spec">class_</a>&lt;...&gt;</code> declaration
can't fit in a single source file without triggering the error, you
can always pass a reference to the <code>class_</code> object to a
function in another source file, and call some of its member
functions (e.g. <code>.def(...)</code>) in the auxilliary source
file: <code>
<p><b>more_of_my_class.cpp</b></code>:
<pre>
void more_of_my_class(class&lt;my_class&gt;&amp; x)
{
x
.def("baz", baz)
.add_property("xx", &amp;my_class::get_xx, &amp;my_class::set_xx)
;
...
}
</pre>
</li>
</ol>
</blockquote>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,366 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - February 2002 Progress Report</title>
<style type="text/css">
:link { color: #0000ff }
:visited { color: #800080 }
p.c3 {font-style: italic}
h2.c2 {text-align: center}
h1.c1 {text-align: center}
</style>
<table border="0" cellpadding="7" cellspacing="0" width=
"100%" summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">February 2002 Progress Report</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="#Python10">Python10 Conference Report</a>
<dt><a href="#progress">Boost.Python v2 Progress</a>
<dd>
<dl class="index">
<dt><a href="#documentation">Documentation</a>
<dt><a href="#conversion">Overhaul of
<code>to_python</code>/<code>from_python</code>
conversion mechanism</a>
<dt><a href="#miscellaneous">Miscellaneous</a>
</dl>
</dl>
<h2><a name="Python10">Python10 Conference Report</a></h2>
I spent the first week of February at the Python10 conference
in Alexandria, VA. I&#39;m including this experience report
for two reasons: firstly, it documents where my time was
used. Secondly, a public presence for Boost.Python and
interaction between the Python and C++ communities is
important to the future of Boost.Python, which in turn is
important to the Kull Project.
<p>Andy Koenig, of all people, was the keynote speaker of
this year&#39;s opening plenary session. He presented his
&quot;impressions of a polyglot outsider&quot;, which
studiously avoided any mention of C++ until the end of his
talk, when he was asked about standardization. I was
surprised to learn that the C++ community at large wanted a
few more years before beginning but when ANSI accepted
HP&#39;s request for a standard, the process was forced to
start: it was a matter of participating or having
standardization proceed without one&#39;s input. Andy managed
to highlight very effectively the balance of strengths in
Python, one of the most important being its support for
extension via libraries. In many ways that makes Python a
good analogue for C++ in the interpreted world
<p>There were several kind mentions of the Boost.Python
library from people who found it indispensable. I was
particularly happy that Karl MacMillan, Michael Droettboom,
and Ichiro Fujinaga from Johns Hopkins is using it to do OCR
on a vast library of music notation, since in a previous life
I was an author of music notation software. These guys are
also drawing on Ullrich Koethe&#39;s VIGRA library for image
manipulation (Ullrich has been a major contributor to
Boost.Python). They also have a system for writing the
Boost.Python wrapper code in C++ comments, which allows them
to keep all of the code in one place. I&#39;ve asked them to
send me some information on that.
<p>The development of Swig has been gaining momentum again
(the basic description at
www.boost.org/libs/python/doc/comparisons.html still
applies). The talk given about it by David Beazly was very
well-attended, and they appear to have quite a few users.
Swig&#39;s strengths (coverage of many langauages) and
weaknesses (incomplete C++ language support) haven&#39;t
changed, although the C++ support seems to have improved
considerably - they now claim to have a complete model of the
C++ type system. It seems to be mostly geared at wrapping
what Walter Landry calls &quot;C-Tran&quot;: C++ code which
traffics in built-in types with little use of abstraction.
I&#39;m not knocking that, either: I&#39;m sure a lot of that
code exists, so it&#39;s a valuable service. One feature Swig
has which I&#39;d like to steal is the ability to unwrap a
single Python argument into multiple C++ arguments, for
example, by converting a Python string into a pointer and
length. When his talk was over, David approached me about a
possible joint workshop on language binding, which sounds
like a fun idea to me.
<p>I spent some considerable time talking with Steven Knight,
the leader of the Scons build tool effort. We had a lot to
share with one another, and I gained a much better
appreciation for many of the Scons design decisions. Scons
seems to be concentrating on being the ultimate build system
substrate, and Steve seemed to think that we were on the
right track with our high-level design. We both hope that the
Boost.Build V2 high-level architecture can eventually be
ported to run on top of Scons.
<p>They also have a highly-refined and successful development
procedure which I&#39;d like to emulate for Boost.Build V2.
Among many other things they do, their source-control system
automatically ensures that when you check in a new test, it
is automatically run on the currently checked-in state of the
code, and is expected to fail -- a relatively obvious good
idea which I&#39;ve never heard before.
<p>Guido Van Rossum&#39;s &quot;State of the Python
Union&quot; address was full of questions for the community
about what should be done next, but the one idea Guido seemed
to stress was that core language stability and continuing
library development would be a good idea (sound familiar?) I
mentioned the Boost model as a counterpoint to the idea of
something like CPAN (the massive Perl library archives), and
it seemed to generate some significant interest. I&#39;ve
offered to work with anyone from the Python community who
wants to set up something like Boost.
<p>There was some discussion of &quot;string
interpolation&quot; (variable substitution in strings), and
Guido mentioned that he had some thoughts about the
strengths/weaknesses of Python&#39;s formatting interface. It
might be useful for those working on formatting for boost to
contact him and find out what he has to say.
<p>Ka-Ping Yee demoed a Mailman discussion thread weaver.
This tool weaves the various messages in a discussion thread
into a single document so you can follow the entire
conversation. Since we&#39;re looking very seriously at
moving Boost to Mailman, this could be a really useful thing
for us to have. If we do this, we&#39;ll move the yahoogroups
discussions into the mailman archive so old discussions can
be easily accessed in the same fashion.
<p>And, just because it&#39;s cool, though perhaps not
relevant: http://homepages.ulb.ac.be/~arigo/psyco/ is a
promising effort to accelerate the execution of Python code
to speeds approaching those of compiled languages. It
reminded me a lot of Todd Veldhuizen&#39;s research into
moving parts of C++ template compilation to runtime, only
coming from the opposite end of things.
<h2><a name="progress">Boost.Python v2 Progress</a></h2>
Here&#39;s what actually got accomplished.
<h3><a name="documentation">Documentation</a></h3>
<p>My first priority upon returning from Python10 was to get
some documentation in place. After wasting an unfortunate
amount of time looking at automatic documentation tools which
don&#39;t quite work, I settled down to use Bill Kempf&#39;s
HTML templates designed to be a boost standard. While they
are working well, it is highly labor-intensive.
<p>I decided to begin with the high-level reference material,
as opposed to tutorial, narrative, or nitty-gritty details of
the framework. It seemed more important to have a precise
description of the way the commonly-used components work than
to have examples in HTML (since we already have some test
modules), and since the low-level details are much
less-frequently needed by users it made sense for me to
simply respond to support requests for the time being.
<p>After completing approximately 60% of the high-level docs
(currently checked in to libs/python/doc/v2), I found myself
ready to start documenting the mechanisms for creating
to-/from-python converters. This caused a dilemma: I had
realized during the previous week that a much simpler,
more-efficient, and easier-to-use implementation was
possible, but I hadn&#39;t planned on implementing it right
away, since what was already in place worked adequately. I
had also received my first query on the C++-sig about how to
write such a converter
<p>Given the labor-intensive nature of documentation writing,
I decided it would be a bad idea to document the conversion
mechanism if I was just going to rewrite it. Often the best
impetus for simplifying a design is the realization that
understandably documenting its current state would be too
difficult, and this was no exception.
<h3><a name="conversion">Overhaul of
<code>to_python</code>/<code>from_python</code> conversion
mechanism</a></h3>
<p>There were two basic realizations involved here:
<ol>
<li><code>to_python</code> conversion could be a one-step
process, once an appropriate conversion function is found.
This allows elimination of the separate indirect
convertibility check
<li>There are basically two categories of from_python
conversions: those which lvalues stored within or held by
the Python object (essentially extractions), like what
happens when an instance of a C++ class exposed with class_
is used as the target of a wrapped member function), and
those in which a new rvalue gets created, as when a Python
Float is converted to a C++
<code>complex&lt;double&gt;</code> or a Python tuple is
converted to a C++ <code>std::vector&lt;&gt;</code>. From
the client side, there are two corresponding categories of
conversion: those which demand an lvalue conversion and
those which can accept an lvalue or an rvalue conversion.
</ol>
The latter realization allowed the following collapse, which
considerably simplified things:
<blockquote>
<table border="1" summary="Conversion protocol">
<tr>
<th>Target Type
<th>Eligible Converters
<tr>
<td><code>T</code>
<td rowspan="5"><code>T</code> rvalue or lvalue
<tr>
<td><code>T const</code>
<tr>
<td><code>T volatile</code>
<tr>
<td><code>T const volatile</code>
<tr>
<td><code>T const&amp;</code>
<tr>
<td><code>T const*</code>
<td rowspan="9"><code>T</code> lvalue
<tr>
<td><code>T volatile*</code>
<tr>
<td><code>T const volatile*</code>
<tr>
<td><code>T&amp;</code>
<tr>
<td><code>T volatile&amp;</code>
<tr>
<td><code>T const volatile&amp;</code>
<tr>
<td><code>T* const&amp;</code>
<tr>
<td><code>T const* const&amp;</code>
<tr>
<td><code>T volatile*const&amp;</code>
<tr>
<td><code>T const volatile*const&amp;</code>
</table>
</blockquote>
This job included the following additional enhancements:
<ul>
<li>Elimination of virtual functions, which cause object
code bloat
<li>Registration of a single converter function for all
lvalue conversions, two for all rvalue conversions
<li>Killed lots of unneeded code
<li>Increased opacity of registry interface
<li>Eliminated all need for decorated runtime type
identifiers
<li>Updated test modules to reflect new interface
<li>Eliminated the need for users to worry about converter
lifetime issues Additional Builtin Conversion Enhancements
<li>Support for complex&lt;float&gt;,
complex&lt;double&gt;, and complex&lt;long double&gt;
conversions
<li>Support for bool conversions
<li>NULL pointers representable by None in Python
<li>Support for conversion of Python classic classes to
numeric types
</ul>
<h3><a name="miscellaneous">Miscellaneous</a></h3>
These don&#39;t fit easily under a large heading:
<ul>
<li>Support CallPolicies for class member functions
<li>from_python_data.hpp: revamped type alignment
metaprogram so that it&#39;s fast enough for KCC
<li>classfwd.hpp header forward-declares class_&lt;T&gt;
<li>indirect_traits.hpp:
<li>added is_pointer_to_reference
<li>fixed bugs
<li>Reduced recompilation dependencies
<li>msvc_typeinfo works around broken MS/Intel typeid()
implementation
<li>Many fixes and improvements to the type_traits library
in order to work around compiler bugs and suppress warnings
<li>Eliminated the need for explicit acquisition of
converter registrations
<li>Expanded constructor support to 6 arguments
<li>Implemented generalized pointer lifetime support
<li>Updated code generation for returning.hpp
<li>Tracked down and fixed cycle GC bugs
<li>Added comprehensive unit tests for destroy_reference,
pointer_type_id, select_from_python, complex&lt;T&gt;,
bool, and classic class instance conversions
</ul>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p class="c3">&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.

View File

@@ -1,166 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/from_python.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/from_python.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#from_python-spec">Class
Template<code>from_python</code></a>
<dd>
<dl class="page-index">
<dt><a href="#from_python-spec-synopsis">Class Template
<code>from_python</code> synopsis</a>
<dt><a href="#from_python-spec-ctors">Class Template
<code>from_python</code> constructor</a>
<dt><a href="#from_python-spec-observers">Class Template
<code>from_python</code> observer functions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/from_python.hpp&gt;</code> introduces a class
template <code>from_python&lt;T&gt;</code> for extracting a C++ object of
type <code>T</code> from a Python object.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="from_python-spec"></a>Class Template
<code>from_python&lt;class T&gt;</code></h3>
<p><code>from_python&lt;T&gt;</code> is the type used internally by
Boost.Python to extract C++ function arguments from a Python argument tuple
when calling a wrapped function. It can also be used directly to make
similar conversions in other contexts.
<h4><a name="from_python-spec-synopsis"></a>Class Template
<code>from_python</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T&gt;
struct from_python : private <a href=
"../../../utility/utility.htm#Class noncopyable">boost::noncopyable</a> // Exposition only.
// from_python&lt;T&gt; meets the <a href=
"NonCopyable.html">NonCopyable</a> requirements
{
from_python(PyObject*);
bool convertible() const;
<i>convertible-to-T</i> operator()(PyObject*) const;
};
}
</pre>
<h4><a name="from_python-spec-ctors"></a>Class Template
<code>from_python</code> constructor</h4>
<pre>
from_python(PyObject* p);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>p != 0</code>
<dt><b>Effects:</b> Constructs a <code>from_python</code> object suitable
for extracting a C++ object of type <code>T</code> from <code>p</code>.
</dl>
<h4><a name="from_python-spec-observers"></a>Class Template
<code>from_python</code> observer functions</h4>
<pre>
bool convertible() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>false</code> if the conversion cannot succeed.
This indicates that either:
<dd>
<ol>
<li>No <code>from_python_converter</code> was registered for
<code>T</code>, or
<li>any such converter rejected the constructor argument
<code>p</code> by returning <code>0</code> from its
<code>convertible()</code> function
</ol>
Note that conversion may still fail in <code>operator()</code> due to
an exception.
<dt><b>Throws:</b> nothing
<dt><b>Rationale:</b> Because <code>from_python&lt;&gt;</code> is used in
overload resolution, and throwing an exception can be slow, it is useful
to be able to rule out a broad class of unsuccessful conversions without
throwing an exception.
</dl>
<pre>
<i>convertible-to-T</i> operator()(PyObject* p) const;
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>*p</code> refers to the same object which was
passed to the constructor, and <code>convertible()</code> returns
<code>true</code>.
<dt><b>Effects:</b> performs the conversion
<dt><b>Returns:</b> an object convertible to <code>T</code>.
</dl>
<h2><a name="examples"></a>Example</h2>
<pre>
#include &lt;string&gt;
#include &lt;boost/python/from_python.hpp&gt;
// If a std::string can be extracted from p, return its
// length. Otherwise, return 0.
std::size_t length_if_string(PyObject* p)
{
from_python&lt;std::string&gt; converter(p);
if (!converter.convertible())
return 0;
else
return converter(p).size();
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>

View File

@@ -1,323 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/handle.hpp&gt;</title>
<style type="text/css">
p.c4 {font-style: italic}
span.c3 {color: #ff0000}
h2.c2 {text-align: center}
h1.c1 {text-align: center}
</style>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">Header &lt;boost/python/handle.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#handle-spec">Class template
<code>handle</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#handle-spec-synopsis">Class <code>handle</code>
synopsis</a></dt>
<dt><a href="#handle-spec-ctors">Class <code>handle</code>
constructors and destructor</a></dt>
<dt><a href="#handle-spec-modifiers">Class <code>handle</code>
modifier functions</a></dt>
<dt><a href="#handle-spec-observers">Class <code>handle</code>
observer functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#borrowed-spec"><code>borrowed</code></a></dt>
<dt><a href="#allow_null-spec"><code>allow_null</code></a></dt>
</dl>
</dd>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/handle.hpp&gt;</code> provides
<code>class&nbsp;template&nbsp;handle</code>, a smart pointer for
managing reference-counted Python objects.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="handle-spec"></a>Class template <code>handle</code></h3>
<p><code>handle</code> is a smart pointer to a Python object type; it
holds a pointer of type <code>T*</code>, where T is its template
parameter. <code>T</code> must be either a type derived from
<code>PyObject</code> or a <a href="definitions.html#POD">POD</a>
type whose initial <code>sizeof(PyObject)</code> bytes are
layout-compatible with <code>PyObject</code>. Use
<code>handle&lt;&gt;</code> at the boundary between tehe
Python/'C' API and high-level code; prefer <code><a
href="object.html#object-spec">object</a></code> for a generalized
interface to Python objects.
<p><a name="upcast"></a>In this document, the term "upcast" refers to an
operation which converts a pointer <code>Y*</code> to a base class
pointer <code>T*</code> via <code>static_cast&lt;T*&gt;</code> if
<code>Y</code> is derived from <code>T</code>, or via C-style cast
<code>(T*)</code> if it is not. However, in the latter case the "upcast"
is ill-formed if the initial <code>sizeof(PyObject)</code> bytes of
<code>Y</code> are not layout-compatible with <code>PyObject</code>.</p>
<h4><a name="handle-spec-synopsis"></a>Class template handle
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T&gt;
class handle
{
typedef <i>unspecified-member-function-pointer</i> bool_type;
public: // types
typedef T element_type;
public: // member functions
~handle();
template &lt;class Y&gt;
explicit handle(detail::borrowed&lt;null_ok&lt;Y&gt; &gt;* p);
template &lt;class Y&gt;
explicit handle(null_ok&lt;detail::borrowed&lt;Y&gt; &gt;* p);
template &lt;class Y&gt;
explicit handle(detail::borrowed&lt;Y&gt;* p);
template &lt;class Y&gt;
explicit handle(null_ok&lt;Y&gt;* p);
template &lt;class Y&gt;
explicit handle(Y* p);
handle();
handle&amp; operator=(handle const&amp; r);
template&lt;typename Y&gt;
handle&amp; operator=(handle&lt;Y&gt; const &amp; r); // never throws
template &lt;typename Y&gt;
handle(handle&lt;Y&gt; const&amp; r);
handle(handle const&amp; r);
T* operator-&gt; () const;
T&amp; operator* () const;
T* get() const;
T* release();
operator bool_type() const; // never throws
private:
T* m_p;
};
template &lt;class T&gt; struct null_ok;
namespace detail { template &lt;class T&gt; struct borrowed; }
}}
</pre>
<h4><a name="handle-spec-ctors">Class <code>handle</code> constructors
and destructor</a></h4>
<pre>
virtual ~handle();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> <code>Py_XDECREF(m_p)</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
explicit handle(detail::borrowed&lt;null_ok&lt;Y&gt; &gt;* p);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> <code>Py_XDECREF(m_p)</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
explicit handle(null_ok&lt;detail::borrowed&lt;Y&gt; &gt;* p);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
explicit handle(detail::borrowed&lt;Y&gt;* p);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a href=
"errors.html#expect_non_null-spec">expect_non_null</a>(p));</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
explicit handle(null_ok&lt;Y&gt;* p);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>Py_XINCREF(p);&nbsp;m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
explicit handle(Y* p);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>Py_XINCREF(p);&nbsp;m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a
href=
"errors.html#expect_non_null-spec">expect_non_null</a>(p));</code></dt>
</dl>
<pre>
handle();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> <code>m_p&nbsp;=&nbsp;0;</code></dt>
</dl>
<pre>
template &lt;typename Y&gt;
handle(handle&lt;Y&gt; const&amp; r);
handle(handle const&amp; r);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>m_p&nbsp;=&nbsp;r.m_p;&nbsp;Py_XINCREF(m_p);</code></dt>
</dl>
<h4><a name="handle-spec-modifiers">Class <code>handle</code>
modifiers</a></h4>
<pre>
handle&amp; operator=(handle const&amp; r);
template&lt;typename Y&gt;
handle&amp; operator=(handle&lt;Y&gt; const &amp; r); // never throws
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>Py_XINCREF(r.m_p);&nbsp;Py_XDECREF(m_p);&nbsp;m_p&nbsp;=&nbsp;r.m_p;</code></dt>
</dl>
<pre>
T* release();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> <code>T* x = m_p;&nbsp;m_p&nbsp;=&nbsp;0;return
x;</code></dt>
</dl>
<h4><a name="handle-spec-observers">Class <code>handle</code>
observers</a></h4>
<pre>
T* operator-&gt; () const;
T* get() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>m_p;</code></dt>
</dl>
<pre>
T&amp; operator* () const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>*m_p;</code></dt>
</dl>
<pre>
operator bool_type() const; // never throws
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> 0 if <code>m_p&nbsp;==&nbsp;0</code>, a pointer
convertible to <code>true</code> otherwise.</dt>
</dl>
<h2><a name="functions"></a>Functions</h2>
<h3><a name="borrowed-spec"></a><code>borrowed</code></h3>
<pre>
template <class T>
detail::borrowed<T>* borrowed(T* p)
{
return (detail::borrowed<T>*)p;
}
</pre>
<h3><a name="allow_null-spec"></a><code>allow_null</code></h3>
<pre>
template <class T>
null_ok<T>* allow_null(T* p)
{
return (null_ok<T>*)p;
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p class="c4">&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</p>
</body>
</html>

View File

@@ -1,214 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/has_back_reference.hpp&gt;</title>
<style type="text/css">
p.c3 {font-style: italic}
h2.c2 {text-align: center}
h1.c1 {text-align: center}
</style>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">Header
&lt;boost/python/has_back_reference.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#has_back_reference-spec">Class template
<code>has_back_reference</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#has_back_reference-spec-synopsis">Class template
<code>has_back_reference</code> synopsis</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
</dd>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/has_back_reference.hpp&gt;</code> defines the
traits class template <code>has_back_reference&lt;&gt;</code>, which can
be specialized by the user to indicate that a wrapped class instance
holds a <code>PyObject*</code> corresponding to a Python object.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="has_back_reference-spec"></a>Class template
<code>has_back_reference</code></h3>
<p>A unary metafunction whose <code>value</code> is true iff its argument
is a <code>pointer_wrapper&lt;&gt;</code>.</p>
<h4><a name="has_back_reference-spec-synopsis"></a>Class template
<code>has_back_reference</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template&lt;class WrappedClass&gt; class has_back_reference
{
static <i>unspecified</i> value = false;
};
}}
</pre>
<p>A "<a href="../../../../more/generic_programming.html#traits">traits
class</a>" which is inspected by Boost.Python to determine how wrapped
classes can be constructed.</p>
<dl class="traits-semantics">
<dt><code>value</code> is an integral constant convertible to bool of
unspecified type.</dt>
<dt>Specializations may substitute a value convertible to
<code>true</code> for <code>value</code> iff for each invocation of
<code>class_&lt;WrappedClass&gt;::def(init&lt;</code><i>type-sequence...</i><code>
&gt;())</code>, there exists a corresponding constructor
<code>WrappedClass::WrappedClass(PyObject*,&nbsp;</code><i>type-sequence...</i>
<code>)</code>. If such a specialization exists, the
<code>WrappedClass</code> constructors will be called with a "back
reference" pointer to the corresponding Python object whenever they are
invoked from Python.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/has_back_reference.hpp&gt;
#include &lt;boost/python/handle.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
using namespace boost::python;
struct X
{
X(PyObject* self) : m_self(self), m_x(0) {}
X(PyObject* self, int x) : m_self(self), m_x(x) {}
handle&lt;&gt; self() { return handle&lt;&gt;(borrowed(m_self)); }
int get() { return m_x; }
void set(int x) { m_x = x; }
PyObject* m_self;
int x;
};
// specialize has_back_reference for X
namespace boost { namespace python
{
template &lt;&gt;
struct has_back_reference&lt;X&gt;
{
enum { value = true; }
}
}}
struct Y
{
Y() : m_x(0) {}
Y(int x) : m_x(x) {}
int get() { return m_x; }
void set(int x) { m_x = x; }
int x;
};
boost::shared_ptr&lt;Y&gt; Y_self(boost::shared_ptr&lt;Y&gt; self) const { return self; }
BOOST_PYTHON_MODULE(back_references)
{
class_&lt;X&gt;("X")
.def(init&lt;int&gt;())
.def("self", &amp;X::self)
.def("get", &amp;X::get)
.def("set", &amp;X::set)
;
class_&lt;Y, shared_ptr&lt;Y&gt; &gt;("Y")
.def(init&lt;int&gt;())
.def("get", &amp;Y::get)
.def("set", &amp;Y::set)
.def("self", Y_self)
;
}
</pre>
The following Python session illustrates that <code>x.self()</code>
returns the same Python object on which it is invoked, while
<code>y.self()</code> must create a new Python object which refers to the
same Y instance.
<h3>Python code</h3>
<pre>
&gt;&gt;&gt; from back_references import *
&gt;&gt;&gt; x = X(1)
&gt;&gt;&gt; x2 = x.self()
&gt;&gt;&gt; x2 is x
<b>1</b>
&gt;&gt;&gt; (x.get(), x2.get())
(1, 1)
&gt;&gt;&gt; x.set(10)
&gt;&gt;&gt; (x.get(), x2.get())
(10, 10)
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; y = Y(2)
&gt;&gt;&gt; y2 = y.self()
&gt;&gt;&gt; y2 is y
<b>0</b>
&gt;&gt;&gt; (y.get(), y2.get())
(2, 2)
&gt;&gt;&gt; y.set(20)
&gt;&gt;&gt; (y.get(), y2.get())
(20, 20)
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p class="c3">&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</p>
</body>
</html>

View File

@@ -1,288 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;{{header}}&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;{{header}}&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#macros">Macros</a>
<dd>
<dl class="page-index">
<dt><a href="#macro-spec">{{macro name}}</a>
</dl>
<dt><a href="#values">Values</a>
<dd>
<dl class="page-index">
<dt><a href="#value-spec">{{value name}}</a>
</dl>
<dt><a href="#types">Types</a>
<dd>
<dl class="page-index">
<dt><a href="#type-spec">{{type name}}</a>
</dl>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#class-spec">Class <code>{{name}}</code></a>
<dd>
<dl class="page-index">
<dt><a href="#class-spec-synopsis">Class <code>{{name}}</code> synopsis</a>
<dt><a href="#class-spec-ctors">Class <code>{{name}}</code>
constructors and destructor</a>
<dt><a href="#class-spec-comparisons">Class <code>{{name}}</code> comparison functions</a>
<dt><a href="#class-spec-modifiers">Class <code>{{name}}</code> modifier functions</a>
<dt><a href="#class-spec-observers">Class <code>{{name}}</code> observer functions</a>
<dt><a href="#class-spec-statics">Class <code>{{name}}</code> static functions</a>
</dl>
</dl>
<dt><a href="#functions">Functions</a>
<dd>
<dl class="page-index">
<dt><a href="#function-spec">{{function name}}</a>
</dl>
<dt><a href="#objects">Objects</a>
<dd>
<dl class="page-index">
<dt><a href="#object-spec">{{object name}}</a>
</dl>
<dt><a href="#examples">Example(s)</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>{{Introductory text}}
<h2><a name="macros"></a>Macros</h2>
<p><a name="macro-spec"></a>{{Macro specifications}}
<h2><a name="values"></a>Values</h2>
<p><a name="value-spec"></a>{{Value specifications}}
<h2><a name="types"></a>Types</h2>
<p><a name="type-spec"></a>{{Type specifications}}
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class-spec"></a>Class <code>{{name}}</code></h3>
<p>{{class overview text}}
<h4><a name="class-spec-synopsis"></a>Class <code>{{name}}</code> synopsis</h4>
<pre>
namespace boost
{
class {{name}}
{
};
};
</pre>
<h4><a name="class-spec-ctors"></a>Class <code>{{name}}</code> constructors and
destructor</h4>
<pre>
{{constructor}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<pre>
{{destructor}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-comparisons"></a>Class <code>{{name}}</code> comparison
functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-modifiers"></a>Class <code>{{name}}</code> modifier
functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-observers"></a>Class <code>{{name}}</code> observer
functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-statics"></a>Class <code>{{name}}</code> static functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="function-spec"></a>{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h2><a name="objects"></a>Objects</h2>
<p><a name="object-spec"></a>{{Object specifications}}
<h2><a name="examples"></a>Example(s)</h2>
<p>{{Example(s)}}
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>

View File

@@ -1,161 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/implicit.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/implicit.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#implicitly_convertible-spec">Function Template
<code>implicitly_convertible</code></a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>implicitly_convertible</code> allows Boost.Python to implicitly
take advantage of a C++ implicit or explicit conversion when matching
Python objects to C++ argument types.
<h2><a name="functions"></a>Functions</h2>
<h3><a name="implicitly_convertible-spec"></a>Function template
<code>implicitly_convertible</code></h3>
<pre>
template &lt;class Source, class Target&gt;
void implicitly_convertible();
</pre>
<table border="1" summary="implicitly_convertible template parameters">
<caption>
<b><code>implicitly_convertible</code> template parameters</b><br>
</caption>
<tr>
<th>Parameter</th>
<th>Description</th>
</tr>
<tr>
<td><code>Source</code></td>
<td>The source type of the implicit conversion</td>
</tr>
<tr>
<td><code>Target</code></td>
<td>The target type of the implicit conversion</td>
</tr>
</table>
<dl class="function-semantics">
<dt><b>Requires:</b> The declaration <code>Target t(s);</code>, where
<code>s</code> is of type <code>Source</code>, is valid.</dt>
<dt><b>Effects:</b> registers an rvalue <code>from_python</code>
converter to <code>Target</code> which can succeed for any
<code>PyObject*&nbsp;p</code> iff there exists any registered converter
which can produce <code>Source</code> rvalues</dt>
<dt><b>Rationale:</b> C++ users expect to be able to take advantage of
the same sort of interoperability in Python as they do in C++.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/implicit.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
using namespace boost::python;
struct X
{
X(int x) : v(x) {}
operator int() { return v; }
int v;
};
int x_value(X const&amp; x)
{
return x.v;
}
X make_x(int n) { return X(n); }
BOOST_PYTHON_MODULE(implicit_ext)
{
def("x_value", x_value);
def("make_x", make_x);
class_&lt;X&gt;("X",
init&lt;int&gt;())
;
implicitly_convertible&lt;X,int&gt;();
implicitly_convertible&lt;int,X&gt;();
}
</pre>
<h3>Python code</h3>
<pre>
&gt;&gt;&gt; from implicit_ext import *
&gt;&gt;&gt; x_value(X(42))
42
&gt;&gt;&gt; x_value(42)
42
&gt;&gt;&gt; x = make_x(X(42))
&gt;&gt;&gt; x_value(x)
42
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="refresh" content="0; URL=../index.html">
<title></title>
</head>
<body>
Automatic redirection failed, please go to <a href=
"../index.html">../index.html</a>.
</body>
</html>

View File

@@ -1,249 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/init.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Headers &lt;boost/python/init.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href=
"#init-expressions"><em>init-expressions</em></a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#init-spec">Class template <code>init</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#init-spec-synopsis">Class template
<code>init</code> synopsis</a></dt>
<dt><a href="#init-spec-ctors">Class <code>init</code>
constructors</a></dt>
</dl>
</dd>
<dt><a href="#optional-spec">Class template
<code>optional</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#optional-spec-synopsis">Class template
<code>optional</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/init.hpp&gt;</code> defines the interface for
exposing C++ constructors to Python as extension class
<code>__init__</code> functions.</p>
<h2><a name="init-expressions"><em>init-expressions</em></a></h2>
An <em>init-expression</em> is used to describe a family of
<code>__init__</code> methods to be generated for an extension class, and
the result has the following properties:
<blockquote>
<dl class="properties">
<dt><b>docstring:</b> An <a href="definitions.html#ntbs">ntbs</a>
whose value will bound to the method's <code>__doc__</code>
attribute</dt>
<dt><b>keywords:</b> A <a href=
"args.html#keyword-expression">keyword-expression</a> which will be
used to name (a trailing subsequence of) the arguments to the
generated <code>__init__</code> function(s).</dt>
<dt><b>call policies:</b> An instance of a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>argument types:</b> An MPL sequence of C++ argument types
which will be used to construct the wrapped C++ object. An init
expression has one or more
<b>valid prefixes</b> which are given by a sequence of
prefixes of its argument types.</dt>
</dl>
</blockquote>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="init-spec"></a>Class template <code>init&lt;T1 =</code>
<i>unspecified</i><code>,&nbsp;T2 =</code>
<i>unspecified</i><code>,</code>...<code>Tn</code> =
<i>unspecified</i><code>&gt;</code></h3>
<p>A <a href="../../../mpl/doc/ref/Sequences.html">MPL sequence</a> which
can be used to specify a family of one or more <code>__init__</code>
functions. Only the last <code>T</code><i><small>i</small></i> supplied
may be an instantiation of <a href=
"#optional-spec"><code>optional</code></a><code>&lt;</code>...<code>&gt;</code>.</p>
<h4><a name="init-spec-synopsis"></a>Class template <code>init</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;T1 = <i>unspecified</i>,...T<i>n</i> = <i>unspecified</i>&gt;
struct init
{
init(char const* doc = 0);
template &lt;class Keywords&gt; init(Keywords const&amp; kw, char const* doc = 0);
template &lt;class Keywords&gt; init(char const* doc, Keywords const&amp; kw);
template &lt;class CallPolicies&gt;
<em>unspecified</em> operator[](CallPolicies const&amp; policies) const
};
}}
</pre>
<h4><a name="init-spec-ctors"></a>Class template <code>init</code>
constructors</h4>
<pre>
init(char const* doc = 0);
template &lt;class Keywords&gt; init(Keywords const&amp; kw, char const* doc = 0);
template &lt;class Keywords&gt; init(char const* doc, Keywords const&amp; kw);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> If supplied, <code>doc</code> is an <a href=
"definitions.html#ntbs">ntbs</a>. If supplied, <code>kw</code> is the
result of a <a href="args.html#keyword-expression"></a></dt>
<dt><b>Effects:</b> The result is an <em>init-expression</em> whose
<em>docstring</em> is <code>doc</code> and whose <em>keywords</em> are
a reference to <code>kw</code>. If the first form is used, the
resulting expression's <em>keywords</em> are empty. The expression's
<em>call policies</em> are an instance of <a href=
"default_call_policies.html#default_call_policies-spec">default_call_policies</a>.
If <code>T</code><i><small>n</small></i> is <a href=
"#optional-spec"><code>optional</code></a><code>&lt;U1,&nbsp;U2,</code>...
<code>U</code><small><i>m</i></small><code>&gt;</code>, the
expression's <em>valid prefixes</em> are given by:</dt>
<dd>
<blockquote>
(<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>),
(<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>
<code>,&nbsp;U1</code>),
(<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>
<code>,&nbsp;U1,&nbsp;U2</code>),
...(<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>
<code>,&nbsp;U1,&nbsp;U2,</code>...<code>U</code><i><small>m</small></i>).
</blockquote>
Otherwise, the expression has one <em>valid prefix</em> given by the
the template arguments the user specified.
</dd>
</dl>
<h4><a name="init-spec-observers"></a>Class template <code>init</code>
observer functions</h4>
<pre>
template &lt;class Policies&gt;
<em>unspecified</em> operator[](Policies const&amp; policies) const
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> Policies is a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>Effects:</b> Returns a new <a href=
"#init-expressions"><em>init-expression</em></a> with all the same
properties as the <code>init</code> object except that its <em>call
policies</em> are replaced by a reference to
<code>policies</code>.</dt>
</dl>
<h3><a name="optional-spec"></a>Class template <code>optional&lt;T1
=</code> <i>unspecified</i><code>,&nbsp;T2 =</code>
<i>unspecified</i><code>,</code>...<code>Tn</code> =
<i>unspecified</i><code>&gt;</code></h3>
<p>A <a href="../../../mpl/doc/ref/Sequences.html">MPL sequence</a> which
can be used to specify the optional arguments to an <code>__init__</code>
function.</p>
<h4><a name="optional-spec-synopsis"></a>Class template
<code>optional</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;T1 = <i>unspecified</i>,...T<i>n</i> = <i>unspecified</i>&gt;
struct optional {};
}}
</pre>
<h2><a name="examples"></a>Example(s)</h2>
<p>Given the C++ declarations:</p>
<pre>
class Y;
class X
{
public:
X(int x, Y* y) : m_y(y) {}
X(double);
private:
Y* m_y;
};
</pre>
A corresponding Boost.Python extension class can be created with:
<pre>
using namespace boost::python;
class_&lt;X&gt;("X", "This is X's docstring.",
init&lt;int,char const*&gt;(args("x","y"), "X.__init__'s docstring")[
with_custodian_and_ward&lt;1,3&gt;()]
)
.def(init&lt;double&gt;())
;
</pre>
<hr>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,209 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/instance_holder.hpp&gt;</title>
<style type="text/css">
p.c4 {font-style: italic}
span.c3 {color: #ff0000}
h2.c2 {text-align: center}
h1.c1 {text-align: center}
</style>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width=
"277" alt="C++ Boost" src="../../../../c++boost.gif" border=
"0"></a></h3>
<td valign="top">
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">Header &lt;boost/python/instance_holder.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#instance_holder-spec">Class
<code>instance_holder</code></a>
<dd>
<dl class="page-index">
<dt><a href="#instance_holder-spec-synopsis">Class
<code>instance_holder</code> synopsis</a>
<dt><a href="#instance_holder-spec-ctors">Class
<code>instance_holder</code> destructor</a>
<dt><a href="#instance_holder-spec-modifiers">Class
<code>instance_holder</code> modifier functions</a>
<dt><a href="#instance_holder-spec-observers">Class
<code>instance_holder</code> observer functions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/instance_holder.hpp&gt;</code> provides
<code>class&nbsp;instance_holder</code>, the base class for types
which hold C++ instances of wrapped classes.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="instance_holder-spec"></a>Class <code>instance_holder</code></h3>
<p><code>instance_holder</code> is an abstract base class whose
concrete derived classes hold C++ class instances within their
Python object wrappers. To allow multiple inheritance in Python
from C++ class wrappers, each such Python object contains a chain
of <code>instance_holder</code>s. When an <code>__init__</code>
function for a wrapped C++ class is invoked, a new
<code>instance_holder</code> instance is created and installed in
the Python object using its <code><a
href="#instance_holder-spec-modifiers">install</a></code>()
function. Each concrete class derived from
<code>instance_holder</code> must provide a <code><a
href="#instance_holder-spec-observers">holds</a>()</code>
implementation which allows Boost.Python to query it for the
type(s) it is holding. In order to support the held type's wrapped
constructor(s), the class must also provide constructors that can
accept an initial <code>PyObject*</code> argument referring to the
owning Python object, and which forward the rest of their
arguments to the constructor of the held type. The initial
argument is needed to enable virtual function overriding in
Python, and may be ignored, depending on the specific
<code>instance_holder</code> subclass.
<h4><a name="instance_holder-spec-synopsis"></a>Class instance_holder
synopsis</h4>
<pre>
namespace boost { namespace python
{
class instance_holder : <a href="../../../utility/utility.htm#Class noncopyable">noncopyable</a>
{
public:
// destructor
virtual ~instance_holder();
// instance_holder modifiers
void install(PyObject* inst) throw();
// instance_holder observers
virtual void* holds(type_info) = 0;
};
}}
</pre>
<h4><a name="instance_holder-spec-ctors">Class <code>instance_holder</code>
destructor</a></h4>
<pre>
virtual ~instance_holder();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> destroys the object
</dl>
<h4><a name="instance_holder-spec-modifiers">Class
<code>instance_holder</code> modifiers</a></h4>
<pre>
void install(PyObject* inst) throw();
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>inst</code> is a Python instance of a
wrapped C++ class type, or is a type derived from a wrapped C++
class type.
<dt><b>Effects:</b> installs the new instance at the head of the
Python object's chain of held instances.
<dt><b>Throws:</b> nothing
</dl>
<h4><a name="instance_holder-spec-observers">Class <code>instance_holder</code>
observers</a></h4>
<pre>
virtual void* holds(type_info x) = 0;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> A pointer to an object of the type described
by <code>x</code> if <code>*this</code> contains such an object,
0 otherwise.
</dl>
<h2><a name="examples"></a>Example</h2>
The following is a simplified version of the instance holder template
used by Boost.Python to wrap classes held by smart pointers:
<pre>
template &lt;class SmartPtr, class Value&gt;
struct pointer_holder : instance_holder
{
// construct from the SmartPtr type
pointer_holder(SmartPtr p)
:m_p(p)
// Forwarding constructors for the held type
pointer_holder(PyObject*)
:m_p(new Value())
{
}
template&lt;class A0&gt;
pointer_holder(PyObject*,A0 a0)
:m_p(new Value(a0))
{
}
template&lt;class A0,class A1&gt;
pointer_holder(PyObject*,A0 a0,A1 a1)
:m_p(new Value(a0,a1))
{
}
...
private: // required holder implementation
void* holds(type_info dst_t)
{
// holds an instance of the SmartPtr type...
if (dst_t == python::type_id&lt;SmartPtr&gt;())
return &amp;this-&gt;m_p;
// ...and an instance of the SmartPtr's element_type, if the
// pointer is non-null
return python::type_id&lt;Value&gt;() == dst_t ? &amp;*this-&gt;m_p : 0;
}
private: // data members
SmartPtr m_p;
};
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p class="c4">&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All
Rights Reserved.

View File

@@ -1,397 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/iterator.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/iterator.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#iterator-spec">Class template
<code>iterator</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#iterator-spec-synopsis">Class
<code>iterator</code> synopsis</a></dt>
<dt><a href="#iterator-spec-ctors">Class template
<code>iterator</code> constructor</a></dt>
</dl>
</dd>
</dl>
<dl class="page-index">
<dt><a href="#iterators-spec">Class template
<code>iterators</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#iterators-spec-synopsis">Class
<code>iterators</code> synopsis</a></dt>
<dt><a href="#iterators-spec-types">Class template
<code>iterators</code> nested types</a></dt>
<dt><a href="#iterators-spec-statics">Class template
<code>iterators</code> static functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#range-spec">range</a></dt>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/iterator.hpp&gt;</code> provides types and
functions for creating <a href=
"http://www.python.org/doc/current/lib/typeiter.html">Python
iterators</a> from <a href=
"http://www.sgi.com/tech/stl/Container.html">C++ Containers</a> and <a
href="http://www.sgi.com/tech/stl/Iterators.html">Iterators</a>. Note
that if your <code>class_</code> supports random-access iterators,
implementing <code><a href=
"http://www.python.org/doc/current/ref/sequence-types.html#l2h-128">__getitem__</a></code>
(also known as the Sequence Protocol) may serve you better than using
this facility: Python will automatically create an iterator type for you
(see <a href=
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-35">iter()</a>),
and each access can be range-checked, leaving no possiblity of accessing
through an invalidated C++ iterator.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="iterator-spec"></a>Class Template <code>iterator</code></h3>
<p>Instances of <code>iterator&lt;C,P&gt;</code> hold a reference to a
callable Python object which, when invoked from Python, expects a single
argument <code>c</code> convertible to <code>C</code> and creates a
Python iterator that traverses [<code>c.begin()</code>,
<code>c.end()</code>). The optional <a href=
"CallPolicies.html">CallPolicies</a> <code>P</code> can be used to
control how elements are returned during iteration.</p>
<p>In the table below, <code><b>c</b></code> is an instance of
<code>Container</code>.</p>
<table border="1" summary="iterator template parameters">
<tr>
<th>Template Parameter</th>
<th>Requirements</th>
<th>Semantics</th>
<th>Default</th>
</tr>
<tr>
<td><code>Container</code></td>
<td>[c.begin(),c.end()) is a valid <a href=
"http://www.sgi.com/tech/stl/Iterators.html">Iterator range</a>.</td>
<td>The result will convert its argument to <code>c</code> and call
<code>c.begin()</code> and <code>c.end()</code> to acquire iterators.
To invoke <code>Container</code>'s <code>const</code>
<code>begin()</code> and <code>end()</code> functions, make it
<code>const</code>.</td>
</tr>
<tr>
<td><code>NextPolicies</code></td>
<td>A default-constructible model of <a href=
"CallPolicies.html#CallPolicies-concept">CallPolicies</a>.</td>
<td>Applied to the resulting iterators' <code>next()</code>
method.</td>
<td>An unspecified model of <a href=
"CallPolicies.html#CallPolicies-concept">CallPolicies</a> which
always makes a copy of the result of deferencing the underlying C++
iterator</td>
</tr>
</table>
<h4><a name="iterator-spec-synopsis"></a>Class Template iterator
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class Container
, class NextPolicies = <i>unspecified</i>&gt;
struct iterator : <a href="object.html#object-spec">object</a>
{
iterator();
};
}}
</pre>
<h4><a name="iterator-spec-constructors"></a>Class Template iterator
constructor</h4>
<pre>
iterator()
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b></dt>
<dd>
Initializes its base class with the result of:
<pre>
range&lt;NextPolicies&gt;(&amp;iterators&lt;Container&gt;::begin, &amp;iterators&lt;Container&gt;::end)
</pre>
</dd>
<dt><b>Postconditions:</b> <code>this-&gt;get()</code> points to a
Python callable object which creates a Python iterator as described
above.</dt>
<dt><b>Rationale:</b> Provides an easy way to create iterators for the
common case where a C++ class being wrapped provides
<code>begin()</code> and <code>end()</code>.</dt>
</dl>
<!-- -->
<h3><a name="iterators-spec"></a>Class Template
<code>iterators</code></h3>
<p>A utility class template which provides a way to reliably call its
argument's <code>begin()</code> and <code>end()</code> member functions.
Note that there is no portable way to take the address of a member
function of a C++ standard library container, so
<code>iterators&lt;&gt;</code> can be particularly helpful when wrapping
them.</p>
<p>In the table below, <code><b>x</b></code> is an instance of
<code>C</code>.</p>
<table border="1" summary="iterator template parameters">
<tr>
<th>Required Valid Expression</th>
<th>Type</th>
</tr>
<tr>
<td><code>x.begin()</code></td>
<td>Convertible to <code>C::const_iterator</code> if <code>C</code>
is a <code>const</code> type; convertible to <code>C::iterator</code>
otherwise.</td>
</tr>
<tr>
<td><code>x.end()</code></td>
<td>Convertible to <code>C::const_iterator</code> if <code>C</code>
is a <code>const</code> type; convertible to <code>C::iterator</code>
otherwise.</td>
</tr>
</table>
<h4><a name="iterators-spec-synopsis"></a>Class Template iterators
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class C&gt;
struct iterators
{
typedef typename C::[const_]iterator iterator;
static iterator begin(C&amp; x);
static iterator end(C&amp; x);
};
}}
</pre>
<h4><a name="iterators-spec-types"></a>Class Template iterators nested
types</h4>
If C is a <code>const</code> type,
<pre>
typedef typename C::const_iterator iterator;
</pre>
Otherwise:
<pre>
typedef typename C::iterator iterator;
</pre>
<h4><a name="iterators-spec-statics"></a>Class Template iterators static
functions</h4>
<pre>
static iterator begin(C&amp;);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>x.begin()</code></dt>
</dl>
<pre>
static iterator end(C&amp;);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>x.end()</code></dt>
</dl>
<!-- -->
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name=
"range-spec">template</a> &lt;class NextPolicies, class Target, class Accessor1, class Accessor2&gt;
<a href=
"object.html#object-spec">object</a> range(Accessor1 start, Accessor2 finish);
template &lt;class NextPolicies, class Accessor1, class Accessor2&gt;
<a href=
"object.html#object-spec">object</a> range(Accessor1 start, Accessor2 finish);
template &lt;class Accessor1, class Accessor2&gt;
<a href=
"object.html#object-spec">object</a> range(Accessor1 start, Accessor2 finish);
</pre>
<dl class="range-semantics">
<dt><b>Requires:</b> <code>NextPolicies</code> is a
default-constructible model of <a href=
"CallPolicies.html#CallPolicies-concept">CallPolicies</a>.</dt>
<dt><b>Effects:</b></dt>
<dd>
<dl>
<dt>The first form creates a Python callable object which, when
invoked, converts its argument to a <code>Target</code> object
<code>x</code>, and creates a Python iterator which traverses
[<code><a href=
"../../../bind/bind.html">bind</a>(start,_1)(x)</code>,&nbsp;<code><a
href="../../../bind/bind.html">bind</a>(finish,_1)(x)</code>),
applying <code>NextPolicies</code> to the iterator's
<code>next()</code> function.</dt>
<dt>The second form is identical to the first, except that
<code>Target</code> is deduced from <code>Accessor1</code> as
follows:</dt>
<dd>
<ol>
<li>If <code>Accessor1</code> is a function type,
<code>Target</code> is the type of its first argument.</li>
<li>If <code>Accessor1</code> is a data member pointer of the
form <code>R&nbsp;(T::*)</code>, <code>Target</code> is
identical to <code>T</code>.</li>
<li>If <code>Accessor1</code> is a member function pointer of
the form
<code>R&nbsp;(T::*)(</code><i>arguments...</i><code>)</code>&nbsp;
<i>cv-opt</i>, where <i>cv-opt</i> is an optional
<code>cv-qualifier</code>, <code>Target</code> is identical to
<code>T</code>.</li>
</ol>
</dd>
<dt>The third form is identical to the second, except that
<code>NextPolicies</code> is an unspecified model of <a href=
"CallPolicies.html#CallPolicies-concept">CallPolicies</a> which
always makes a copy of the result of deferencing the underlying C++
iterator</dt>
</dl>
</dd>
<dt><b>Rationale:</b> The use of <code><a href=
"../../../bind/bind.html">boost::bind</a>()</code> allows C++ iterators
to be accessed through functions, member functions or data member
pointers. Customization of <code>NextPolicies</code> (e.g. using
<code><a href=
"return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a></code>)
is useful when it is expensive to copy sequence elements of a wrapped
class type. Customization of <code>Target</code> is useful when
<code>Accessor1</code> is a function object, or when a base class of
the intended target type would otherwise be deduced.</dt>
</dl>
<h2><a name="examples"></a>Examples</h2>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;vector&gt;
using namespace boost::python;
BOOST_PYTHON_MODULE(demo)
{
class_&lt;std::vector&lt;double&gt; &gt;("dvec")
.def("__iter__", iterator&lt;std::vector&lt;double&gt; &gt;())
;
}
</pre>
A more comprehensive example can be found in:
<dl>
<dt><code><a href=
"../../test/iterator.cpp">libs/python/test/iterator.cpp</a></code></dt>
<dt><code><a href=
"../../test/input_iterator.cpp">libs/python/test/input_iterator.cpp</a></code></dt>
<dt><code><a href=
"../../test/iterator.py">libs/python/test/input_iterator.py</a></code></dt>
<dd>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All
Rights Reserved.</i></p>
</dd>
</dl>
</body>
</html>

View File

@@ -1,140 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/list.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/list.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#list-spec">Class <code>list</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#list-spec-synopsis">Class <code>list</code>
synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
<a href=
"http://www.python.org/doc/current/lib/typesseq-mutable.html">list</a>
type.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="list-spec"></a>Class <code>list</code></h3>
<p>Exposes the <a href=
"http://www.python.org/doc/current/lib/typesseq-mutable.html">mapping
protocol</a> of Python's built-in <code>list</code> type. The semantics
of the constructors and member functions defined below can be fully
understood by reading the <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
definition. Since <code>list</code> is publicly derived from <code><a
href="object.html#object-spec">object</a></code>, the public object
interface applies to <code>list</code> instances as well.</p>
<h4><a name="list-spec-synopsis"></a>Class <code>list</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
class list : public object
{
public:
list(); // new list
template &lt;class T&gt;
explicit list(T const&amp; sequence);
template &lt;class T&gt;
void append(T const&amp; x);
template &lt;class T&gt;
long count(T const&amp; value) const;
template &lt;class T&gt;
void extend(T const&amp; x);
template &lt;class T&gt;
long index(T const&amp; x) const;
template &lt;class T&gt;
void insert(object const&amp; index, T const&amp; x); // insert object before index
object pop(); // remove and return item at index (default last)
object pop(long index);
object pop(object const&amp; index);
template &lt;class T&gt;
void remove(T const&amp; value);
void reverse(); // reverse *IN PLACE*
void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -&gt; -1, 0, 1
template &lt;class T&gt;
void sort(T const&amp; value);
};
}}
</pre>
<h2><a name="examples"></a>Example</h2>
<pre>
using namespace boost::python;
// Return the number of zeroes in the list
long zeroes(list l)
{
return l.count(0);
}
</pre>
<p>Revised 1 October, 2002</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,117 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/long.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/long.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#long_-spec">Class <code>long_</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#long_-spec-synopsis">Class <code>long_</code>
synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
<a href=
"http://www.python.org/doc/current/lib/typesnumeric.html">long</a>
integer type.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="long_-spec"></a>Class <code>long_</code></h3>
<p>Exposes the <a href=
"http://www.python.org/doc/current/lib/typesnumeric.html">numeric type
protocol</a> of Python's built-in <code>long</code> type. The semantics
of the constructors and member functions defined below can be fully
understood by reading the <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
definition. Since <code>long_</code> is publicly derived from <code><a
href="object.html#object-spec">object</a></code>, the public object
interface applies to <code>long_</code> instances as well.</p>
<h4><a name="long_-spec-synopsis"></a>Class <code>long_</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
class long_ : public object
{
public:
long_(); // new long_
template &lt;class T&gt;
explicit long_(T const&amp; rhs);
template &lt;class T, class U&gt;
long_(T const&amp; rhs, U const&amp; base);
};
}}
</pre>
<h2><a name="examples"></a>Example</h2>
<pre>
namespace python = boost::python;
// compute a factorial without overflowing
python::long_ fact(long n)
{
if (n == 0)
return python::long_(1);
else
return n * fact(n - 1);
}
</pre>
<p>Revised 1 October, 2002</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,299 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/lvalue_from_python.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/lvalue_from_pytype.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#lvalue_from_pytype-spec">Class Template
<code>lvalue_from_pytype</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#lvalue_from_pytype-spec-synopsis">Class Template
<code>lvalue_from_pytype</code> synopsis</a></dt>
<dt><a href="#lvalue_from_pytype-spec-ctors">Class Template
<code>lvalue_from_pytype</code> constructor</a></dt>
</dl>
</dd>
</dl>
<dl class="page-index">
<dt><a href="#extract_identity-spec">Class Template
<code>extract_identity</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#extract_identity-spec-synopsis">Class Template
<code>extract_identity</code> synopsis</a></dt>
<dt><a href="#extract_identity-spec-statics">Class Template
<code>extract_identity</code> static functions</a></dt>
</dl>
</dd>
<dt><a href="#extract_member-spec">Class Template
<code>extract_member</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#extract_member-spec-synopsis">Class Template
<code>extract_member</code> synopsis</a></dt>
<dt><a href="#extract_member-spec-statics">Class Template
<code>extract_member</code> static functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>&lt;boost/python/lvalue_from_pytype.hpp&gt;</code> supplies a
facility for extracting C++ objects from within Python instances of a
given type. This is typically useful for dealing with "traditional"
Python extension types.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="lvalue_from_pytype-spec"></a>Class template
<code>lvalue_from_pytype</code></h3>
<p>Class template <code>lvalue_from_pytype</code> will register
from_python converters which, given an object of the given Python type,
can extract references and pointers to a particular C++ type. Its
template arguments are:</p>
<table border="1" summary="lvalue_from_pytype template parameters">
<caption>
<b><code>lvalue_from_pytype</code> Requirements</b><br>
In the table below, <b><code>x</code></b> denotes an object of type
<code>PythonObject&amp;</code>
</caption>
<tr>
<th>Parameter</th>
<th>Requirements</th>
<th>Semantics</th>
</tr>
<tr>
<td><code>Extractor</code></td>
<td>a model of <a href=
"Extractor.html#Extractor-concept">Extractor</a> whose execute
function returns a reference type.</td>
<td>Extracts the lvalue from the Python object once its type has been
confirmed</td>
</tr>
<tr>
<td><code>python_type</code></td>
<td>A compile-time constant <code><a href=
"http://www.python.org/doc/2.2/ext/dnt-type-methods.html">PyTypeObject</a>*</code></td>
<td>The Python type of instances convertible by this converter.
Python subtypes are also convertible.</td>
</tr>
</table>
<h4><a name="lvalue_from_pytype-spec-synopsis"></a>Class template
<code>lvalue_from_pytype</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class Extractor, PyTypeObject const* python_type&gt;
struct lvalue_from_pytype
{
lvalue_from_pytype();
};
}}
</pre>
<h4><a name="lvalue_from_pytype-spec-ctors"></a>Class template
<code>lvalue_from_pytype</code> constructor</h4>
<pre>
lvalue_from_pytype();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Registers converters which can convert Python
objects of the given type to lvalues of the type returned by
<code>Extractor::execute</code>.</dt>
</dl>
<h3><a name="extract_identity-spec"></a>Class template
<code>extract_identity</code></h3>
<p><code>extract_identity</code> is a model of <a href=
"Extractor.html#Extractor-concept">Extractor</a> which can be used in the
common case where the C++ type to be extracted is the same as the Python
object type.</p>
<h4><a name="extract_identity-spec-synopsis"></a>Class template
<code>extract_identity</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class InstanceType&gt;
struct extract_identity
{
static InstanceType&amp; execute(InstanceType&amp; c);
};
}}
</pre>
<h4><a name="extract_identity-spec-statics"></a>Class template
<code>extract_identity</code> static functions</h4>
<pre>
InstanceType&amp; execute(InstanceType&amp; c);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>c</code></dt>
</dl>
<h3><a name="extract_member-spec"></a>Class template
<code>extract_member</code></h3>
<p><code>extract_member</code> is a model of <a href=
"Extractor.html#Extractor-concept">Extractor</a> which can be used in the
common case in the common case where the C++ type to be extracted is a
member of the Python object.</p>
<h4><a name="extract_member-spec-synopsis"></a>Class template
<code>extract_member</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class InstanceType, class MemberType, MemberType (InstanceType::*member)&gt;
struct extract_member
{
static MemberType&amp; execute(InstanceType&amp; c);
};
}}
</pre>
<h4><a name="extract_member-spec-statics"></a>Class template
<code>extract_member</code> static functions</h4>
<pre>
static MemberType&amp; execute(InstanceType&amp; c);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>c.*member</code></dt>
</dl>
<h2><a name="examples"></a>Example</h2>
This example presumes that someone has implemented the standard <a href=
"http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
module</a> from the Python documentation, and we want to build a module
which manipulates <code>Noddy</code>s. Since
<code>noddy_NoddyObject</code> is so simple that it carries no
interesting information, the example is a bit contrived: it assumes you
want to keep track of one particular object for some reason. This module
would have to be dynamically linked to the module which defines
<code>noddy_NoddyType</code>.
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/handle.hpp&gt;
#include &lt;boost/python/borrowed.hpp&gt;
#include &lt;boost/python/lvalue_from_pytype.hpp&gt;
// definition lifted from the Python docs
typedef struct {
PyObject_HEAD
} noddy_NoddyObject;
using namespace boost::python;
static handle&lt;&gt; cache;
bool is_cached(noddy_NoddyObject* x)
{
return x == cache.get();
}
void set_cache(noddy_NoddyObject* x)
{
cache = handle&lt;&gt;(borrowed(x));
}
BOOST_PYTHON_MODULE(noddy_cache)
{
def("is_cached", is_cached);
def("set_cache", set_cache);
// register Noddy lvalue converter
lvalue_from_pytype&lt;extract_identity&lt;noddy_NoddyObject&gt;,&amp;noddy_NoddyType&gt;();
}
</pre>
<h3>Python code</h3>
<pre>
&gt;&gt;&gt; import noddy
&gt;&gt;&gt; n = noddy.new_noddy()
&gt;&gt;&gt; import noddy_cache
&gt;&gt;&gt; noddy_cache.is_cached(n)
0
&gt;&gt;&gt; noddy_cache.set_cache(n)
&gt;&gt;&gt; noddy_cache.is_cached(n)
1
&gt;&gt;&gt; noddy_cache.is_cached(noddy.new_noddy())
0
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,182 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/make_function.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/make_function.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#make_function-spec">make_function</a></dt>
<dt><a href="#make_constructor-spec">make_constructor</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code><a href="#make_function-spec">make_function</a>()</code> and
<code><a href="#make_constructor-spec">make_constructor</a>()</code> are
the functions used internally by <code><a href=
"def.html#def-spec">def</a>()</code> and <code>class_&lt;&gt;::<a href=
"class.html#class_-spec-modifiers">def</a>()</code> to produce Python
callable objects which wrap C++ functions and member functions.</p>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="make_function-spec">template &lt;class F&gt;</a>
<a href="object.html#object-spec">object</a> make_function(F f)
template &lt;class F, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies)
template &lt;class F, class Policies, class Keywords&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; keywords)
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>F</code> is a function pointer or member
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, converts its arguments to C++ and calls <code>f</code>. If
<code>F</code> is a pointer-to-member-function type, the target object
of the function call (<code>*this</code>) will be taken from the first
Python argument, and subsequent Python arguments will be used as the
arguments to <code>f</code>. If <code>policies</code> are supplied, it
will be applied to the function as described <a href=
"CallPolicies.html">here</a>. If <code>keywords</code> are
supplied, the keywords will be applied in order to the final
arguments of the resulting function.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<pre>
<a name=
"make_constructor-spec"></a>template &lt;class T, class ArgList, class Generator&gt;
<a href="object.html#object-spec">object</a> make_constructor();
template &lt;class ArgList, class Generator, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_constructor(Policies const&amp; policies)
</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/Sequences.html">MPL sequence</a> of C++ argument
types (<i>A1,&nbsp;A2,...&nbsp;AN</i>) such that if
<code>a1,&nbsp;a2</code>...&nbsp;<code>aN</code> are objects of type
<i>A1,&nbsp;A2,...&nbsp;AN</i> respectively, the expression <code>new
Generator::apply&lt;T&gt;::type(a1,&nbsp;a2</code>...&nbsp;<code>aN</code>)
is valid. Generator is a model of <a href=
"HolderGenerator.html">HolderGenerator</a>.</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&lt;T&gt;::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>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<p>C++ function exposed below returns a callable object wrapping one of
two functions.</p>
<pre>
#include &lt;boost/python/make_function.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
char const* foo() { return "foo"; }
char const* bar() { return "bar"; }
using namespace boost::python;
object choose_function(bool selector)
{
if (selector)
return boost::python::make_function(foo);
else
return boost::python::make_function(bar);
}
BOOST_PYTHON_MODULE(make_function_test)
{
def("choose_function", choose_function);
}
</pre>
It can be used this way in Python:
<pre>
&gt;&gt;&gt; from make_function_test import *
&gt;&gt;&gt; f = choose_function(1)
&gt;&gt;&gt; g = choose_function(0)
&gt;&gt;&gt; f()
'foo'
&gt;&gt;&gt; g()
'bar'
</pre>
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,143 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/manage_new_object.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/manage_new_object.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#manage_new_object-spec">Class
<code>manage_new_object</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#manage_new_object-spec-synopsis">Class
<code>manage_new_object</code> synopsis</a></dt>
<dt><a href="#manage_new_object-spec-metafunctions">Class
<code>manage_new_object</code> metafunctions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="manage_new_object-spec"></a>Class
<code>manage_new_object</code></h3>
<p><code>manage_new_object</code> is a model of <a href=
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
which can be used to wrap C++ functions which return a pointer to an
object allocated with a <i>new-expression</i>, and expect the caller to
take responsibility for deleting that object.</p>
<h4><a name="manage_new_object-spec-synopsis"></a>Class
<code>manage_new_object</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
struct manage_new_object
{
template &lt;class T&gt; struct apply;
};
}}
</pre>
<h4><a name="manage_new_object-spec-metafunctions"></a>Class
<code>manage_new_object</code> metafunctions</h4>
<pre>
template &lt;class T&gt; struct apply
</pre>
<dl class="metafunction-semantics">
<dt><b>Requires:</b> <code>T</code> is <code>U*</code> for some
<code>U</code>.</dt>
<dt><b>Returns:</b> <code>typedef <a href=
"to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>&lt;T&gt;
type;</code></dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<p>In C++:</p>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/manage_new_object.hpp&gt;
#include &lt;boost/python/return_value_policy.hpp&gt;
struct Foo {
Foo(int x) : x(x){}
int get_x() { return x; }
int x;
};
Foo* make_foo(int x) { return new Foo(x); }
// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE(my_module)
{
def("make_foo", make_foo, return_value_policy&lt;manage_new_object&gt;())
class_&lt;Foo&gt;("Foo")
.def("get_x", &amp;Foo::get_x)
;
}
</pre>
In Python:
<pre>
&gt;&gt;&gt; from my_module import *
&gt;&gt;&gt; f = make_foo(3) # create a Foo object
&gt;&gt;&gt; f.get_x()
3
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,108 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/module.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/module.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#macros">Macros</a>
<dd>
<dl class="page-index">
<dt><a href=
"#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a>
</dl>
<dt><a href="#examples">Example(s)</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>This header provides the basic facilities needed to create a
Boost.Python extension module.
<h2><a name="macros"></a>Macros</h2>
<p><a name=
"BOOST_PYTHON_MODULE-spec"><code>BOOST_PYTHON_MODULE(name)</code></a>
is used to declare Python <a href=
"http://www.python.org/doc/2.2/ext/methodTable.html#SECTION003400000000000000000">
module initialization functions</a>. The <code>name</code> argument must
exactly match the name of the module to be initialized, and must conform to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming
rules</a>. Where you would normally write
<pre>
extern &quot;C&quot; void init<i>name</i>()
{
...
}
</pre>
Boost.Python modules should be initialized with
<pre>
BOOST_PYTHON_MODULE(<i>name</i>)
{
...
}
</pre>
This macro generates two functions in the scope where it is used:
<code>extern&nbsp;&quot;C&quot;&nbsp;void&nbsp;init<i>name</i>()</code>,
and <code>void&nbsp;init_module_<i>name</i>()</code>, whose body must
follow the macro invocation. <code>init_<i>name</i></code> passes
<code>init_module_<i>name</i></code> to <code><a
href="errors.html#handle_exception">handle_exception</a>()</code> so
that any C++ exceptions generated are safely processeed. During the
body of <code>init_<i>name</i></code>, the current <code><a
href="scope.html#scope-spec">scope</a></code> refers to the module
being initialized.
<h2><a name="examples"></a>Example(s)</h2>
<p>C++ module definition:
<pre>
#include &lt;boost/python/module.hpp&gt;
BOOST_PYTHON_MODULE(xxx)
{
throw &quot;something bad happened&quot;
}
</pre>
Interactive Python:
<pre>
&gt;&gt;&gt; import xxx
Traceback (most recent call last):
File "<stdin>", line 1, in ?
RuntimeError: Unidentifiable C++ Exception
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>

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