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
nobody
f5e65866d4 This commit was manufactured by cvs2svn to create tag
'Version_1_27_0'.

[SVN r12749]
2002-02-07 13:33:59 +00:00
nobody
ca162434ca This commit was manufactured by cvs2svn to create branch 'RC_1_27_0'.
[SVN r12739]
2002-02-06 03:32:50 +00:00
88 changed files with 2111 additions and 6379 deletions

66
Jamfile
View File

@@ -4,24 +4,14 @@ subproject libs/python ;
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
PYTHON_PROPERTIES
+= <metrowerks><*><cxxflags>"-inline deferred"
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
<define>BOOST_PYTHON_DYNAMIC_LIB
<define>BOOST_PYTHON_V2
;
{
local BOOST_PYTHON_V2_PROPERTIES
= $(PYTHON_PROPERTIES)
<metrowerks><*><cxxflags>"-inline deferred"
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
<define>BOOST_PYTHON_DYNAMIC_LIB
<define>BOOST_PYTHON_V2
;
local gcc-release-properties
= <optimization>speed <cxxflags>-fomit-frame-pointer
<inlining>on <cxxflags>-foptimize-sibling-calls
;
local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) <gcc><release>$(gcc-release-properties)
;
dll bpl
:
src/converter/from_python.cpp
@@ -36,61 +26,45 @@ include <module@>python.jam ;
src/objects.cpp
src/converter/builtin_converters.cpp
:
$(BOOST_PYTHON_V2_PROPERTIES)
$(PYTHON_PROPERTIES)
<define>BOOST_PYTHON_SOURCE
;
# -------- general test -------
extension m1 : test/m1.cpp <dll>bpl
:
extension m1 : test/m1.cpp <lib>bpl
:
: debug-python
;
extension m2 : test/m2.cpp <dll>bpl
extension m2 : test/m2.cpp <lib>bpl
:
: ;
: debug-python ;
boost-python-runtest try : test/newtest.py <pyd>m1 <pyd>m2 : : ;
boost-python-runtest try : test/newtest.py <lib>m1 <lib>m2 : : debug-python ;
# ----------- builtin converters -----------
extension builtin_converters_ext : test/test_builtin_converters.cpp <dll>bpl
extension builtin_converters_ext : test/test_builtin_converters.cpp <lib>bpl
:
:
: debug-python
;
boost-python-runtest test_builtin_converters : test/test_builtin_converters.py
<pyd>builtin_converters_ext
<lib>builtin_converters_ext
:
:
: debug-python
;
# ----------- pointer adoption -----------
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <dll>bpl
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <lib>bpl
:
:
: debug-python
;
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
<pyd>test_pointer_adoption_ext
<lib>test_pointer_adoption_ext
:
:
: debug-python
;
}
unit-test indirect_traits_test
: test/indirect_traits_test.cpp : <include>$(BOOST_ROOT) ;
unit-test destroy_test
: test/destroy_test.cpp : <include>$(BOOST_ROOT) ;
unit-test pointer_type_id_test
: test/pointer_type_id_test.cpp : <include>$(BOOST_ROOT) ;
unit-test select_from_python_test
: test/select_from_python_test.cpp
src/converter/type_id.cpp
src/converter/registry.cpp # MWerks needs this for some reason
: $(PYTHON_PROPERTIES)
;

View File

@@ -9,7 +9,7 @@
# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test
#
# Declares the following targets:
# 1. libboost_python.dll/.so, a dynamic library to be linked with all
# 1. libboost_python, a static link library to be linked with all
# Boost.Python modules
#
# 2. pairs of test targets of the form <name>.test and <name>.run
@@ -66,7 +66,7 @@ local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_DYNAMIC_LIB
#######################
rule bpl-test ( test-name : sources + )
{
boost-python-test $(test-name) : $(sources) <dll>boost_python ;
boost-python-test $(test-name) : $(sources) <lib>libboost_python ;
}
#######################
@@ -81,14 +81,14 @@ local CPP_SOURCES =
init_function module_builder objects cross_module errors
;
lib boost_python_static : ../src/$(CPP_SOURCES).cpp
lib libboost_python_static : ../src/$(CPP_SOURCES).cpp
# requirements
: $(BOOST_PYTHON_INCLUDES)
<shared-linkable>true
<define>BOOST_PYTHON_STATIC_LIB=1
$(PYTHON_PROPERTIES) ;
dll boost_python
dll libboost_python
# $(SUFDLL[1])
: ../src/$(CPP_SOURCES).cpp
# requirements
@@ -104,7 +104,7 @@ bpl-test boost_python_test
: ../test/comprehensive.cpp ;
boost-python-runtest comprehensive
: ../test/comprehensive.py <pyd>boost_python_test <dll>boost_python ;
: ../test/comprehensive.py <lib>boost_python_test <lib>libboost_python ;
############# simple tests from ../example ############
@@ -114,7 +114,7 @@ rule boost-python-example-runtest ( name )
: ../example/$(name).cpp ;
boost-python-runtest $(name)
: ../example/test_$(name).py <pyd>$(name) ;
: ../example/test_$(name).py <lib>$(name) ;
}
@@ -139,7 +139,7 @@ bpl-test noncopyable_import : ../example/noncopyable_import.cpp ;
rule boost-python-multi-example-runtest ( test-name : modules + )
{
boost-python-runtest $(test-name)
: ../example/tst_$(test-name).py <pyd>$(modules) <dll>boost_python
: ../example/tst_$(test-name).py <lib>$(modules) <lib>libboost_python
: : : $(PYTHON_VECT_ITERATIONS) ;
}

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

@@ -37,12 +37,19 @@ namespace python = boost::python;
BOOST_PYTHON_MODULE_INIT(getting_started1)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("getting_started1");
// Add regular functions to the module.
this_module.def(greet, "greet");
this_module.def(square, "square");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}
</pre>
</blockquote>

View File

@@ -47,6 +47,8 @@ namespace python = boost::python;
BOOST_PYTHON_MODULE_INIT(getting_started2)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("getting_started2");
@@ -63,6 +65,11 @@ BOOST_PYTHON_MODULE_INIT(getting_started2)
// Even better, invite() can also be made a member of hello_class!!!
hello_class.def(invite, "invite");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}
</blockquote></pre>
<p>

View File

@@ -78,19 +78,26 @@ namespace python = boost::python;
BOOST_PYTHON_MODULE_INIT(my_module)
{
    python::module_builder my_module("my_module");
    python::class_builder&lt;Base&gt; base_class(my_module, "Base");
    base_class.def(python::constructor&lt;void&gt;());
    python::class_builder&lt;Derived&gt; derived_class(my_module, "Derived");
    derived_class.def(python::constructor&lt;void&gt;());
<b>// Establish the inheritance relationship between Base and Derived
derived_class.declare_base(base_class);</b>
my_module.def(derived_as_base, "derived_as_base");
my_module.def(get_name, "get_name");
my_module.def(get_derived_x, "get_derived_x");
    try
    {
       python::module_builder my_module("my_module");
       python::class_builder&lt;Base&gt; base_class(my_module, "Base");
       base_class.def(python::constructor&lt;void&gt;());
       python::class_builder&lt;Derived&gt; derived_class(my_module, "Derived");
       derived_class.def(python::constructor&lt;void&gt;());
<b>// Establish the inheritance relationship between Base and Derived
derived_class.declare_base(base_class);</b>
my_module.def(derived_as_base, "derived_as_base");
my_module.def(get_name, "get_name");
my_module.def(get_derived_x, "get_derived_x");
    }
    catch(...)
    {
       python::handle_exception();    // Deal with the exception for Python
    }
}
</pre>
</blockquote>

View File

@@ -151,9 +151,16 @@ struct baz_callback {
BOOST_PYTHON_MODULE_INIT(foobar)
{
boost::python::module_builder foobar("foobar");
boost::python::class_builder&lt;baz,baz_callback&gt; baz_class("baz");
baz_class.def(&amp;baz::calls_pure, "calls_pure");
try
{
boost::python::module_builder foobar("foobar");
boost::python::class_builder&lt;baz,baz_callback&gt; baz_class("baz");
baz_class.def(&amp;baz::calls_pure, "calls_pure");
}
catch(...)
{
boost::python::handle_exception(); // Deal with the exception for Python
}
}
</pre>
</blockquote>

View File

@@ -1,31 +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 - 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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Acknowledgments</h2>
</td>
</tr>
</table>
<hr>
{{text}}
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,31 +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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</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 -->
05 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,62 +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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</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>{{Introductory text}}</p>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="call-spec"></a>call
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}</dt>
<dt><b>Effects:</b> {{text}}</dt>
<dt><b>Postconditions:</b> {{text}}</dt>
<dt><b>Returns:</b> {{text}}</dt>
<dt><b>Throws:</b> {{text}}</dt>
<dt><b>Complexity:</b> {{text}}</dt>
<dt><b>Rationale:</b> {{text}}</dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
<p>{{Example(s)}}</p>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,337 +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/class.hpp&gt;,
&lt;boost/python/class_fwd.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">Boost.Python</h1>
<h2 align="center">Headers &lt;boost/python/class.hpp&gt;,
&lt;boost/python/class_fwd.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="#class_-spec">Class template <code>class_</code></a>
<dd>
<dl class="page-index">
<dt><a href="#class_-spec-synopsis">Class <code>class_</code>
synopsis</a>
<dt><a href="#class_-spec-ctors">Class <code>class_</code>
constructors</a>
<dt><a href="#class_-spec-modifiers">Class <code>class_</code>
modifier functions</a>
<dt><a href="#class_-spec-observers">Class <code>class_</code>
observer functions</a>
</dl>
<dt><a href="#bases-spec">Class template <code>bases</code></a>
<dd>
<dl class="page-index">
<dt><a href="#bases-spec-synopsis">Class <code>bases</code>
synopsis</a>
</dl>
<dt><a href="#args-spec">Class template <code>args</code></a>
<dd>
<dl class="page-index">
<dt><a href="#args-spec-synopsis">Class <code>args</code>
synopsis</a>
</dl>
</dl>
<dt><a href="#examples">Example(s)</a>
</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, and the <code>args</code> and <code>bases</code>
utility class templates in the anonymous namespace (the latter definitions
will probably be moved in a future release).
<p><code>&lt;boost/python/class_fwd.hpp&gt;</code> contains a forward
declaration of the <code>class_</code> class template.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class_-spec"></a>Class template <code>class_&lt;T, Bases, <a
href="HolderGenerator.html">HolderGenerator</a>&gt;</code></h3>
<p>Creates a Python class associated with the C++ type passed as its first
parameter. Its template arguments are:<br>
<br>
<table border="1" summary="class_ template parameters">
<tr>
<th>Parameter
<th>Requirements
<th>Default
<tr>
<td><code>T</code>
<td>A class type.
<tr>
<td><code>Bases</code>
<td>An <a href="../../../mpl/doc/Sequences.html">MPL sequence</a> of
C++ base classes of <code>T</code>.
<td>An unspecified empty sequence
<tr>
<td><code>HolderGenerator</code>
<td>A model of <code><a href=
"HolderGenerator.html">HolderGenerator</a></code>.
<td><code>boost::python::objects::value_holder_generator</code>
</table>
<h4><a name="class_-spec-synopsis"></a>Class template <code>class_</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T
, class Bases = <i>none</i>
, class HolderGenerator = objects::value_holder_generator&gt;
class class_
{
class_();
class_(char const* name);
template &lt;class F&gt;
class_&amp; def(char const* name, F f);
template &lt;class Fn, class CallPolicy&gt;
class_&amp; def(char const* name, Fn fn, CallPolicy policy);
template &lt;class Args&gt;
class_&amp; def_init(Args const&amp; = Args());
class_&amp; def_init();
ref object() const;
};
}}
</pre>
<h4><a name="class_-spec-ctors"></a>Class template <code>class_</code>
constructors</h4>
<pre>
class_()
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The platform's <code>std::type_info::name()</code>
implementation produces a string which corresponds to the type's
declaration in C++
<dt><b>Effects:</b> Constructs a <code>class_</code> object which
generates a Boost.Python extension class with the same name as
<code>T</code>.
<dt><b>Rationale:</b> Many platforms can generate reasonable names for
Python classes without user intervention.
</dl>
<pre>
class_(char const* name)
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>.
<dt><b>Effects:</b> Constructs a <code>class_</code> object which
generates a Boost.Python extension class named <code>name</code>.
<dt><b>Rationale:</b> Gives the user full control over class naming.
</dl>
<h4><a name="class_-spec-modifiers"></a>Class template <code>class_</code>
modifier functions</h4>
<pre>
template &lt;class F&gt;
class_&amp; def(char const* name, F f)
template &lt;class Fn, class CallPolicy&gt;
class_&amp; def(char const* name, Fn f, CallPolicy policy)
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>f</code> is a non-null pointer-to-function or
pointer-to-member-function. <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>. In the first form, the return type of
<code>f</code> is not a reference and is not a pointer other
than <code>char const*</code> or <code>PyObject*</code>. In the
second form <code>policy</code> is a model of <a
href="CallPolicies.html">CallPolicies</a>.
<dt><b>Effects:</b> Adds the result of <code><a href=
"make_function.html#make_function-spec">make_function</a>(f)</code> to
the Boost.Python extension class being defined, with the given
<code>name</code>. If the extension class already has an attribute named
<code><i>name</i></code>, the usual <a href=
"overloading.html">overloading procedure</a> applies.
<dt><b>Returns:</b> <code>*this</code>
</dl>
<pre>
template &lt;class Args&gt;
class_&amp; def_init(Args const&amp; argument_types)
class_&amp; def_init()
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> in the first form, argument_types must be an <a
href="../../../mpl/doc/Sequences.html">MPL sequence</a> of C++ argument
types (<i>A1, A2,... AN</i>) such that if
<code>a1, a2</code>... <code>aN</code> are objects of type
<i>A1, A2,... AN</i> respectively, the expression
<code>T(a1, a2</code>... <code>aN</code>) is valid. In the second form,
the expression <code>T()</code> must be valid.
<dt><b>Effects:</b> Adds the result of <code><a href=
"make_function.html#make_constructor-spec">make_constructor</a>&lt;T,Args,HolderGenerator&gt;()</code>
to the Boost.Python extension class being defined with the name
"__init__". If the 2nd form is used, an unspecified empty <a href=
"../../../mpl/doc/Sequences.html">MPL sequence</a> type is substituted
for <code>Args</code>. If the extension class already has an "__init__"
attribute, the usual <a href="http:overloading.html">overloading
procedure</a> applies.
<dt><b>Returns:</b> <code>*this</code>
<dt><b>Rationale:</b> Allows users to easily expose a class' constructor
to Python.
</dl>
<h4><a name="class_-spec-observers"></a>Class template <code>class_</code>
observer functions</h4>
<pre>
ref object() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> A <code>ref</code> object which holds a reference to
the Boost.Python extension class object created by the
<code>class_</code> constructor.
<dt><b>Rationale:</b> Mostly not needed by users, since <code><a href=
"module.html#add-spec">module::add</a>()</code> uses this to insert the
extension class in the module.
</dl>
<h3><a name="args-spec"></a>Class template
<code>args&lt;T1, T2,</code>...<code>TN&gt;</code></h3>
<p>Essentially an alias for <code>boost::mpl::type_list</code> which users
can use in <code>def_init</code> calls to make their code more readable.
Currently it is in the global unnammed namespace, but that will probably
change.
<h4><a name="args-spec-synopsis"></a>Class template <code>args</code>
synopsis</h4>
<pre>
namespace
{
template &lt;T1 = <i>unspecified</i>,...TN = <i>unspecified</i>&gt;
struct args : ::boost::mpl::type_list&lt;T1,...TN&gt;::type
{};
}
</pre>
<h3><a name="bases-spec"></a>Class template
<code>bases&lt;T1, T2,</code>...<code>TN&gt;</code></h3>
<p>Essentially an alias for <code>boost::mpl::type_list</code> which users
can use in <code>class_&lt;</code>...<code>&gt;</code> instantiations to
make their code more readable. Currently it is in the global unnammed
namespace, but that will probably change.
<h4><a name="bases-spec-synopsis"></a>Class template <code>bases</code>
synopsis</h4>
<pre>
namespace
{
template &lt;T1 = <i>unspecified</i>,...TN = <i>unspecified</i>&gt;
struct bases : ::boost::mpl::type_list&lt;T1,...TN&gt;::type
{};
}
</pre>
<h2><a name="examples"></a>Example(s)</h2>
<p>Given a C++ class declaration:
<pre>
class Foo : public Bar, public Baz
{
public:
Foo(int, char const*);
Foo(double);
std::string const&amp; name() { return m_name; }
void name(char const*);
private:
...
};
</pre>
A corresponding Boost.Python extension class can be created with:
<pre>
using namespace boost::python;
ref foo =
class_&lt;Foo,bases&lt;Bar,Baz&gt; &gt;()
.def_init(args&lt;int,char const*&gt;())
.def_init(args&lt;double&gt;())
.def("get_name", &amp;Foo::get_name, return_internal_reference&lt;&gt;())
.def("set_name", &amp;Foo::set_name)
.object();
</pre>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--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,90 +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 - 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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</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-public">Public Library 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>Boost.Python 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 Boost.Python.</p>
<table summary="application defined macros" cellspacing="10" width="100%">
<tr>
<td><b>Macro</b></td>
<td><b>Meaning</b></td>
</tr>
<tr>
<td>{{macro}}</td>
<td>{{meaning}}</td>
</tr>
<tr>
<td>{{macro}}</td>
<td>{{meaning}}</td>
</tr>
</table>
<h2><a name="lib-defined-public"></a>Public Library Defined Macros</h2>
<p>These macros are defined by Boost.Python but are expected to be used by application
code.</p>
<table summary="public library defined macros" cellspacing="10" width="100%">
<tr>
<td><b>Macro</b></td>
<td><b>Meaning</b></td>
</tr>
<tr>
<td>{{macro}}</td>
<td>{{meaning}}</td>
</tr>
<tr>
<td>{{macro}}</td>
<td>{{meaning}}</td>
</tr>
</table>
<h2><a name="lib-defined-impl"></a>Library Defined Implementation Macros</h2>
<p>These macros are defined by Boost.Python and are implementation details of interest
only to implementers.</p>
<table summary="library defined implementation macros" cellspacing="10" width="100%">
<tr>
<td><b>Macro</b></td>
<td><b>Meaning</b></td>
</tr>
<tr>
<td>{{macro}}</td>
<td>{{meaning}}</td>
</tr>
<tr>
<td>{{macro}}</td>
<td>{{meaning}}</td>
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,135 +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/copy_const_reference.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">Boost.Python</h1>
<h2 align="center">Header
&lt;boost/python/copy_const_reference.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="#copy_const_reference-spec">Class
<code>copy_const_reference</code></a>
<dd>
<dl class="page-index">
<dt><a href="#copy_const_reference-spec-synopsis">Class
<code>copy_const_reference</code> synopsis</a>
<dt><a href="#copy_const_reference-spec-metafunctions">Class
<code>copy_const_reference</code> metafunctions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</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=
"ResultConverterGenerator.html">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.
<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><b>Returns:</b> <code>typedef <a href=
"to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T&gt;
type;</code>
</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_INIT(my_module)
{
module m("my_module")
.add(
class_&lt;Bar&gt;()
)
.add(
class_&lt;Foo&gt;()
.def_init(args&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 -->
15 February, 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,135 +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/copy_non_const_reference.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">Boost.Python</h1>
<h2 align="center">Header
&lt;boost/python/copy_non_const_reference.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="#copy_non_const_reference-spec">Class
<code>copy_non_const_reference</code></a>
<dd>
<dl class="page-index">
<dt><a href="#copy_non_const_reference-spec-synopsis">Class
<code>copy_non_const_reference</code> synopsis</a>
<dt><a href="#copy_non_const_reference-spec-metafunctions">Class
<code>copy_non_const_reference</code> metafunctions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</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=
"ResultConverterGenerator.html">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.
<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><b>Returns:</b> <code>typedef <a href=
"to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T&gt;
type;</code>
</dl>
<h2><a name="examples"></a>Example</h2>
<p>C++ code:
<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_INIT(my_module)
{
module m("my_module")
.add(
class_&lt;Bar&gt;()
)
.add(
class_&lt;Foo&gt;()
.def_init(args&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 -->
05 November, 2001
<!--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,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">Boost.Python</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=
"ResultConverterGenerator.html">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 -->
05 November, 2001
<!--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,34 +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 - 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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Definitions</h2>
</td>
</tr>
</table>
<hr>
<dl class="definitions">
<dt><b>{{term}}:</b> {{definition}}</dt>
<dt><b>{{term}}:</b> {{definition}}</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,232 +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">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/errors.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="#class-spec">Class <code>error_already_set</code></a>
<dd>
<dl class="page-index">
<dt><a href="#error_already_set-spec-synopsis">Class
<code>error_already_set</code> synopsis</a>
</dl>
</dl>
<dt><a href="#functions">Functions</a>
<dd>
<dl class="page-index">
<dt><a href="#handle_exception-spec">handle_exception</a>
<dt><a href="#expect_non_null-spec">expect_non_null</a>
</dl>
<dt><a href="#examples">Examples</a>
</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.
<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>.
<h4><a name="class-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><b>Effects:</b> The first form calls <code>f()</code> inside a
<code>try</code> block whose <code>catch</code> clauses set an
appropriate Python exception for the C++ exception caught, returning
<code>true</code> if an exception was caught, <code>false</code>
otherwise. The second form passes a function which rethrows the exception
currently being handled to the first form.
<dt><b>Postconditions:</b> No exception is being handled
<dt><b>Throws:</b> nothing
<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: <a href=
"make_function.html#make_function-spec">make_function()</a>, <a href=
"make_function.html#make_constructor-spec">make_constructor()</a>, <a
href="module.html#def-spec">module::def</a> and <a href=
"class.html#def-spec">class_::def</a>). 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.
</dl>
<pre>
<a name="expect_non_null-spec">PyObject* expect_non_null(PyObject* x);</a>
template &lt;class T&gt; T* expect_non_null(T* x);
</pre>
<dl class="expect_non_null-semantics">
<dt><b>Returns:</b> <code>x</code>
<dt><b>Throws:</b> <code><a href=
"#error_already_set-spec">error_already_set()</a></code> iff <code>x ==
0</code>.
<dt><b>Rationale:</b> Simplifies error-handling when calling many
functions in the <a href=
"http://www.python.org/doc/2.2/api/api.html">Python/C API</a>, which
return 0 on error.
</dl>
<h2><a name="examples"></a>Examples</h2>
<pre>
#include &lt;string&gt;
#include &lt;boost/python/errors.hpp&gt;
#include &lt;boost/python/reference.hpp&gt;
// Returns a std::string which has the same value as obj's "__name__"
// attribute.
std::string get_name(boost::python::ref obj)
{
// throws if there's no __name__ attribute
PyObject* p = boost::python::expect_non_null(
PyObject_GetAttrString(obj.get(), "__name__"));
// throws if it's not a Python string
std::string result(
boost::python::expect_non_null(
PyString_AsString(p)));
Py_XDECREF(p); // Done with p
return result;
}
//
// Demonstrate form 1 of handle_exception
//
// Place 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, PyObject* a, PyObject* b)
{
result = PyInt_FromLong(
get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
}
// 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), a1, 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(boost::python::ref(a1)) == get_name(boost::python::ref(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 -->
05 November, 2001
<!--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,38 +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 - 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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Frequently Asked Questions (FAQs)</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#question1">{{question}}</a></dt>
<dt><a href="#question2">{{question}}</a></dt>
</dl>
<h2><a name="question1"></a>{{question}}</h2>
<p>{{answer}}</p>
<h2><a name="question2"></a>{{question}}</h2>
<p>{{answer}}</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,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">Boost.Python</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().size();
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--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,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">Boost.Python</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 -->
05 November, 2001
<!--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,41 +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</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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Index</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="overview.html">Overview</a></dt>
<dt><a href="reference.html">Reference</a></dt>
<dt><a href="configuration.html">Configuration Information</a></dt>
<dt><a href="rationale.html">Rationale</a></dt>
<dt><a href="definitions.html">Definitions</a></dt>
<dt><a href="faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="bibliography.html">Bibliography</a></dt>
<dt><a href="acknowledgments.html">Acknowledgments</a></dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,279 +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/lvalue_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">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/lvalue_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="#lvalue_from_python-spec">Class Template <code>lvalue_from_python</code></a>
<dd>
<dl class="page-index">
<dt><a href="#lvalue_from_python-spec-synopsis">Class Template
<code>lvalue_from_python</code> synopsis</a>
<dt><a href="#lvalue_from_python-spec-ctors">Class Template
<code>lvalue_from_python</code> constructor</a>
</dl>
</dl>
<dl class="page-index">
<dt><a href="#get_member-spec">Class Template <code>get_member</code></a>
<dd>
<dl class="page-index">
<dt><a href="#get_member-spec-synopsis">Class Template
<code>get_member</code> synopsis</a>
<dt><a href="#get_member-spec-statics">Class Template
<code>get_member</code> static functions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>&lt;boost/python/lvalue_from_python.hpp&gt;</code> supplies
a facility for extracting C++ objects from within instances of a
given Python type. This is typically useful for dealing with
&quot;traditional&quot; Python extension types.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="lvalue_from_python-spec"></a>Class template <code>lvalue_from_python</code></h3>
<p>Class template <code>lvalue_from_python</code> will register
from_python converters which extract a references and pointers to
a C++ type which is held within an object of a given Python
type. Its template arguments are:
<p>
<table border="1" summary="lvalue_from_python template parameters">
<caption>
<b><code>lvalue_from_python</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>Requirements
<th>Description
<th>Default
<tr>
<td><code>python_type</code>
<td>A compile-time constant <code><a
href="http://www.python.org/doc/2.2/ext/dnt-type-methods.html">PyTypeObject</a>*</code>
<td>The Python type of instances convertible by this
converter. Python subtypes are also convertible.
<tr>
<td><code>Value</code>
<td>A non-reference type.
<td>The C++ type to be extracted
<tr>
<td><code>PythonObject</code>
<td>initial <code>sizeof(PyObject)</code> bytes are
layout-compatible with <code>PyObject</code>.
<td>The C++ type used to hold Python instances of
<code>python_type</code>.
<td><code>Value</code>
<tr>
<td><code>Extract</code>
<td><code>Value&amp; v = Extract::execute(x);</code>
<td>A type whose static <code>execute</code> function extracts a <code>Value</code> reference from within an object of type <code>PythonObject</code>.
<td>An unspecified type whose <code>execute</code> function consists of <code>return&nbsp;x;</code>
</table>
If only the first two template arguments are supplied, these
converters extract the entire <code>PythonObject</code> as a
whole.
<p>
If the lifetime of the <code>lvalue_from_python</code> object ends
before the last attempt to convert to one its target types, the
behavior is undefined. The easiest way to ensure correct behavior
is to declare an <code>lvalue_from_python</code> instance as a
static local in a <a
href="module.html#BOOST_PYTHON_MODULE_INIT-spec">module init
function</a>, as shown in the <a href="#examples">example</a>
below.
<h4><a name="lvalue_from_python-spec-synopsis"></a>Class template <code>lvalue_from_python</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;
PyTypeObject const* python_type
, class Value
, class PythonObject = Value
, class Extract = <i>unspecified</i>
&gt;
class lvalue_from_python
{
lvalue_from_python();
};
}}
</pre>
<h4><a name="lvalue_from_python-spec-ctors"></a>Class template <code>lvalue_from_python</code> constructor</h4>
<pre>
lvalue_from_python();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Registers from_python converters which
extract
<code>Value&amp;</code>, <code>Value const&amp;</code>,
<code>Value*</code>, or <code>Value const*</code> from Python
objects of type <code>python_type</code> using
<code>Extract::execute()</code>.
</dl>
<h3><a name="get_member-spec"></a>Class template <code>get_member</code></h3>
<p><code>get_member</code> can be used with
<code>lvalue_from_python</code> in the common case where the C++
type to be extracted is a member of the Python object.
<h4><a name="get_member-spec-synopsis"></a>Class template <code>get_member</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class Class, class Member, Member (Class::*mp)&gt;
struct get_member
{
static Member&amp; execute(Class&amp; c);
};
}}
</pre>
<h4><a name="get_member-spec-statics"></a>Class template <code>get_member</code> static functions</h4>
<pre>
Member&amp; execute(Class&amp; c);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>c.*mp</code>
</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.
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/reference.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
// definition lifted from the Python docs
typedef struct {
PyObject_HEAD
} noddy_NoddyObject;
using namespace boost::python;
static ref cache;
bool is_cached(noddy_NoddyObject* x)
{
return x == cache.get();
}
void set_cache(noddy_NoddyObject* x)
{
cache.reset((PyObject*)x, ref::increment_count);
}
BOOST_PYTHON_MODULE_INIT(noddy_cache)
{
module noddy_cache(&quot;noddy_cache&quot;)
.def(&quot;is_cached&quot;, is_cached)
.def(&quot;set_cache&quot;, set_cache)
;
}
</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 -->
05 November, 2001
<!--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,146 +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/make_function.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">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/make_function.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#functions">Functions</a>
<dd>
<dl class="page-index">
<dt><a href="#make_function-spec">make_function</a>
<dt><a href="#make_constructor-spec">make_constructor</a>
</dl>
<dt><a href="#examples">Example</a>
</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>class_&lt;&gt;::<a href=
"class.html#class_-spec-modifiers">def</a></code>, <code>class_&lt;&gt;::<a
href="module.html#module-spec-modifiers">def</a></code>, and
<code>class_&lt;&gt;::<a href=
"class.html#class_-spec-modifiers">def_init</a></code> to produce Python
callable objects which wrap C++ functions and member functions.
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="make_function-spec">template &lt;class F&gt;</a>
objects::function* make_function(F f)&lt;/a&gt;
template &lt;class F, class Policies&gt;
objects::function* make_function(F f, Policies const&amp; policies)
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>F</code> is a function pointer or member
function pointer type
<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
must be a model of <a href="CallPolicies.html">CallPolicies</a>, and will
be applied to the function as described <a href=
"CallPolicies.html">here</a>.
<dt><b>Returns:</b> A pointer convertible to <code>PyObject*</code> which
refers to the new Python callable object.
</dl>
<pre>
<a name=
"make_constructor-spec">template &lt;class T, class ArgList, class Generator&gt;
objects::function* make_constructor();</a>
</pre>
<dl class="make_constructor-semantics">
<dt><b>Requires:</b> <code>T</code> is a class type. <code>ArgList</code>
is an <a href="../../../mpl/doc/Sequences.html">MPL sequence</a> of C++
argument types (<i>A1, A2,... AN</i>) such that if
<code>a1, a2</code>... <code>aN</code> are objects of type
<i>A1, A2,... AN</i> respectively, the expression <code>new
Generator::apply&lt;T&gt;::type(a1, a2</code>... <code>aN</code>) is
valid. Generator is a model of <a href=
"HolderGenerator.html">HolderGenerator</a>.
<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. The result is
installed in the extension class object.
<dt><b>Returns:</b> The new Python callable object
</dl>
<h2><a name="examples"></a>Example</h2>
<p>C++ function exposed below returns a callable object wrapping one of two
functions.
<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"; }
PyObject* choose_function(bool selector)
{
if (selector)
return boost::python::make_function(foo);
else
return boost::python::make_function(bar);
}
BOOST_PYTHON_MODULE_INIT(make_function_test)
{
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 -->
14 February 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,130 +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/manage_new_object.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">Boost.Python</h1>
<h2 align="center">Header
&lt;boost/python/manage_new_object.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="#manage_new_object-spec">Class
<code>manage_new_object</code></a>
<dd>
<dl class="page-index">
<dt><a href="#manage_new_object-spec-synopsis">Class
<code>manage_new_object</code> synopsis</a>
<dt><a href="#manage_new_object-spec-metafunctions">Class
<code>manage_new_object</code> metafunctions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</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=
"ResultConverterGenerator.html">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.
<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><b>Returns:</b> <code>typedef <a href=
"to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>&lt;T&gt;
type;</code>
</dl>
<h2><a name="examples"></a>Example</h2>
<p>In C++:
<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_INIT(my_module)
{
module m("my_module")
.def("make_foo", make_foo)
.add(
class_&lt;Foo&gt;()
.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 -->
14 February 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,262 +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">Boost.Python</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_INIT-spec">BOOST_PYTHON_MODULE_INIT</a>
</dl>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#module-spec">Class <code>module</code></a>
<dd>
<dl class="page-index">
<dt><a href="#module-spec-synopsis">Class <code>module</code>
synopsis</a>
<dt><a href="#module-spec-ctors">Class <code>module</code>
constructor</a>
<dt><a href="#module-spec-modifiers">Class <code>module</code>
modifier functions</a>
<dt><a href="#module-spec-observers">Class <code>module</code>
observer functions</a>
</dl>
</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=
"BOOST_PYTHON_MODULE_INIT-spec"><code>BOOST_PYTHON_MODULE_INIT(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>
void init<i>name</i>()
{
...
</pre>
Boost.Python modules should be initialized with
<pre>
BOOST_PYTHON_MODULE_INIT(<i>name</i>)
{
...
</pre>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="module-spec">Class <code>module</code></a></h3>
<p>This class represents the Python extension module under construction. It
provides functions for adding attributes and for retrieving the underlying
Python module object.
<h4><a name="module-spec-synopsis"></a>Class <code>module</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
class module : public module_base
{
public:
module(const char* name);
// modifier functions
module&amp; setattr(const char* name, PyObject*);
module&amp; setattr(const char* name, PyTypeObject*);
module&amp; setattr(const char* name, ref const&amp;);
module&amp; add(PyTypeObject* x);
template &lt;class T, class Bases, class HolderGenerator&gt;
module&amp; add(class_&lt;T,Bases,HolderGenerator&gt; const&amp; c);
template &lt;class Fn&gt;
module&amp; def(char const* name, Fn fn);
template &lt;class Fn, class ResultHandler&gt;
module&amp; def(char const* name, Fn fn, ResultHandler handler);
// observer function
ref object() const;
};
}}
</pre>
<h4><a name="module-spec-ctors">Class <code>module</code></a>
constructor</h4>
<pre>
module(const char* name);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is a ntbs whose value matches the
argument passed to <a href=
"#BOOST_PYTHON_MODULE_INIT-spec">BOOST_PYTHON_MODULE_INIT</a>.
<dt><b>Effects:</b> Creates a <code>module</code> object representing a
Python module named <code>name</code>.
</dl>
<h4><a name="module-spec-modifiers">Class <code>module</code></a> modifier
functions</h4>
<pre>
module&amp; setattr(const char* name, PyObject* obj);
module&amp; setattr(const char* name, PyTypeObject* obj);
module&amp; setattr(const char* name, ref const&amp; r);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>. In the first two forms, <code>obj</code> is non-null.
In the third form, <code>r.get()</code> is non-null.
<dt><b>Effects:</b> Adds the given Python object to the module. If the
object is a product of <code><a href=
"make_function.html#make_function-spec">make_function</a>()</code>, the
usual <a href="overloading.html">overloading procedure</a> applies.
In the first two forms, ownership of a reference to obj is transferred
from caller to callee, even if an exception is thrown.
<dt><b>Returns:</b> <code>*this</code>
</dl>
<pre>
module&amp; add(PyTypeObject* x);
template &lt;class T, class Bases, class HolderGenerator&gt;
module&amp; add(class_&lt;T,Bases,HolderGenerator&gt; const&amp; c);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> In the first form, <code>x</code> is non-null
<dt><b>Effects:</b> The first form adds the Python type object named by
<code>x</code> to the Python module under construction, with the name
given by the type's <code><a href=
"http://www.python.org/doc/2.2/ext/dnt-type-methods.html">tp_name</a></code>
field. The second form adds the extension class object being constructed
by <code>c</code> to the module, with the same name that was passed to
<code>c</code>'s constructor.
<dt><b>Returns:</b> <code>*this</code>
<dt><b>Rationale:</b> Provides a way to set type attributes in the module
without having to explicitly specify the name.
</dl>
<pre>
template &lt;class Fn&gt;
module&amp; def(char const* name, Fn f);
template &lt;class Fn, class ResultHandler&gt;
module&amp; def(char const* name, Fn f, ResultHandler handler);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>f</code> is a non-null pointer-to-function or
pointer-to-member-function. <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>. In the first form, the return type of
<code>f</code> is not a reference and is not a pointer other
than <code>char const*</code> or <code>PyObject*</code>. In the
second form <code>policy</code> is a model of <a
href="CallPolicy.html">CallPolicy</a>.
<dt><b>Effects:</b> Adds the result of <code><a href=
"make_function.html#make_function-spec">make_function</a>(f)</code> to
the extension module being defined, with the given <code>name</code>. If
the module already has an attribute named <code><i>name</i></code>, the
usual <a href="http:overloading.html">overloading procedure</a> applies.
<dt><b>Returns:</b> <code>*this</code>
</dl>
<h4><a name="module-spec-observers">Class <code>module</code></a> observer
functions</h4>
<pre>
ref object() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> A <code>ref</code> object which holds a reference to
the Python module object created by the <code>module</code> constructor.
</dl>
<h2><a name="examples"></a>Example(s)</h2>
<p>C++ module definition:
<pre>
#include &lt;boost/python/module.hpp&gt;
char const* greet()
{
return "hello, Boost.Python!";
}
BOOST_PYTHON_MODULE_INIT(boost_greet)
{
module("boost_greet")
.def("greet", greet);
}
</pre>
Interactive Python:
<pre>
&gt;&gt;&gt; import boost_greet
&gt;&gt;&gt; boost_greet.greet()
'hello, Boost.Python!'
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
14 February, 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,47 +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 - Overview</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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Overview</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#topic1">First topic</a></dt>
<dt><a href="#topic2">Second topic</a></dt>
<dt><a href="#footnotes">Footnotes</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>{{text}}</p>
<h2><a name="topic1"></a>First Topic</h2>
<p>{{text}}</p>
<h2><a name="topic2"></a>Second Topic</h2>
<p>{{text}}</p>
<h2><a name="footnotes"></a>Footnotes</h2>
<dl>
<dt><a name="footnote1" class="footnote">(1)</a> {{text}}</dt>
<dt><a name="footnote2" class="footnote">(2)</a> {{text}}</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,47 +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 - Rationale</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="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Rationale</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#topic1">First topic</a></dt>
<dt><a href="#topic2">Second topic</a></dt>
<dt><a href="#footnotes">Footnotes</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>{{text}}</p>
<h2><a name="topic1"></a>First Topic</h2>
<p>{{text}}</p>
<h2><a name="topic2"></a>Second Topic</h2>
<p>{{text}}</p>
<h2><a name="footnotes"></a>Footnotes</h2>
<dl>
<dt><a name="footnote1" class="footnote">(1)</a> {{text}}</dt>
<dt><a name="footnote2" class="footnote">(2)</a> {{text}}</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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,383 +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 - Reference</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"reference">
<tr>
<td valign="top" width="300">
<h3><a href="http://www.boost.org"><img height="86" width="277" alt=
"C++ Boost" src="../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Reference</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="Reference">
<dt><a href="#high_level">High Level Components</a>
<dt><a href="#framework">Framework Elements</a>
<dt><a href="#utilities">Utilities</a>
<dt><a href="#by_name">Index By Name</a>
</dl>
<a name="high_level"></a>
<h2>High Level Components</h2>
<dl class="index">
<dd>
<a name="general_purpose"></a>
<h3>General Purpose</h3>
<dl class="index">
<dt><a href="class.html">class.hpp/class_fwd.hpp</a>
<dd>
<dl class="index">
<dt><a href="class.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href="class.html#class_-spec">class_</a>
<dt><a href="class.html#bases-spec">bases</a>
<dt><a href="class.html#args-spec">args</a>
</dl>
</dl>
<dt><a href="errors.html">errors.hpp</a>
<dd>
<dl class="index">
<dt><a href="errors.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"errors.html#error_already_set-spec">error_already_set</a>
</dl>
<dt><a href="errors.html#functions">Functions</a>
<dd>
<dl class="index">
<dt><a href=
"errors.html#handle_exception-spec">handle_exception</a>
<dt><a href=
"errors.html#expect_non_null-spec">expect_non_null</a>
</dl>
</dl>
<dt><a href="make_function.html">make_function.hpp</a>
<dd>
<dl class="index">
<dt><a href="make_function.html#classes">Functions</a>
<dd>
<dl class="index">
<dt><a href=
"make_function.html#make_function-spec">make_function</a>
<dt><a href=
"make_.html#make_constructor-spec">make_constructor</a>
</dl>
</dl>
<dt><a href="module.html">module.hpp</a>
<dd>
<dl class="index">
<dt><a href="module.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href="module.html#module-spec">module</a>
</dl>
</dl>
<dt><a href="objects.html">objects.hpp</a>
<dd>
<dl class="index">
<dt><a href="objects.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href="objects.html#xxx-spec">not yet documented</a>
</dl>
</dl>
<dt><a href="reference_hpp.html">reference.hpp</a>
<dd>
<dl class="index">
<dt><a href="reference_hpp.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href="reference_hpp.html#reference-spec">reference</a>
</dl>
<dt><a href="reference_hpp.html#types">Types</a>
<dd>
<dl class="index">
<dt><a href="reference_hpp.html#ref-spec">ref</a>
</dl>
</dl>
</dl>
<a name="type_conversion"></a>
<h3>To/From Python Type Conversion</h3>
<dl class="index">
<dt><a href="from_python.html">from_python.hpp</a>
<dd>
<dl class="index">
<dt><a href="from_python.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"from_python.html#from_python-spec">from_python</a>
</dl>
</dl>
<dt><a href="to_python_converter.html">to_python_converter.hpp</a>
<dd>
<dl class="index">
<dt><a href="to_python_converter.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"to_python_converter.html#to_python_converter-spec">to_python_converter</a>
</dl>
</dl>
<dt><a href="to_python_indirect.html">to_python_indirect.hpp</a>
<dd>
<dl class="index">
<dt><a href="to_python_indirect.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>
</dl>
</dl>
<dt><a href="to_python_value.html">to_python_value.hpp</a>
<dd>
<dl class="index">
<dt><a href="to_python_value.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"to_python_value.html#to_python_value-spec">to_python_value</a>
</dl>
</dl>
<dt><a href="type_from_python.html">type_from_python.hpp</a>
<dd>
<dl class="index">
<dt><a href="type_from_python.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"type_from_python.html#type_from_python-spec">type_from_python</a>
</dl>
</dl>
<dt><a href="value_from_python.html">value_from_python.hpp</a>
<dd>
<dl class="index">
<dt><a href="value_from_python.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"value_from_python.html#value_from_python-spec">value_from_python</a>
</dl>
</dl>
</dl>
<a name="models_of_call_policies"></a>
<h3>Models of CallPolicies</h3>
<dl class="index">
<dt><a href=
"default_call_policies.html">default_call_policies.hpp</a>
<dd>
<dl class="index">
<dt><a href="default_call_policies.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"default_call_policies.html#default_call_policies-spec">default_call_policies</a>
<dt><a href=
"default_call_policies.html#default_result_converter-spec">default_result_converter</a>
</dl>
</dl>
<dt><a href=
"return_internal_reference.html">return_internal_reference.hpp</a>
<dd>
<dl class="index">
<dt><a href="return_internal_reference.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"return_internal_reference.html#return_internal_reference-spec">
return_internal_reference</a>
</dl>
</dl>
<dt><a href="return_value_policy.html">return_value_policy.hpp</a>
<dd>
<dl class="index">
<dt><a href="return_value_policy.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"return_value_policy.html#return_value_policy-spec">return_value_policy</a>
</dl>
</dl>
<dt><a href=
"with_custodian_and_ward.html">with_custodian_and_ward.hpp</a>
<dd>
<dl class="index">
<dt><a href="with_custodian_and_ward.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"with_custodian_and_ward.html#with_custodian_and_ward-spec">with_custodian_and_ward</a>
<dt><a href=
"with_custodian_and_ward.html#with_custodian_and_ward_postcall-spec">
with_custodian_and_ward_postcall</a>
</dl>
</dl>
</dl>
<a name="return_handler_generators"></a>
<h3>Models of ReturnHandlerGenerator</h3>
<dl class="index">
<dt><a href="copy_const_reference.html">copy_const_reference.hpp</a>
<dd>
<dl class="index">
<dt><a href="copy_const_reference.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"copy_const_reference.html#copy_const_reference-spec">copy_const_reference</a>
</dl>
</dl>
<dt><a href=
"copy_non_const_reference.html">copy_non_const_reference.hpp</a>
<dd>
<dl class="index">
<dt><a href="copy_non_const_reference.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"copy_non_const_reference.html#copy_non_const_reference-spec">
copy_non_const_reference</a>
</dl>
</dl>
<dt><a href="manage_new_object.html">manage_new_object.hpp</a>
<dd>
<dl class="index">
<dt><a href="manage_new_object.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"manage_new_object.html#manage_new_object-spec">manage_new_object</a>
</dl>
</dl>
<dt><a href=
"reference_existing_object.html">reference_existing_object.hpp</a>
<dd>
<dl class="index">
<dt><a href="reference_existing_object.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"reference_existing_object.html#reference_existing_object-spec">
reference_existing_object</a>
</dl>
</dl>
<dt><a href=
"lvalue_from_python.html">reference_from_python.hpp</a>
<dd>
<dl class="index">
<dt><a href="lvalue_from_python.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"lvalue_from_python.html#reference_from_python-spec">reference_from_python</a>
<dt><a href=
"lvalue_from_python.html#get_member-spec">get_member</a>
</dl>
</dl>
</dl>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 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">
<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/reference_existing_object.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">Boost.Python</h1>
<h2 align="center">Header
&lt;boost/python/reference_existing_object.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="#reference_existing_object-spec">Class
<code>reference_existing_object</code></a>
<dd>
<dl class="page-index">
<dt><a href="#reference_existing_object-spec-synopsis">Class
<code>reference_existing_object</code> synopsis</a>
<dt><a href="#reference_existing_object-spec-metafunctions">Class
<code>reference_existing_object</code> metafunctions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="reference_existing_object-spec"></a>Class
<code>reference_existing_object</code></h3>
<p><code>reference_existing_object</code> is a model of <a href=
"ResultConverterGenerator.html">ResultConverterGenerator</a> which can be
used to wrap C++ functions which return a reference or pointer to a C++
object. When the wrapped function is called, the value referenced by its
return value is not copied. A new Python object is created which contains a
pointer to the referent, and no attempt is made to ensure that the lifetime
of the referent is at least as long as that of the corresponding Python
object. Thus, it can be <font color="#ff0000"><b>highly
dangerous</b></font> to use <code>reference_existing_object</code> without
additional lifetime management from such models of <a href=
"CallPolicies.html">CallPolicies</a> as <a href=
"with_custodian_and_ward.html#with_custodian_and_ward-spec">with_custodian_and_ward</a>.
This class is used in the implementation of <a href=
"return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a>.
<h4><a name="reference_existing_object-spec-synopsis"></a>Class
<code>reference_existing_object</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
struct reference_existing_object
{
template &lt;class T&gt; struct apply;
};
}}
</pre>
<h4><a name="reference_existing_object-spec-metafunctions"></a>Class
<code>reference_existing_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&amp;</code> or
<code>U*</code>for some <code>U</code>.
<dt><b>Returns:</b> <code>typedef <a href=
"to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>&lt;T,V&gt;
type</code>, where <code>V</code> is a <a href=
"to_python_indirect.html#HolderObjectGenerator">HolderObjectGenerator</a>
which constructs an instance holder containing an <i>unowned</i>
<code>U*</code> pointing to the referent of the wrapped function's return
value.
</dl>
<h2><a name="examples"></a>Example</h2>
<p>In C++:
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/reference_existing_object.hpp&gt;
#include &lt;boost/python/return_value_policy.hpp&gt;
#include &lt;utility&gt;
// classes to wrap
struct Singleton
{
Singleton() : x(0) {}
int exchange(int n) // set x and return the old value
{
std::swap(n, x);
return n;
}
int x;
};
Singleton&amp; get_it()
{
static Singleton just_one;
return just_one;
}
// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE_INIT(singleton)
{
module m("singleton")
.def("get_it", get_it)
.add(
class_&lt;Singleton&gt;()
.def("exchange", &amp;Singleton::exchange)
);
}
</pre>
In Python:
<pre>
&gt;&gt;&gt; import singleton
&gt;&gt;&gt; s1 = singleton.get_it()
&gt;&gt;&gt; s2 = singleton.get_it()
&gt;&gt;&gt; id(s1) == id(s2) # s1 and s2 are not the same object
0
&gt;&gt;&gt; s1.exchange(42) # but they reference the same C++ Singleton
0
&gt;&gt;&gt; s2.exchange(99)
42
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
14 February 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,210 +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/return_internal_reference.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">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/return_internal_reference.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="#return_internal_reference-spec">Class Template <code>return_internal_reference</code></a>
<dd>
<dl class="page-index">
<dt><a href="#return_internal_reference-spec-synopsis">Class Template
<code>return_internal_reference</code> synopsis</a>
<dt><a href="#return_internal_reference-spec-statics">Class
<code>return_internal_reference</code> static functions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>return_internal_reference</code> instantiations are models of <a href=
"CallPolicies.html">CallPolicies</a> which allow pointers and
references to objects held internally by a free or member function
argument or from the target of a member function to be returned
safely without making a copy of the referent. The default for its
first template argument handles the common case where the
containing object is the target (<code>*this</code>) of a wrapped
member function.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="return_internal_reference-spec"></a>Class template <code>return_internal_reference</code></h3>
<table border="1" summary="return_internal_reference template parameters">
<caption>
<b><code>return_internal_reference</code> template parameters</b>
</caption>
<tr>
<th>Parameter
<th>Requirements
<th>Description
<th>Default
<tr>
<td><code>owner_arg</code>
<td>A positive compile-time constant of type
<code>std::size_t</code>.
<td>The index of the parameter which contains the object to
which the reference or pointer is being returned. If used to
wrap a member function, parameter 1 is the target object
(<code>*this</code>). Note that if the target Python object
type doesn't support weak references, a Python
<code>TypeError</code> exception will be raised when the
function being wrapped is called.
<td>1
<tr>
<td><code>Base</code>
<td>A model of <a href="CallPolicies.html">CallPolicies</a>
<td>Used for policy composition. Any
<code>result_converter</code> it supplies will be overridden by
<code>return_internal_reference</code>, but its
<code>precall</code> and <code>postcall</code> policies are
composed as described here <a
href="CallPolicies.html#composition">CallPolicies</a>.
<td><code><a href="default_call_policies.html#default_call_policies-spec">default_call_policies</a></code>
</table>
<h4><a name="return_internal_reference-spec-synopsis"></a>Class template <code>return_internal_reference</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;std::size_t owner_arg = 1, class Base = default_call_policies&gt;
struct return_internal_reference : Base
{
static PyObject* postcall(PyObject*, PyObject* result);
typedef <a href="reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a> result_converter;
};
}}
</pre>
<h4><a name="default_call_policies-spec-statics"></a>Class
<code>default_call_policies</code> static functions</h4>
<pre>
PyObject* postcall(PyObject* args, PyObject* result);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code><a href="http://www.python.org/doc/2.2/api/tupleObjects.html#l2h-476">PyTuple_Check</a>(args) != 0</code>
<dt><b>Returns:</b> <code><a href="with_custodian_and_ward.html#with_custodian_and_ward_postcall-spec-statics">with_custodian_and_ward_postcall::postcall(args, result)</a></code>
</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/return_internal_reference.hpp&gt;
class Bar
{
Bar(int x) : x(x) {}
int get_x() const { return x; }
void set_x(int x) { this-&gt;x = x; }
private:
int x;
}
class Foo
{
public:
Foo(int x) : b(x) {}
// Returns an internal reference
Bar const&amp; get_bar() const { return b; }
private:
Bar b;
};
using namespace boost::python;
BOOST_PYTHON_MODULE_INIT(internal_refs)
{
module m(&quot;internal_refs&quot;)
.add(
class_&lt;Bar&gt;()
.def(&quot;get_x&quot;, &amp;Bar::get_x)
.def(&quot;set_x&quot;, &amp;Bar::set_x)
)
.add(
class_&lt;Foo&gt;()
.def_init(args&lt;int&gt;())
.def(&quot;get_bar&quot;, &amp;Foo::get_bar
, return_internal_reference&lt;&gt;())
)
;
}
</pre>
<h3>Python code</h3>
<pre>
&gt;&gt;&gt; from internal_refs import *
&gt;&gt;&gt; f = Foo(3)
&gt;&gt;&gt; b1 = f.get_bar()
&gt;&gt;&gt; b2 = f.get_bar()
&gt;&gt;&gt; b1.get_x()
3
&gt;&gt;&gt; b2.get_x()
3
&gt;&gt;&gt; b1.set_x(42)
&gt;&gt;&gt; b2.get_x()
42
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
15 February, 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,148 +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/return_value_policy.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">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/return_value_policy.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="#return_value_policy-spec">Class Template <code>return_value_policy</code></a>
<dd>
<dl class="page-index">
<dt><a href="#return_value_policy-spec-synopsis">Class Template
<code>return_value_policy</code> synopsis</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>return_value_policy</code> instantiations are simply models
of <a href=
"CallPolicies.html">CallPolicies</a> which are composed of a <a href=
"ResultConverterGenerator.html">ResultConverterGenerator</a> and optional <code>Base</code> <a href=
"CallPolicies.html">CallPolicies</a>.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="return_value_policy-spec"></a>Class template <code>return_value_policy</code></h3>
<table border="1" summary="return_value_policy template parameters">
<caption>
<b><code>return_value_policy</code> template parameters</b>
</caption>
<tr>
<th>Parameter
<th>Requirements
<th>Default
<tr>
<td><code>ResultConverterGenerator</code>
<td>A model of <a href=
"ResultConverterGenerator.html">ResultConverterGenerator</a>.
<tr>
<td><code>Base</code>
<td>A model of <a href="CallPolicies.html">CallPolicies</a>
<td><code><a href="default_call_policies.html#default_call_policies-spec">default_call_policies</a></code>
</table>
<h4><a name="return_value_policy-spec-synopsis"></a>Class template <code>return_value_policy</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class ResultConverterGenerator, class Base = default_call_policies&gt;
struct return_value_policy : Base
{
typedef ResultConverterGenerator result_converter;
};
}}
</pre>
<h2><a name="examples"></a>Example</h2>
<h3>C++ Module Definition</h3>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/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_INIT(my_module)
{
module m("my_module")
.add(
class_&lt;Bar&gt;()
)
.add(
class_&lt;Foo&gt;()
.def_init(args&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 -->
15 February, 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,189 +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/to_python_converter.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">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/to_python_converter.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="#to_python_converter-spec">Class Template <code>to_python_converter</code></a>
<dd>
<dl class="page-index">
<dt><a href="#to_python_converter-spec-synopsis">Class Template
<code>to_python_converter</code> synopsis</a>
<dt><a href="#to_python_converter-spec-ctors">Class Template
<code>to_python_converter</code> constructor</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>to_python_converter</code> registers a conversion from
objects of a given C++ type into a Python object.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="to_python_converter-spec"></a>Class template <code>to_python_converter</code></h3>
<code>to_python_converter</code> adds a wrapper around a static
member function of its second template parameter, handling
low-level details such as insertion into the converter registry.
<table border="1" summary="to_python_converter template parameters">
<caption>
<b><code>to_python_converter</code> template parameters</b><br>
In the table below, <b><code>x</code></b> denotes an object of type <code>T</code>
</caption>
<tr>
<th>Parameter
<th>Requirements
<th>Description
<tr>
<td><code>T</code>
<td>
<td>The C++ type of the source object in the conversion
<tr>
<td><code>Conversion</code>
<td><code>PyObject*&nbsp;p&nbsp;=&nbsp;Conversion::convert(x)</code>,<br>
if <code>p&nbsp;==&nbsp;0</code>, <code><a href="http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>.
<td>A class type whose static member function
<code>convert</code> does the real work of the conversion.
<tr>
</table>
<h4><a name="to_python_converter-spec-synopsis"></a>Class template <code>to_python_converter</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T, class Conversion&gt;
struct to_python_converter
{
to_python_converter();
};
}}
</pre>
<h4><a name="to_python_converter-spec-ctors"></a>Class template <code>to_python_converter</code> constructor</h4>
<pre>
to_python_converter();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Registers a to_python converter which uses
<code>Conversion::convert()</code> to do its work.
</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 placed the corresponding
declarations in <code>&quot;noddy.h&quot;</code>. Because
<code>noddy_NoddyObject</code> is the ultimate trivial extension type,
the example is a bit contrived: it wraps a function for which all
information is contained in the <i>type</i> of its return value.
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/reference.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &quot;noddy.h&quot;
struct tag {};
tag make_tag() { return tag(); }
using namespace boost::python;
struct tag_to_noddy
{
static PyObject* convert(tag const&amp; x)
{
return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
}
};
BOOST_PYTHON_MODULE_INIT(to_python_converter)
{
module to_python(&quot;to_python_converter&quot;)
.def(&quot;make_tag&quot;, make_tag)
;
to_python_converter&lt;tag, tag_to_noddy&gt;();
}
</pre>
<h3>Python code</h3>
<pre>
&gt;&gt;&gt; import to_python_converter
&gt;&gt;&gt; def always_none():
... return None
...
&gt;&gt;&gt; def choose_function(x):
... if (x % 2 != 0):
... return to_python_converter.make_tag
... else:
... return always_none
...
&gt;&gt;&gt; a = [ choose_function(x) for x in range(5) ]
&gt;&gt;&gt; b = [ f() for f in a ]
&gt;&gt;&gt; type(b[0])
&lt;type 'NoneType'&gt;
&gt;&gt;&gt; type(b[1])
&lt;type 'Noddy'&gt;
&gt;&gt;&gt; type(b[2])
&lt;type 'NoneType'&gt;
&gt;&gt;&gt; type(b[3])
&lt;type 'Noddy'&gt;
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--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,194 +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/to_python_indirect.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">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/to_python_indirect.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="#to_python_indirect-spec">Class Template <code>to_python_indirect</code></a>
<dd>
<dl class="page-index">
<dt><a href="#to_python_indirect-spec-synopsis">Class Template
<code>to_python_indirect</code> synopsis</a>
<dt><a href="#to_python_indirect-spec-observers">Class Template
<code>to_python_indirect</code> observer functions</a>
<dt><a href="#to_python_indirect-spec-statics">Class Template
<code>to_python_indirect</code> static functions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>&lt;boost/python/to_python_indirect.hpp&gt;</code> supplies
a way to construct new Python objects that hold wrapped C++ class
instances via a pointer or smart pointer.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="to_python_indirect-spec"></a>Class template <code>to_python_indirect</code></h3>
<p>Class template <code>to_python_indirect</code> converts objects
of its first argument type to python as extension class instances, using the ownership policy provided by its 2nd argument.
<p>
<table border="1" summary="to_python_indirect template parameters">
<caption>
<b><code>to_python_indirect</code> Requirements</b><br>
In the table below, <b><code>x</code></b> denotes an object of
type <code>T</code>, <b><code>h</code></b> denotes an
object of type
<code>boost::python::objects::instance_holder*</code>, and
<b><code>p</code></b> denotes an object of type
<code>U*</code>.
</caption>
<tr>
<th>Parameter
<th>Requirements
<th>Description
<tr>
<td><code>T</code>
<td>Either <code>U</code>&nbsp;<i>cv</i><code>&amp;</code>
(where <i>cv</i> is any optional cv-qualification) or a <a
href="Dereferenceable.html">Dereferenceable</a> type such that
<code>*x</code> is convertible to <code>U const&amp;</code>, where
<code>U</code> is a class type.
<td>A type deferencing a C++ class exposed to Python using
class template <code><a
href="class.html#class_-spec">class_</a></code>.
<tr>
<td><code>MakeHolder</code>
<td>h = MakeHolder::execute(p);
<td>A class whose static <code>execute()</code> creates an
<code>instance_holder</code>.
</table>
Instantiations of <code>to_python_indirect</code> are models of <a
href="ResultConverter.html">ResultConverter</a>.
<h4><a name="to_python_indirect-spec-synopsis"></a>Class template <code>to_python_indirect</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T, class MakeHolder&gt;
struct to_python_indirect
{
static bool convertible();
PyObject* operator()(T ptr_or_reference) const;
private:
static PyTypeObject* type();
};
}}
</pre>
<h4><a name="to_python_indirect-spec-observers"></a>Class template <code>to_python_indirect</code> observers</h4>
<pre>
PyObject* operator()(T x) const;
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>x</code> refers to an object (if it
is a pointer type, it is non-null). <code>convertible() ==
true</code>.
<dt><b>Effects:</b> Creates an appropriately-typed Boost.Python
extension class instance, uses <code>MakeHolder</code> to create
an <code>instance_holder</code> from <code>x</code>, installs
the <code>instance_holder</code> in the new extension class
instance, and returns a pointer to it.
</dl>
<h4><a name="to_python_indirect-spec-statics"></a>Class template <code>to_python_indirect</code> statics</h4>
<pre>
bool convertible();
</pre>
<dt><b>Effects:</b> Returns <code>true</code> iff any module has
registered a Python type corresponding to <code>U</code>.
<h2><a name="examples"></a>Example</h2>
This example replicates the functionality of <a
href="reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a>,
but without some of the compile-time error checking.
<pre>
struct make_reference_holder
{
typedef boost::python::objects::instance_holder* result_type;
template &lt;class T&gt;
static result_type execute(T* p)
{
return new boost::python::objects::pointer_holder&lt;T*, T&gt;(p);
}
};
struct reference_existing_object
{
// metafunction returning the <a href="ResultConverter.html">ResultConverter</a>
template &lt;class T&gt;
struct apply
{
typedef boost::python::to_python_indirect&lt;T,make_reference_holder&gt; type;
};
};
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
16 February, 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

@@ -16,15 +16,10 @@ namespace python = boost::python;
// extension module. This is where we build the module contents.
BOOST_PYTHON_MODULE_INIT(getting_started1)
{
try {
// Create an object representing this extension module.
python::module_builder this_module("getting_started1");
// Add regular functions to the module.
this_module.def(greet, "greet");
this_module.def(square, "square");
}
catch(...) {
boost::python::handle_exception();
}
}

View File

@@ -0,0 +1,210 @@
// 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.
//
// This work was funded in part by Lawrence Berkeley National Labs
//
// This file generated for 5-argument member functions and 6-argument free
// functions by gen_call.py
#ifndef CALL_DWA20011214_HPP
# define CALL_DWA20011214_HPP
# include <boost/python/detail/returning.hpp>
namespace boost { namespace python {
template <class R>
inline PyObject* call(R (*f)(), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
// Member functions
template <class R, class A0>
inline PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
}} // namespace boost::python
#endif // CALL_DWA20011214_HPP

View File

@@ -122,7 +122,7 @@ class class_ : private objects::class_base
// Define the constructor with the given Args, which should be an
// MPL sequence of types.
template <class Args>
self& def_init(Args const&)
self& def_init(Args const& = Args())
{
def("__init__", make_constructor<T,Args,HolderGenerator>());
return *this;

View File

@@ -233,7 +233,7 @@ class BOOST_PYTHON_DECL_TEMPLATE meta_class
boost::python::detail::getattrable<
boost::python::detail::setattrable<
boost::python::detail::type_object<class_t<T> > > > > >,
private boost::noncopyable
boost::noncopyable
{
public:
meta_class();

View File

@@ -0,0 +1,62 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BODY_DWA2001127_HPP
# define BODY_DWA2001127_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/converter/type_id.hpp>
namespace boost { namespace python { namespace converter {
namespace registry
{
class entry;
}
struct BOOST_PYTHON_DECL body
{
public:
body(type_id_t key);
virtual ~body() {}
type_id_t key() const;
protected:
// true iff the registry is still alive
bool can_unregister() const;
private:
// called when the registry is destroyed, to prevent it from being
// unregistered.
void do_not_unregister();
friend class registry::entry;
private:
type_id_t m_key;
bool m_can_unregister;
};
//
// implementations
//
inline body::body(type_id_t key)
: m_key(key)
, m_can_unregister(true)
{
}
inline type_id_t body::key() const
{
return m_key;
}
inline bool body::can_unregister() const
{
return m_can_unregister;
}
}}} // namespace boost::python::converter
#endif // BODY_DWA2001127_HPP

View File

@@ -6,9 +6,7 @@
#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP
# define BUILTIN_CONVERTERS_DWA2002124_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/none.hpp>
# include <string>
# include <complex>
namespace boost { namespace python {
@@ -46,22 +44,18 @@ namespace detail
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x))
BOOST_PYTHON_TO_INT(char)
BOOST_PYTHON_TO_INT(short)
BOOST_PYTHON_TO_INT(int)
BOOST_PYTHON_TO_INT(long)
# undef BOOST_TO_PYTHON_INT
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : detail::none())
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x ? x : detail::none())
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x)
namespace converter
{

View File

@@ -0,0 +1,75 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_DWA20011215_HPP
# define CLASS_DWA20011215_HPP
# include <boost/python/object/class.hpp>
# include <boost/python/converter/from_python.hpp>
namespace boost { namespace python { namespace converter {
template <class T>
struct class_from_python_converter
{
class_from_python_converter();
static void* convertible(PyObject*);
static T& convert_ref(PyObject*, from_python_data&);
static T const& convert_cref(PyObject*, from_python_data&);
static T* convert_ptr(PyObject*, from_python_data&);
static T const* convert_cptr(PyObject*, from_python_data&);
from_python_converter<T&> to_ref;
from_python_converter<T const&> to_cref;
from_python_converter<T*> to_ptr;
from_python_converter<T const*> to_cptr;
};
//
// implementations
//
template <class T>
class_from_python_converter<T>::class_from_python_converter()
: to_ref(convertible, convert_ref)
, to_cref(convertible, convert_cref)
, to_ptr(convertible, convert_ptr)
, to_cptr(convertible, convert_cptr)
{}
template <class T>
T& class_from_python_converter<T>::convert_ref(PyObject*, from_python_data& x)
{
return *static_cast<T*>(x.stage1);
}
template <class T>
T const& class_from_python_converter<T>::convert_cref(PyObject*, from_python_data& x)
{
return *static_cast<T*>(x.stage1);
}
template <class T>
T* class_from_python_converter<T>::convert_ptr(PyObject*, from_python_data& x)
{
return static_cast<T*>(x.stage1);
}
template <class T>
T const* class_from_python_converter<T>::convert_cptr(PyObject*, from_python_data& x)
{
return static_cast<T*>(x.stage1);
}
template <class T>
void* class_from_python_converter<T>::convertible(PyObject* p)
{
return objects::find_instance<T>(p);
}
}}} // namespace boost::python::converter
#endif // CLASS_DWA20011215_HPP

View File

@@ -1,25 +0,0 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FIND_FROM_PYTHON_DWA2002223_HPP
# define FIND_FROM_PYTHON_DWA2002223_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace converter {
struct lvalue_from_python_registration;
struct rvalue_from_python_registration;
struct rvalue_stage1_data;
BOOST_PYTHON_DECL void* find(
PyObject* source, lvalue_from_python_registration const*);
BOOST_PYTHON_DECL void* find(
PyObject* source, rvalue_from_python_registration const*, rvalue_stage1_data&);
}}} // namespace boost::python::converter
#endif // FIND_FROM_PYTHON_DWA2002223_HPP

View File

@@ -6,282 +6,192 @@
#ifndef FROM_PYTHON_DWA2002127_HPP
# define FROM_PYTHON_DWA2002127_HPP
# include <boost/python/converter/find_from_python.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/destroy.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/python/converter/pointer_type_id.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/converter/body.hpp>
# include <boost/python/converter/from_python_function.hpp>
# include <boost/python/converter/from_python_data.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace converter {
namespace boost { namespace python { namespace converter {
struct from_python_base
// The type of convertibility checking functions
typedef void* (*from_python_check)(PyObject*);
typedef void (*from_python_destructor)(from_python_data&);
// forward declaration
template <class T> struct from_python_lookup;
// from_python --
// A body class representing a conversion from python to C++.
struct BOOST_PYTHON_DECL from_python_converter_base : body
{
public: // member functions
from_python_base(void* result);
from_python_base(PyObject*, lvalue_from_python_registration const* chain);
bool convertible() const;
from_python_converter_base(type_id_t, from_python_check); // registers
// Must return non-null iff the conversion will be successful. Any
// non-null pointer is acceptable, and will be passed on to the
// convert() function, so useful data can be stored there.
inline void* convertible(PyObject*) const;
// Given the head of a from_python converter chain, find the
// converter which can convert p, leaving its intermediate data in
// data.
inline static from_python_converter_base const*
find(from_python_converter_base const*chain, PyObject* p, void*& data);
protected: // member functions
void*const& result() const;
private:
from_python_check m_convertible;
from_python_converter_base* m_next;
};
template <class T>
struct from_python_converter : from_python_converter_base
{
public: // types
typedef typename from_python_function<T>::type conversion_function;
public: // member functions
from_python_converter(from_python_check, conversion_function, from_python_destructor = 0);
T convert(PyObject*, from_python_data&) const;
void destroy(from_python_data&) const;
// Find a converter for converting p to a T.
static from_python_converter<T> const* find(PyObject* p, void*& data);
private: // data members
void* m_result;
conversion_function m_convert;
from_python_destructor m_destroy;
// Keeps the chain of converters which convert from PyObject* to T
static from_python_converter_base*const& chain;
};
// Used when T == U*const&
// Initialized to refer to a common place in the registry.
template <class T>
struct pointer_const_reference_from_python
from_python_converter_base*const&
from_python_converter<T>::chain = registry::from_python_chain(type_id<T>());
// -------------------------------------------------------------------------
// A class which implements from_python with a registry lookup.
template <class T>
struct from_python_lookup // : from_python_base
{
pointer_const_reference_from_python(PyObject*);
T operator()(PyObject*) const;
public: // types
public: // member functions
from_python_lookup(PyObject* source);
~from_python_lookup();
bool convertible() const;
private:
typename detail::referent_storage<T>::type m_result;
static lvalue_from_python_registration*& chain;
};
T operator()(PyObject*);
// Used when T == U*
template <class T>
struct pointer_from_python : from_python_base
{
pointer_from_python(PyObject*);
T operator()(PyObject*) const;
public: // functions for use by conversion implementations
// Get the converter object
from_python_converter<T> const* converter() const;
static lvalue_from_python_registration*& chain;
};
// Used when T == U& and (T != V const& or T == W volatile&)
template <class T>
struct reference_from_python : from_python_base
{
reference_from_python(PyObject*);
T operator()(PyObject*) const;
static lvalue_from_python_registration*& chain;
};
// ------- rvalue converters ---------
// Used for the case where T is a non-pointer, non-reference type OR
// is a const non-volatile reference to a non-pointer type.
template <class T>
class rvalue_from_python
{
typedef typename boost::add_reference<
typename boost::add_const<T>::type
>::type result_type;
public:
rvalue_from_python(PyObject*);
~rvalue_from_python();
bool convertible() const;
result_type operator()(PyObject*);
private:
rvalue_data<result_type> m_data;
static rvalue_from_python_registration*& chain;
};
template <class T>
struct select_from_python
{
BOOST_STATIC_CONSTANT(
bool, ptr = is_pointer<T>::value);
BOOST_STATIC_CONSTANT(
bool, ptr_cref
= boost::python::detail::is_reference_to_pointer<T>::value
&& boost::python::detail::is_reference_to_const<T>::value
&& !boost::python::detail::is_reference_to_volatile<T>::value);
BOOST_STATIC_CONSTANT(
bool, ref =
boost::python::detail::is_reference_to_non_const<T>::value
|| boost::python::detail::is_reference_to_volatile<T>::value);
typedef typename mpl::select_type<
ptr
, pointer_from_python<T>
, typename mpl::select_type<
ptr_cref
, pointer_const_reference_from_python<T>
, typename mpl::select_type<
ref
, reference_from_python<T>
, rvalue_from_python<T>
>::type
>::type
>::type type;
private: // data members
typedef typename from_python_intermediate_data<T>::type intermediate_t;
mutable intermediate_t m_intermediate_data;
from_python_converter<T> const* m_converter;
};
//
// implementations
//
inline from_python_base::from_python_base(void* result)
: m_result(result)
inline void* from_python_converter_base::convertible(PyObject* o) const
{
return m_convertible(o);
}
inline from_python_base::from_python_base(
PyObject* source
, lvalue_from_python_registration const* chain)
: m_result(find(source, chain))
inline from_python_converter_base const*
from_python_converter_base::find(
from_python_converter_base const* chain, PyObject* p, void*& data)
{
}
inline bool from_python_base::convertible() const
{
return m_result != 0;
}
inline void*const& from_python_base::result() const
{
return m_result;
}
// --------
namespace detail
{
template <class U>
inline U& void_ptr_to_reference(void const volatile* p, U&(*)())
{
return *(U*)p;
}
template <class T>
struct null_ptr_owner
{
static T value;
};
template <class T> T null_ptr_owner<T>::value = 0;
template <class U>
inline U& null_ptr_reference(U&(*)())
{
return null_ptr_owner<U>::value;
}
template <class T>
inline void write_void_ptr(void const volatile* storage, void* ptr, T*)
{
*(T**)storage = (T*)ptr;
}
// writes U(ptr) into the storage
template <class U>
inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)())
{
// stripping CV qualification suppresses warnings on older EDGs
typedef typename remove_cv<U>::type u_stripped;
write_void_ptr(storage, ptr, u_stripped(0));
}
for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next)
{
void* d = q->convertible(p);
if (d != 0)
{
data = d;
return q;
}
}
return 0;
}
template <class T>
inline pointer_const_reference_from_python<T>::pointer_const_reference_from_python(PyObject* p)
inline from_python_converter<T>::from_python_converter(
from_python_check checker
, conversion_function converter
, from_python_destructor destructor // = 0
)
: from_python_converter_base(type_id<T>(), checker)
, m_convert(converter)
, m_destroy(destructor)
{
detail::write_void_ptr_reference(
m_result.bytes
, p == Py_None ? p : find(p, chain)
, (T(*)())0);
}
template <class T>
inline bool pointer_const_reference_from_python<T>::convertible() const
{
return detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0;
}
template <class T>
inline T pointer_const_reference_from_python<T>::operator()(PyObject* p) const
{
return (p == Py_None)
? detail::null_ptr_reference((T(*)())0)
: detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
}
template <class T>
lvalue_from_python_registration*& pointer_const_reference_from_python<T>::chain
= registry::lvalue_converters(pointer_type_id<T>());
// --------
template <class T>
inline pointer_from_python<T>::pointer_from_python(PyObject* p)
: from_python_base(p == Py_None ? p : find(p, chain))
{
}
template <class T>
inline T pointer_from_python<T>::operator()(PyObject* p) const
{
return (p == Py_None) ? 0 : T(result());
}
template <class T>
lvalue_from_python_registration*& pointer_from_python<T>::chain
= registry::lvalue_converters(pointer_type_id<T>());
// --------
template <class T>
inline reference_from_python<T>::reference_from_python(PyObject* p)
: from_python_base(find(p,chain))
{
}
template <class T>
inline T reference_from_python<T>::operator()(PyObject*) const
{
return detail::void_ptr_to_reference(result(), (T(*)())0);
}
template <class T>
lvalue_from_python_registration*& reference_from_python<T>::chain
= registry::lvalue_converters(undecorated_type_id<T>());
// -------
template <class T>
inline rvalue_from_python<T>::rvalue_from_python(PyObject* obj)
{
find(obj, chain, m_data.stage1);
}
template <class T>
inline rvalue_from_python<T>::~rvalue_from_python()
{
if (m_data.stage1.convertible == m_data.storage.bytes)
python::detail::destroy_reference<result_type>(m_data.storage.bytes);
}
template <class T>
inline bool rvalue_from_python<T>::convertible() const
{
return m_data.stage1.convertible != 0;
}
template <class T>
inline typename rvalue_from_python<T>::result_type
rvalue_from_python<T>::operator()(PyObject* p)
{
if (m_data.stage1.construct != 0)
m_data.stage1.construct(p, &m_data.stage1);
return detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
}
template <class T>
rvalue_from_python_registration*& rvalue_from_python<T>::chain
= registry::rvalue_converters(undecorated_type_id<T>());
inline from_python_converter<T> const*
from_python_converter<T>::find(PyObject* p, void*& data)
{
return static_cast<from_python_converter<T> const*>(
from_python_converter_base::find(chain, p, data));
}
template <class T>
inline T from_python_converter<T>::convert(PyObject* src, from_python_data& data) const
{
return this->m_convert(src, data);
}
template <class T>
inline void from_python_converter<T>::destroy(from_python_data& data) const
{
if (this->m_destroy)
{
this->m_destroy(data);
}
}
template <class T>
inline from_python_lookup<T>::from_python_lookup(PyObject* src)
: m_converter(
from_python_converter<T>::find(
src, m_intermediate_data.stage1))
{
}
template <class T>
inline from_python_lookup<T>::~from_python_lookup()
{
if (m_converter != 0)
m_converter->destroy(m_intermediate_data);
}
template <class T>
inline bool from_python_lookup<T>::convertible() const
{
return this->m_converter != 0;
}
template <class T>
inline T from_python_lookup<T>::operator()(PyObject* obj)
{
return this->m_converter->convert(obj, m_intermediate_data);
}
template <class T>
inline from_python_converter<T> const*
from_python_lookup<T>::converter() const
{
return this->m_converter;
}
}}} // namespace boost::python::converter

View File

@@ -9,22 +9,26 @@
# include <boost/python/detail/char_array.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/type_traits/same_traits.hpp>
# include <boost/type_traits/alignment_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/static_assert.hpp>
# include <boost/python/converter/from_python_stage1_data.hpp>
# include <boost/type.hpp>
// Keep these for the metaprogram which EDG is choking on.
# if !defined(__EDG__) || (__EDG_VERSION__ > 245)
# include <boost/mpl/type_list.hpp>
# include <boost/mpl/for_each.hpp>
# include <boost/type_traits/alignment_traits.hpp>
# include <boost/type_traits/composite_traits.hpp>
# else
# include <boost/type_traits/cv_traits.hpp>
# endif
namespace boost { namespace python { namespace converter {
// A POD which is layout-compatible with the real intermediate data
// for all from_python conversions. There may be additional storage if
// we are converting a reference type.
struct from_python_data
{
void* stage1;
};
namespace detail
{
template <class T> struct referent_alignment;
@@ -70,8 +74,8 @@ namespace detail
template <class T> struct referent_size
{
static T f();
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f()));
static T t;
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t));
};
# endif
@@ -107,31 +111,36 @@ namespace detail
bool, choose_t2 = (
aligned2 && (
is_same<T1,unknown_alignment>::value
| (align2 < align1)
| (align2 < alignment_of<T1>::value)
| (sizeof(T2) < sizeof(T1)))
));
typedef typename mpl::select_type<choose_t2, T2, T1>::type type;
typedef mpl::select_type<choose_t2, T2, T1>::type type;
};
};
typedef mpl::type_list<
char,short,int,long, float,double,long double
char,short,int,long,float,double,long double
,void*
,void(*)()
,void (alignment_dummy::*)()
, char (alignment_dummy::*)
>::type
>
align_types;
#endif // EDG is too slow
#endif // EDG is too slow
template <class Align, std::size_t size>
union aligned_storage
struct aligned_storage
{
Align align;
char bytes[size
// this is just a STATIC_ASSERT. For some reason
// MSVC was barfing on the boost one.
- (is_same<Align,unknown_alignment>::value ? size : 0)];
typedef Align align_t;
union
{
Align align;
char bytes[size
// this is just a STATIC_ASSERT. For some reason
// MSVC was barfing on the boost one.
- (is_same<align_t,unknown_alignment>::value ? size : 0)];
};
};
template <class Reference>
@@ -142,56 +151,56 @@ namespace detail
typedef mpl::for_each<
align_types
, unknown_alignment
, best_alignment_type<
referent_alignment<Reference>::value
>
, best_alignment_type<referent_alignment<Reference>::value>
> loop;
typedef typename loop::state align_t;
#else
typedef typename remove_cv<typename remove_reference<Reference>::type>::type referent;
// The Python source makes the assumption that double has
// maximal alignment, but that fails on some platforms
BOOST_STATIC_CONSTANT(
std::size_t, target_align = alignment_of<referent>::value);
// maximal alignment anyway
typedef double align_t;
#endif
// Here we make some assumptions and leave out some possible
// types worth checking, but this should work most of the time.
typedef typename mpl::select_type<
is_POD<referent>::value
, referent
, typename mpl::select_type<
alignment_of<long>::value >= target_align
, long
, typename mpl::select_type<
alignment_of<double>::value >= target_align
, double
, long double>::type
>::type
>::type align_t;
#endif
BOOST_STATIC_CONSTANT(std::size_t, alignment1 = alignment_of<align_t>::value);
BOOST_STATIC_CONSTANT(std::size_t, alignment2 = referent_alignment<Reference>::value);
BOOST_STATIC_ASSERT(alignment1 >= alignment2);
BOOST_STATIC_ASSERT(alignment1 % alignment2 == 0);
typedef aligned_storage<align_t,referent_size<Reference>::value> type;
};
template <class T>
struct intermediate_data : from_python_data
{
typename referent_storage<T>::type stage2;
};
template <>
struct intermediate_data<void> : from_python_data
{
};
}
// -------------------------------------------------------------------------
// Auxiliary POD storage where the convertible and/or convert functions of a
// from_python object may place arbitrary data.
//
// Always starts with a void*
//
// For references, we produce additional aligned storage sufficient to
// store the referent
template <class T>
struct rvalue_data
struct from_python_intermediate_data
{
rvalue_stage1_data stage1;
typename detail::referent_storage<
typename add_reference<T>::type
>::type storage;
typedef typename mpl::select_type<
is_reference<T>::value, T, void>::type just_reference_t;
typedef detail::intermediate_data<just_reference_t> type;
};
template <class T>
void* get_storage(from_python_data& x, boost::type<T>* = 0)
{
typedef typename from_python_intermediate_data<T>::type layout;
return static_cast<layout*>(&x)->stage2.bytes;
}
}}} // namespace boost::python::converter
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP

View File

@@ -10,8 +10,13 @@
namespace boost { namespace python { namespace converter {
struct rvalue_stage1_data;
typedef void (*constructor_function)(PyObject* source, rvalue_stage1_data*);
struct from_python_data;
template <class T>
struct from_python_function
{
typedef T (*type)(PyObject*, from_python_data&);
};
}}} // namespace boost::python::converter

View File

@@ -1,21 +0,0 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP
# define FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP
# include <boost/python/converter/from_python_function.hpp>
namespace boost { namespace python { namespace converter {
struct rvalue_stage1_data
{
void* convertible;
constructor_function construct;
};
}}} // namespace boost::python::converter
#endif // FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP

View File

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

View File

@@ -1,28 +0,0 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REGISTRATIONS_DWA2002223_HPP
# define REGISTRATIONS_DWA2002223_HPP
# include <boost/python/converter/from_python_function.hpp>
namespace boost { namespace python { namespace converter {
struct lvalue_from_python_registration
{
void* (*convert)(PyObject* source);
lvalue_from_python_registration* next;
};
struct rvalue_from_python_registration
{
void* (*convertible)(PyObject*);
constructor_function construct;
rvalue_from_python_registration* next;
};
}}} // namespace boost::python::converter
#endif // REGISTRATIONS_DWA2002223_HPP

View File

@@ -9,33 +9,20 @@
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/to_python_function.hpp>
# include <boost/python/converter/from_python_function.hpp>
namespace boost { namespace python { namespace converter {
struct lvalue_from_python_registration;
struct rvalue_from_python_registration;
struct BOOST_PYTHON_DECL from_python_converter_base;
// This namespace acts as a sort of singleton
namespace registry
{
BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t);
BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t);
BOOST_PYTHON_DECL to_python_value_function const&
to_python_function(undecorated_type_id_t);
BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t);
// Insert an lvalue from_python converter
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), undecorated_type_id_t);
// Insert an rvalue from_python converter
BOOST_PYTHON_DECL void insert(
void* (*convertible)(PyObject*)
, constructor_function
, undecorated_type_id_t
);
BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t);
BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key);
}

View File

@@ -0,0 +1,191 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TARGET_DWA20011119_HPP
# define TARGET_DWA20011119_HPP
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/type_traits/same_traits.hpp>
namespace boost { namespace python { namespace converter {
// target --
//
// This type generator (see
// ../../../more/generic_programming.html#type_generator) is used
// to select the return type of the appropriate converter for
// unwrapping a given type.
// Strategy:
//
// 1. reduce everything to a common, un-cv-qualified reference
// type where possible. This will save on registering many different
// converter types.
//
// 2. 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.
//
// Target Source
// int int
// int const& int
// int& int&
// int volatile& int volatile&
// int const volatile& int const volatile&
// On compilers supporting partial specialization:
//
// Target Source
// T T const&
// T& T&
// T const& T const&
// T volatile T&
// T const volatile& T const&
// T* T*
// T const* T const*
// T volatile T*
// T const volatile* T const*
// T cv*const& same as T cv*
// T cv*& T*& <- should this be legal?
// T cv*volatile& T*& <- should this be legal?
// T cv*const volatile& T*& <- should this be legal?
// On others:
//
// Target Source
// T T&
// T cv& T cv&
// T cv* T cv*
// T cv*cv& T cv*cv&
// As you can see, in order to handle the same range of types without
// partial specialization, more converters need to be registered.
template <class T>
struct target
{
// Some pointer types are handled in a more sophisticated way on
// compilers supporting partial specialization.
BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_scalar<T>::value));
typedef typename mpl::select_type<
use_identity
, T
, typename add_reference<
typename add_const<
typename remove_volatile<T>::type
>::type
>::type
>::type type;
};
// When partial specialization is not present, we'll simply need to
// register many more converters.
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct target<T&>
{
typedef typename remove_volatile<T>::type& type;
};
template <class T>
struct target<T const&>
{
typedef typename boost::mpl::select_type<
is_scalar<T>::value
, typename remove_cv<T>::type
, typename remove_volatile<T>::type const&
>::type type;
};
template <class T>
struct target<T*>
{
typedef typename remove_volatile<T>::type* type;
};
// Handle T*-cv for completeness. Function arguments in a signature
// are never actually cv-qualified, but who knows how these converters
// might be used, or whether compiler bugs lurk which make it seem
// otherwise?
template <class T>
struct target<T* const>
{
typedef typename remove_volatile<T>::type* type;
};
template <class T>
struct target<T* volatile>
{
typedef typename remove_volatile<T>::type* type;
};
template <class T>
struct target<T* const volatile>
{
typedef typename remove_volatile<T>::type* type;
};
// non-const references to pointers should be handled by the
// specialization for T&, above.
template <class T>
struct target<T* const&>
{
typedef typename remove_volatile<T>::type* type;
};
# endif
// Fortunately, we can handle T const& where T is an arithmetic type
// by explicit specialization. These specializations will cause value
// and const& arguments to be converted to values, rather than to
// references.
# define BOOST_PYTHON_UNWRAP_VALUE(T) \
template <> \
struct target<T> \
{ \
typedef T type; \
}; \
template <> \
struct target<T const> \
{ \
typedef T type; \
}; \
template <> \
struct target<T volatile> \
{ \
typedef T type; \
}; \
template <> \
struct target<T const volatile> \
{ \
typedef T type; \
}; \
template <> \
struct target<T const&> \
{ \
typedef T type; \
}
BOOST_PYTHON_UNWRAP_VALUE(char);
BOOST_PYTHON_UNWRAP_VALUE(unsigned char);
BOOST_PYTHON_UNWRAP_VALUE(signed char);
BOOST_PYTHON_UNWRAP_VALUE(unsigned int);
BOOST_PYTHON_UNWRAP_VALUE(signed int);
BOOST_PYTHON_UNWRAP_VALUE(unsigned short);
BOOST_PYTHON_UNWRAP_VALUE(signed short);
BOOST_PYTHON_UNWRAP_VALUE(unsigned long);
BOOST_PYTHON_UNWRAP_VALUE(signed long);
BOOST_PYTHON_UNWRAP_VALUE(char const*);
}}} // namespace boost::python::converter
#endif // TARGET_DWA20011119_HPP

View File

@@ -0,0 +1,36 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef UNWRAPPER_BASE_DWA20011215_HPP
# define UNWRAPPER_BASE_DWA20011215_HPP
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/body.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_DECL unwrapper_base : body
{
public:
unwrapper_base(type_id_t); // registers
~unwrapper_base(); // unregisters
// Must return non-null iff the conversion will be successful. Any
// non-null pointer is acceptable, and will be passed on to the
// convert() function, so useful data can be stored there.
virtual void* can_convert(PyObject*) const = 0;
protected:
// this is an arbitrary non-null pointer you can use to indicate success
static void* const non_null;
private: // body required interface implementation
void destroy_handle(handle*) const {}
};
}}} // namespace boost::python::converter
#endif // UNWRAPPER_BASE_DWA20011215_HPP

View File

@@ -1,83 +0,0 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DESTROY_DWA2002221_HPP
# define DESTROY_DWA2002221_HPP
# include <boost/type_traits/composite_traits.hpp>
# include <boost/type_traits/object_traits.hpp>
namespace boost { namespace python { namespace detail {
template <bool array, bool trivial_destructor> struct value_destroyer;
template <>
struct value_destroyer<false,false>
{
template <class T>
static void execute(T const volatile* p)
{
p->T::~T();
}
};
template <>
struct value_destroyer<true,false>
{
template <class A, class T>
static void execute(A*, T const volatile* const first)
{
for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p)
value_destroyer<
boost::is_array<T>::value
,boost::has_trivial_destructor<T>::value
>::execute(p);
}
template <class T>
static void execute(T const volatile* p)
{
execute(p, *p);
}
};
template <>
struct value_destroyer<true,true>
{
template <class T>
static void execute(T const volatile* p)
{
}
};
template <>
struct value_destroyer<false,true>
{
template <class T>
static void execute(T const volatile* p)
{
}
};
template <class T>
inline void destroy_reference_impl(void* p, T& (*)())
{
// note: cv-qualification needed for MSVC6
// must come *before* T for metrowerks
value_destroyer<
(boost::is_array<T>::value)
, (boost::has_trivial_destructor<T>::value)
>::execute((const volatile T*)p);
}
template <class T>
inline void destroy_reference(void* p, T(*)() = 0)
{
destroy_reference_impl(p, (T(*)())0);
}
}}} // namespace boost::python::detail
#endif // DESTROY_DWA2002221_HPP

View File

@@ -27,14 +27,13 @@ struct is_reference_to_const<T const&>
template <class T>
struct is_reference_to_non_const
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::type_traits::ice_and<
::boost::is_reference<T>::value
, ::boost::type_traits::ice_not<
::boost::python::detail::is_reference_to_const<T>::value>::value
>::value)
);
BOOST_STATIC_CONSTANT(bool, value = false);
};
template <class T>
struct is_reference_to_non_const<T&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>

View File

@@ -1,44 +0,0 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MODULE_BASE_DWA2002227_HPP
# define MODULE_BASE_DWA2002227_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/reference.hpp>
namespace boost { namespace python { namespace detail {
class BOOST_PYTHON_DECL module_base
{
public:
// Create a module. REQUIRES: only one module is created per module.
module_base(const char* name);
~module_base();
// Add elements to the module
void setattr(const char* name, PyObject*);
void setattr(const char* name, ref const&);
void add(PyTypeObject* x); // just use the type's name
void add_type(ref);
// Return a reference to the Python module object being built
inline ref object() const;
private:
ref m_module;
static PyMethodDef initial_methods[1];
};
//
// inline implementations
//
inline ref module_base::object() const
{
return m_module;
}
}}} // namespace boost::python::detail
#endif // MODULE_BASE_DWA2002227_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -28,13 +28,6 @@ bool handle_exception(T f)
return handle_exception_impl(function0<void>(boost::ref(f)));
}
namespace detail { inline void rethrow() { throw; } }
inline void handle_exception()
{
handle_exception(detail::rethrow);
}
BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x);
template <class T>

View File

@@ -7,14 +7,15 @@
# define FROM_PYTHON_DWA2002128_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/target.hpp>
namespace boost { namespace python {
template <class T>
struct from_python
: converter::select_from_python<T>::type
: converter::from_python_lookup<typename converter::target<T>::type>
{
typedef typename converter::select_from_python<T>::type base;
typedef converter::from_python_lookup<typename converter::target<T>::type> base;
from_python(PyObject*);
};
@@ -27,14 +28,6 @@ struct from_python<PyObject*>
PyObject* operator()(PyObject* source) const { return source; }
};
template <>
struct from_python<PyObject* const&>
{
from_python(PyObject*) {}
bool convertible() const { return true; }
PyObject*const& operator()(PyObject*const& source) const { return source; }
};
//
// implementations
//

View File

@@ -8,14 +8,36 @@
# include <boost/python/errors.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/reference.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/objects.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/class_fwd.hpp>
# include <boost/python/detail/module_base.hpp>
namespace boost { namespace python {
class module : public detail::module_base
class BOOST_PYTHON_DECL module_base
{
public:
// Create a module. REQUIRES: only one module is created per module.
module_base(const char* name);
~module_base();
// Add elements to the module
void setattr(const char* name, PyObject*);
void setattr(const char* name, ref const&);
void add(PyTypeObject* x); // just use the type's name
void add_type(ref);
// Return a reference to the Python module object being built
ref module() const;
private:
ref m_module;
static PyMethodDef initial_methods[1];
};
class module : public module_base
{
public:
module(const char* name)
@@ -54,6 +76,11 @@ class module : public detail::module_base
//
// inline implementations
//
inline ref module_base::module() const
{
return m_module;
}
inline module& module::setattr(const char* name, PyObject* x)
{
this->module_base::setattr(name, x);

View File

@@ -6,6 +6,7 @@
#ifndef CLASS_DWA20011214_HPP
# define CLASS_DWA20011214_HPP
# include <boost/python/module.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/utility.hpp>
@@ -25,7 +26,7 @@ template <class T> struct holder;
// To identify a class, we don't need cv/reference decorations
typedef converter::undecorated_type_id_t class_id;
struct BOOST_PYTHON_DECL class_base : private noncopyable
struct BOOST_PYTHON_DECL class_base : noncopyable
{
// constructor
class_base(
@@ -43,7 +44,7 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable
};
// Base class for all holders
struct BOOST_PYTHON_DECL instance_holder : private noncopyable
struct BOOST_PYTHON_DECL instance_holder : noncopyable
{
public:
instance_holder();
@@ -52,7 +53,7 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable
// return the next holder in a chain
instance_holder* next() const;
virtual void* holds(converter::undecorated_type_id_t) = 0;
virtual void* holds(converter::type_id_t) = 0;
void install(PyObject* inst) throw();
@@ -84,19 +85,15 @@ struct instance
instance_holder* objects;
};
// Given an undecorated type_id, find the instance data which
// corresponds to it, or return 0 in case no such type is held.
BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::undecorated_type_id_t);
// Given a type_id, find the instance data which corresponds to it, or
// return 0 in case no such type is held.
BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t);
// This produces a function with the right signature for use in from_python conversions
template <class T>
struct instance_finder
T* find_instance(PyObject* p, T* = 0)
{
static inline void* execute(PyObject* p)
{
return find_instance_impl(p, converter::undecorated_type_id<T>());
}
};
return static_cast<T*>(find_instance_impl(p, converter::type_id<T>()));
}
BOOST_PYTHON_DECL ref class_metatype();
BOOST_PYTHON_DECL ref class_type();

View File

@@ -6,10 +6,10 @@
#ifndef CLASS_CONVERTERS_DWA2002119_HPP
# define CLASS_CONVERTERS_DWA2002119_HPP
# include <boost/python/converter/class.hpp>
# include <boost/python/object/class_wrapper.hpp>
# include <boost/mpl/for_each.hpp>
# include <boost/python/reference.hpp>
# include <boost/python/converter/registry.hpp>
namespace boost { namespace python { namespace objects {
@@ -24,6 +24,7 @@ struct class_converters
class_converters(ref const& python_class);
private: // data members
converter::class_from_python_converter<Derived> m_unwrapper;
class_wrapper<Derived> m_wrapper;
};
@@ -89,10 +90,6 @@ template <class Derived, class Bases>
class_converters<Derived,Bases>::class_converters(ref const& type_object)
: m_wrapper(type_object)
{
converter::registry::insert(
&instance_finder<Derived>::execute
, converter::undecorated_type_id<Derived>());
// register all up/downcasts here
register_dynamic_id<Derived>();

View File

@@ -139,7 +139,7 @@ struct pointer_holder : instance_holder
{}
private: // required holder implementation
void* holds(converter::undecorated_type_id_t);
void* holds(converter::type_id_t);
private: // data members
Pointer m_p;
@@ -186,12 +186,12 @@ pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
}
template <class Pointer, class Value>
void* pointer_holder<Pointer, Value>::holds(converter::undecorated_type_id_t dst_t)
void* pointer_holder<Pointer, Value>::holds(converter::type_id_t dst_t)
{
if (dst_t == converter::undecorated_type_id<Pointer>())
if (dst_t == converter::type_id<Pointer>())
return &this->m_p;
converter::type_id_t src_t = converter::undecorated_type_id<Value>();
converter::type_id_t src_t = converter::type_id<Value>();
return src_t == dst_t ? &*this->m_p
: find_dynamic_type(&*this->m_p, src_t, dst_t);
}

View File

@@ -134,7 +134,7 @@ struct value_holder : instance_holder
{}
private: // required holder implementation
void* holds(converter::undecorated_type_id_t);
void* holds(converter::type_id_t);
private: // data members
Held m_held;
@@ -151,9 +151,9 @@ struct value_holder_generator
};
template <class Held>
void* value_holder<Held>::holds(converter::undecorated_type_id_t dst_t)
void* value_holder<Held>::holds(converter::type_id_t dst_t)
{
converter::undecorated_type_id_t src_t = converter::undecorated_type_id<Held>();
converter::type_id_t src_t = converter::type_id<Held>();
return src_t == dst_t ? &m_held
: find_static_type(&m_held, src_t, dst_t);
}

View File

@@ -0,0 +1,62 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REFERENCE_FROM_PYTHON_DWA2002130_HPP
# define REFERENCE_FROM_PYTHON_DWA2002130_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/python/type_from_python.hpp>
namespace boost { namespace python {
// Utility which produces a member extractor function on platforms
// other than VC6.
template <class Class, class Member, Member (Class::*mp)>
struct get_member
{
static Member& execute(Class* c)
{
return c->*mp;
}
};
template <
PyTypeObject const* python_type
, class Value
, class PythonObject
, class Extract
>
struct reference_from_python
{
typedef type_from_python<python_type> convertible_t;
reference_from_python()
: m_mutable_converter(
&convertible_t::convertible, convert_mutable)
, m_const_converter(
&convertible_t::convertible, convert_const)
{}
static Value& convert_mutable(PyObject* op, converter::from_python_data&)
{
return Extract::execute(*(PythonObject*)op);
}
static Value const& convert_const(PyObject* op, converter::from_python_data&)
{
return Extract::execute(*(PythonObject*)op);
}
private:
typedef converter::from_python_converter<Value&> mutable_converter;
typedef converter::from_python_converter<Value const&> const_converter;
mutable_converter m_mutable_converter;
const_converter m_const_converter;
};
}} // namespace boost::python
#endif // REFERENCE_FROM_PYTHON_DWA2002130_HPP

View File

@@ -7,34 +7,41 @@
# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP
# include <boost/python/default_call_policies.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/to_python_indirect.hpp>
# include <boost/python/with_custodian_and_ward.hpp>
# include <boost/mpl/select_type.hpp>
namespace boost { namespace python {
namespace detail
{
template <std::size_t>
struct return_internal_reference_owner_arg_must_be_greater_than_zero
template <class T>
struct return_internal_reference_requires_a_pointer_or_reference_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
struct internal_reference_to_python_generator
{
template <class T>
struct apply
{
typedef typename mpl::select_type<
is_object<T>::value
, detail::return_internal_reference_requires_a_pointer_or_reference_return_type<T>
, to_python_indirect<T, detail::make_reference_holder>
>::type type;
};
};
template <std::size_t owner_arg = 1, class Base = default_call_policies>
struct return_internal_reference
: with_custodian_and_ward_postcall<0, owner_arg, Base>
{
private:
BOOST_STATIC_CONSTANT(bool, legal = owner_arg > 0);
public:
typedef typename mpl::select_type<
legal
, reference_existing_object
, detail::return_internal_reference_owner_arg_must_be_greater_than_zero<owner_arg>
>::type result_converter;
typedef reference_existing_object result_converter;
};
}} // namespace boost::python

View File

@@ -9,10 +9,10 @@
namespace boost { namespace python {
template <class ResultConverterGenerator, class Base = default_call_policies>
template <class Handler, class Base = default_call_policies>
struct return_value_policy : Base
{
typedef ResultConverterGenerator result_converter;
typedef Handler result_converter;
};
}} // namespace boost::python

View File

@@ -12,7 +12,7 @@
namespace boost { namespace python {
template <class T, class Conversion>
template <class T, class Derived>
struct to_python_converter
{
to_python_converter();
@@ -22,11 +22,11 @@ struct to_python_converter
// implementation
//
template <class T, class Conversion>
to_python_converter<T,Conversion>::to_python_converter()
template <class T, class Derived>
to_python_converter<T,Derived>::to_python_converter()
{
typedef converter::as_to_python_value_function<
T, Conversion
T, Derived
> normalized;
converter::registry::insert(

View File

@@ -10,12 +10,11 @@
# include <boost/python/object/pointer_holder.hpp>
# include <boost/python/object/class_object.hpp>
# include <boost/python/detail/unwind_type.hpp>
# include <boost/shared_ptr.hpp>
# include <memory>
namespace boost { namespace python {
template <class T, class MakeHolder>
template <class T, class HolderGenerator>
struct to_python_indirect
{
static bool convertible();
@@ -35,15 +34,8 @@ namespace detail
template <class T>
static result_type execute(T* p)
{
// can't use auto_ptr with Intel 5 for some reason
# if defined(__ICL) && __ICL < 600
typedef boost::shared_ptr<T> smart_pointer;
# else
typedef std::auto_ptr<T> smart_pointer;
# endif
return new objects::pointer_holder<smart_pointer, T>(
smart_pointer(p));
return new objects::pointer_holder<std::auto_ptr<T>, T>(
std::auto_ptr<T>(p));
}
};
@@ -69,14 +61,14 @@ namespace detail
};
}
template <class T, class MakeHolder>
inline bool to_python_indirect<T,MakeHolder>::convertible()
template <class T, class HolderGenerator>
inline bool to_python_indirect<T,HolderGenerator>::convertible()
{
return type() != 0;
}
template <class T, class MakeHolder>
inline PyObject* to_python_indirect<T,MakeHolder>::operator()(T x) const
template <class T, class HolderGenerator>
inline PyObject* to_python_indirect<T,HolderGenerator>::operator()(T x) const
{
PyObject* raw_result = type()->tp_alloc(type(), 0);
@@ -90,7 +82,7 @@ inline PyObject* to_python_indirect<T,MakeHolder>::operator()(T x) const
// Build a value_holder to contain the object using the copy
// constructor
objects::instance_holder* p =
detail::unwind_type<MakeHolder>(x);
detail::unwind_type<HolderGenerator>(x);
// Install it in the instance
p->install(raw_result);
@@ -99,8 +91,8 @@ inline PyObject* to_python_indirect<T,MakeHolder>::operator()(T x) const
return result.release();
}
template <class T, class MakeHolder>
inline PyTypeObject* to_python_indirect<T,MakeHolder>::type()
template <class T, class HolderGenerator>
inline PyTypeObject* to_python_indirect<T,HolderGenerator>::type()
{
return detail::unwind_type<detail::get_pointer_class,T>();
}

View File

@@ -6,94 +6,15 @@
#ifndef TYPE_FROM_PYTHON_DWA2002130_HPP
# define TYPE_FROM_PYTHON_DWA2002130_HPP
# include <boost/python/converter/registry.hpp>
namespace boost { namespace python {
namespace detail
{
// Given a pointer-to-function of 1 parameter returning a reference
// type, return the type_id of the function's return type.
template <class T, class U>
inline converter::undecorated_type_id_t extractor_type_id(T&(*)(U))
{
return converter::undecorated_type_id<T>();
}
// A function generator whose static execute() function is an lvalue
// from_python converter using the given Extractor. U is exepcted to
// be the actual type of the PyObject instance from which the result
// is being extracted.
template <class Extractor, class U>
struct normalized_extractor
{
static inline void* execute(PyObject* op)
{
typedef typename boost::add_reference<U>::type param;
return &Extractor::execute(
boost::python::converter::detail::void_ptr_to_reference(
op, (param(*)())0 )
);
}
};
// Given an Extractor type and a pointer to its execute function,
// return a new object whose static execute function does the same
// job but is a conforming lvalue from_python conversion function.
//
// usage: normalize<Extractor>(&Extractor::execute)
template <class Extractor, class T, class U>
inline normalized_extractor<Extractor,U>
normalize(T(*)(U), Extractor* = 0)
{
return normalized_extractor<Extractor, U>();
}
}
// An Extractor which extracts the given member from a Python object
// whose instances are stored as InstanceType.
template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
struct member_extractor
{
static MemberType& execute(InstanceType& c)
{
(void)c.ob_type; // static assertion
return c.*member;
}
};
// An Extractor which simply extracts the entire python object
// instance of InstanceType.
template <class InstanceType>
struct identity_extractor
{
static InstanceType& execute(InstanceType& c)
{
(void)c.ob_type; // static assertion
return c;
}
};
// Registers a from_python conversion which extracts lvalues using
// Extractor's static execute function from Python objects whose type
// object is python_type.
template <PyTypeObject const* python_type, class Extractor>
template <PyTypeObject const* python_type>
struct type_from_python
{
type_from_python()
static void* convertible(PyObject* op)
{
converter::registry::insert(
&extract, detail::extractor_type_id(&Extractor::execute));
}
static void* extract(PyObject* op)
{
return PyObject_TypeCheck(op, const_cast<PyTypeObject*>(python_type))
? const_cast<void*>(
static_cast<void const volatile*>(
detail::normalize<Extractor>(&Extractor::execute).execute(op)))
: 0
;
return PyObject_TypeCheck(
op, const_cast<PyTypeObject*>(python_type)) ? op : 0;
}
};

View File

@@ -0,0 +1,73 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef VALUE_FROM_PYTHON_DWA2002130_HPP
# define VALUE_FROM_PYTHON_DWA2002130_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/static_assert.hpp>
namespace boost { namespace python {
template <typename T, class Derived>
struct value_from_python
{
typedef value_from_python<T,Derived> self;
typedef converter::from_python_check from_python_check;
value_from_python(from_python_check convertible)
: m_converter(
convertible
, &Derived::convert
// Change this to a compile-time check later to avoid
// generating destroy function
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
)
{
}
value_from_python()
: m_converter(
&Derived::convertible
, &Derived::convert
// Change this to a compile-time check later to avoid
// generating destroy function
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
)
{
}
static void* get_storage(converter::from_python_data& data)
{
return converter::get_storage<T const&>(data);
}
// Mark successful construction
static void constructed(converter::from_python_data& data)
{
data.stage1 = self::get_storage(data);
}
inline static void destroy(converter::from_python_data& data)
{
// Get the location of the storage for
void* storage = self::get_storage(data);
// Check for successful construction
if (data.stage1 == storage)
static_cast<T*>(storage)->~T();
}
private:
converter::from_python_converter<T const&> m_converter;
};
}} // namespace boost::python
#endif // VALUE_FROM_PYTHON_DWA2002130_HPP

18
src/converter/body.cpp Normal file
View File

@@ -0,0 +1,18 @@
// 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.
#include <boost/python/converter/body.hpp>
namespace boost { namespace python { namespace converter {
// default implementation is a no-op. Most handles will not hold any
// data that needs to be managed. Unwrap objects which convert
// by-value are an exception. Fortunately, the concrete body subclass
// has that knowledge.
void body::destroy_handle(handle*) const
{
}
}}} // namespace boost::python::converter

View File

@@ -7,259 +7,221 @@
#include <boost/python/detail/config.hpp>
#include <boost/python/detail/wrap_python.hpp>
#include <boost/python/converter/builtin_converters.hpp>
#include <boost/python/converter/target.hpp>
#include <boost/python/value_from_python.hpp>
#include <boost/python/converter/from_python_data.hpp>
#include <boost/python/converter/registry.hpp>
#include <boost/python/reference.hpp>
#include <boost/python/errors.hpp>
#include <boost/cast.hpp>
//#include <boost/mpl/type_list.hpp>
#include <string>
#include <complex>
namespace boost { namespace python { namespace converter {
namespace
{
// An lvalue conversion function which extracts a char const* from a
// Python String.
void* convert_to_cstring(PyObject* obj)
// Only an object which we know is holding a char const* can be
// converted to one
struct convertible_to_cstring
{
return PyString_Check(obj) ? PyString_AsString(obj) : 0;
}
// Given a target type and a SlotPolicy describing how to perform a
// given conversion, registers from_python converters which use the
// SlotPolicy to extract the type.
template <class T, class SlotPolicy>
struct slot_rvalue_from_python
{
public:
slot_rvalue_from_python()
static unaryfunc* execute(PyObject* obj)
{
registry::insert(
&slot_rvalue_from_python<T,SlotPolicy>::convertible
, &slot_rvalue_from_python<T,SlotPolicy>::construct
, undecorated_type_id<T>()
);
}
private:
static void* convertible(PyObject* obj)
{
unaryfunc* slot = SlotPolicy::get_slot(obj);
return slot && *slot ? slot : 0;
}
static void construct(PyObject* obj, rvalue_stage1_data* data)
{
// Get the (intermediate) source object
unaryfunc creator = *static_cast<unaryfunc*>(data->convertible);
ref intermediate(creator(obj));
// Get the location in which to construct
void* storage = ((rvalue_data<T>*)data)->storage.bytes;
new (storage) T(SlotPolicy::extract(intermediate.get()));
// record successful construction
data->convertible = storage;
return PyString_Check(obj) ? &obj->ob_type->tp_str : 0;
}
};
// A SlotPolicy for extracting integer types from Python objects
struct int_rvalue_from_python
struct extract_cstring
{
static unaryfunc* get_slot(PyObject* obj)
static char const* execute(PyObject* obj)
{
return PyString_AsString(obj);
}
};
// Any object which can be converted to a Python string can also be
// converted to a C++ string, since the latter owns its bytes.
struct convertible_to_string
{
static unaryfunc* execute(PyObject* obj)
{
return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0;
}
};
// Transform a function returning a unaryfunc* into one that returns a void*
template <class F>
struct return_void_ptr
{
static void* execute(PyObject* p) { return F::execute(p); }
};
template <
class T // The target type
, class Convertible // returns a pointer to a unaryfunc producing an object
, class TExtract // ...from which TExtract extracts T's constructor argument
>
struct tp_scalar_from_python
: from_python_converter<T>
{
private:
typedef return_void_ptr<Convertible> convertible_fn;
public:
tp_scalar_from_python()
: from_python_converter<T>(
&convertible_fn::execute
, convert)
{}
static T convert(PyObject* obj, from_python_data& data)
{
unaryfunc converter = *(unaryfunc*)data.stage1;
ref converted(converter(obj));
return TExtract::execute(converted.get());
}
};
// Extract a reference to T using the functions in the source
// object's type slots
template <
class T // The target type
, class Convertible // returns a pointer to a unaryfunc producing an object
, class TExtract // ...from which TExtract extracts T's constructor argument
>
struct tp_cref_from_python
: value_from_python<T, tp_cref_from_python<T,Convertible,TExtract> >
{
private:
typedef tp_cref_from_python<T,Convertible,TExtract> self;
typedef value_from_python<T,tp_cref_from_python<T,Convertible,TExtract> > base;
public:
tp_cref_from_python()
: base(&return_void_ptr<Convertible>::execute)
{}
static T const& convert(PyObject* obj, from_python_data& data)
{
unaryfunc converter = *(unaryfunc*)data.stage1;
void* storage = self::get_storage(data);
ref converted(converter(obj));
T* const p = new (storage) T(TExtract::execute(converted.get()));
// note that construction is successful.
data.stage1 = p;
return *p;
}
};
struct convertible_to_int
{
static unaryfunc* execute(PyObject* obj)
{
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
if (number_methods == 0)
return 0;
// For floating types, return the float conversion slot to avoid
// creating a new object. We'll handle that below
if (PyFloat_Check(obj))
// creating a new object. We'll handle that in
// py_int_or_float_as_long, below
if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float)
return &number_methods->nb_float;
if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__int__"))
return 0;
return &number_methods->nb_int;
}
static long extract(PyObject* intermediate)
return number_methods && number_methods->nb_int
? &number_methods->nb_int : 0;
}
};
struct py_int_or_float_as_long
{
static long execute(PyObject* obj)
{
if (PyFloat_Check(intermediate))
if (PyObject_TypeCheck(obj, &PyFloat_Type))
{
return numeric_cast<long>(PyFloat_AS_DOUBLE(intermediate));
return numeric_cast<long>(PyFloat_AS_DOUBLE(obj));
}
else
{
return PyInt_AS_LONG(intermediate);
return PyInt_AS_LONG(obj);
}
}
};
// identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
// "slot" which just returns its argument. Used for bool
// conversions, since all Python objects are directly convertible to
// bool
extern "C" PyObject* identity_unaryfunc(PyObject* x)
struct convertible_to_double
{
Py_INCREF(x);
return x;
}
unaryfunc py_object_identity = identity_unaryfunc;
// A SlotPolicy for extracting bool from a Python object
struct bool_rvalue_from_python
{
static unaryfunc* get_slot(PyObject*)
{
return &py_object_identity;
}
static bool extract(PyObject* intermediate)
{
return PyObject_IsTrue(intermediate);
}
};
// A SlotPolicy for extracting floating types from Python objects.
struct float_rvalue_from_python
{
static unaryfunc* get_slot(PyObject* obj)
static unaryfunc* execute(PyObject* obj)
{
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
if (number_methods == 0)
return 0;
// For integer types, return the tp_int conversion slot to avoid
// creating a new object. We'll handle that below
if (PyInt_Check(obj))
// creating a new object. We'll handle that in
// py_float_or_int_as_double, below
if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int)
return &number_methods->nb_int;
if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__float__"))
return 0;
return &number_methods->nb_float;
return number_methods && number_methods->nb_float
? &number_methods->nb_float : 0;
}
static double extract(PyObject* intermediate)
};
struct py_float_or_int_as_double
{
static double execute(PyObject* obj)
{
if (PyInt_Check(intermediate))
if (PyObject_TypeCheck(obj, &PyInt_Type))
{
return PyInt_AS_LONG(intermediate);
return PyInt_AS_LONG(obj);
}
else
{
return PyFloat_AS_DOUBLE(intermediate);
return PyFloat_AS_DOUBLE(obj);
}
}
};
// A SlotPolicy for extracting C++ strings from Python objects.
struct string_rvalue_from_python
template <class T, class Convertible, class Convert>
struct scalar_from_python
{
// If the underlying object is "string-able" this will succeed
static unaryfunc* get_slot(PyObject* obj)
{
if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__str__"))
return 0;
return &obj->ob_type->tp_str;
};
// Remember that this will be used to construct the result object
static char const* extract(PyObject* intermediate)
{
return PyString_AsString(intermediate);
}
tp_cref_from_python<T,Convertible,Convert> cref_converter;
tp_scalar_from_python<T,Convertible,Convert> value_converter;
};
// identity_unaryfunc/non_null -- manufacture a unaryfunc "slot"
// which just returns its argument. Used for bool conversions, since
// all Python objects are directly convertible to bool
extern "C" PyObject* to_complex_unaryfunc(PyObject* x)
template <class T>
void register_int_converters(T* = 0)
{
return PyObject_CallMethod(x, "__complex__", const_cast<char*>("()"));
static scalar_from_python<T, convertible_to_int, py_int_or_float_as_long> x;
}
unaryfunc py_object_to_complex = to_complex_unaryfunc;
}
struct complex_rvalue_from_python
{
static unaryfunc* get_slot(PyObject* obj)
{
if (PyComplex_Check(obj))
return &py_object_identity;
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
// For integer types, return the tp_int conversion slot to avoid
// creating a new object. We'll handle that below
if (PyInt_Check(obj) && number_methods)
return &number_methods->nb_int;
if (PyFloat_Check(obj) && number_methods)
return &number_methods->nb_float;
if (!PyObject_HasAttrString((PyObject*)obj, "__complex__"))
return 0;
return &py_object_to_complex;
}
static std::complex<double> extract(PyObject* intermediate)
{
if (PyComplex_Check(intermediate))
{
return std::complex<double>(
PyComplex_RealAsDouble(intermediate)
, PyComplex_ImagAsDouble(intermediate));
}
else if (PyInt_Check(intermediate))
{
return PyInt_AS_LONG(intermediate);
}
else if (!PyFloat_Check(intermediate))
{
PyErr_SetString(PyExc_TypeError, "__complex__ method did not return a Complex object");
throw error_already_set();
}
return PyFloat_AS_DOUBLE(intermediate);
}
};
}
#define REGISTER_INT_CONVERTERS(U) slot_rvalue_from_python<U,int_rvalue_from_python>()
#define REGISTER_INT_CONVERTERS(U) register_int_converters<U>()
#define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U)
void initialize_builtin_converters()
{
// booleans
slot_rvalue_from_python<bool,bool_rvalue_from_python>();
// integer types
REGISTER_INT_CONVERTERS2(char);
REGISTER_INT_CONVERTERS2(short);
REGISTER_INT_CONVERTERS2(int);
REGISTER_INT_CONVERTERS2(long);
// floating types
slot_rvalue_from_python<float,float_rvalue_from_python>();
slot_rvalue_from_python<double,float_rvalue_from_python>();
slot_rvalue_from_python<long double,float_rvalue_from_python>();
static scalar_from_python<
float,convertible_to_double,py_float_or_int_as_double> float_from_python;
slot_rvalue_from_python<std::complex<float>,complex_rvalue_from_python>();
slot_rvalue_from_python<std::complex<double>,complex_rvalue_from_python>();
slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
static scalar_from_python<
double,convertible_to_double,py_float_or_int_as_double> double_from_python;
// Add an lvalue converter for char which gets us char const*
registry::insert(convert_to_cstring,undecorated_type_id<char>());
static scalar_from_python<
long double,convertible_to_double,py_float_or_int_as_double> long_double_from_python;
static scalar_from_python<
char const*, convertible_to_cstring, extract_cstring> cstring_from_python;
// Register by-value converters to std::string
slot_rvalue_from_python<std::string, string_rvalue_from_python>();
static tp_cref_from_python<
std::string, convertible_to_string, extract_cstring> string_from_python;
}
}}} // namespace boost::python::converter

View File

@@ -4,40 +4,23 @@
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/find_from_python.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/converter/from_python_data.hpp>
#include <boost/python/converter/from_python.hpp>
#include <boost/python/converter/registry.hpp>
namespace boost { namespace python { namespace converter {
BOOST_PYTHON_DECL void* find(
PyObject* source
, rvalue_from_python_registration const* chain
, rvalue_stage1_data& data)
{
for (;chain != 0; chain = chain->next)
{
void* r = chain->convertible(source);
if (r != 0)
{
data.construct = chain->construct;
return data.convertible = r;
}
}
return data.convertible = 0;
}
from_python_converter_base::from_python_converter_base(
type_id_t type
, from_python_check checker
)
: body(type)
, m_convertible(checker)
BOOST_PYTHON_DECL void* find(
PyObject* source
, lvalue_from_python_registration const* chain)
{
for (;chain != 0; chain = chain->next)
{
void* r = chain->convert(source);
if (r != 0)
return r;
}
return 0;
// Insert this in the converter chain.
from_python_converter_base*& head = registry::from_python_chain(type);
m_next = head;
head = this;
}
}}} // namespace boost::python::converter

35
src/converter/handle.cpp Normal file
View File

@@ -0,0 +1,35 @@
// 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.
#include <boost/python/converter/handle.hpp>
#include <boost/python/converter/body.hpp>
namespace boost { namespace python { namespace converter {
bool handle::convertible() const
{
for (handle const* p = this; p != 0; p = p->m_next)
{
if (p->m_body == 0)
return false;
}
return true;
}
void handle::destroy()
{
// Recurse down the chain releasing from tail to head
if (m_next != 0)
m_next->destroy();
// Our body knows how to destroy us. If we never got a body,
// there's nothing to do.
if (m_body)
m_body->destroy_handle(this);
}
// void handle::dummy::nonnull() {}
}}} // namespace boost::python::converter

View File

@@ -4,7 +4,6 @@
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/registry.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/converter/builtin_converters.hpp>
#include <map>
#include <stdexcept>
@@ -20,23 +19,20 @@ namespace // <unnamed>
// The unique to_python converter for the associated C++ type.
to_python_value_function m_to_python_converter;
// The collection of from_python converters for the associated
// C++ type.
lvalue_from_python_registration* m_lvalue_from_python;
rvalue_from_python_registration* m_rvalue_from_python;
from_python_converter_base* m_from_python_converters;
// The class object associated with this type
PyTypeObject* m_class_object;
};
typedef std::map<undecorated_type_id_t, entry> registry_t;
typedef std::map<type_id_t, entry> registry_t;
registry_t& entries()
{
static registry_t registry;
#ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually.
static bool builtin_converters_initialized = false;
if (!builtin_converters_initialized)
{
@@ -46,19 +42,17 @@ namespace // <unnamed>
initialize_builtin_converters();
}
#endif
return registry;
}
entry* find(undecorated_type_id_t type)
entry* find(type_id_t type)
{
return &entries()[type];
}
entry::entry()
: m_to_python_converter(0)
, m_lvalue_from_python(0)
, m_rvalue_from_python(0)
, m_from_python_converters(0)
, m_class_object(0)
{
}
@@ -84,46 +78,15 @@ namespace registry
slot = f;
}
// Insert an lvalue from_python converter
void insert(void* (*convert)(PyObject*), undecorated_type_id_t key)
from_python_converter_base*& from_python_chain(type_id_t key)
{
entry* found = find(key);
lvalue_from_python_registration *registration = new lvalue_from_python_registration;
registration->convert = convert;
registration->next = found->m_lvalue_from_python;
found->m_lvalue_from_python = registration;
insert(convert, 0, key);
return find(key)->m_from_python_converters;
}
// Insert an rvalue from_python converter
void insert(void* (*convertible)(PyObject*)
, constructor_function construct
, undecorated_type_id_t key)
{
entry* found = find(key);
rvalue_from_python_registration *registration = new rvalue_from_python_registration;
registration->convertible = convertible;
registration->construct = construct;
registration->next = found->m_rvalue_from_python;
found->m_rvalue_from_python = registration;
}
PyTypeObject*& class_object(undecorated_type_id_t key)
{
return find(key)->m_class_object;
}
lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t key)
{
return find(key)->m_lvalue_from_python;
}
rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t key)
{
return find(key)->m_rvalue_from_python;
}
} // namespace registry
}}} // namespace boost::python::converter

36
src/converter/unwrap.cpp Normal file
View File

@@ -0,0 +1,36 @@
// 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.
#include <boost/python/converter/unwrap.hpp>
namespace boost { namespace python { namespace converter {
namespace
{
struct pyobject_unwrapper : unwrapper_base
{
pyobject_unwrapper();
void* can_convert(PyObject*) const;
};
pyobject_unwrapper static_unwrapper;
std::pair<unwrapper_base*,void*> unwrapper_pair(&static_unwrapper,&static_unwrapper);
pyobject_unwrapper::pyobject_unwrapper()
: unwrapper_base(type_id<PyObject*>())
{
}
void* pyobject_unwrapper::can_convert(PyObject*) const
{
return non_null;
}
}
BOOST_PYTHON_DECL std::pair<unwrapper_base*,void*>&
unwrap_more_<PyObject*>::m_unwrapper = unwrapper_pair;
}}} // namespace boost::python::converter

View File

@@ -0,0 +1,31 @@
// 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.
#include <boost/python/converter/unwrapper.hpp>
#include <boost/python/converter/registry.hpp>
#include <boost/type_traits/same_traits.hpp>
namespace boost { namespace python { namespace converter {
unwrapper_base::unwrapper_base(type_id_t key)
: body(key)
{
registry::insert(*this);
}
unwrapper_base::~unwrapper_base()
{
if (can_unregister())
registry::remove(*this);
}
namespace
{
int arbitrary;
}
void* const unwrapper_base::non_null = &arbitrary;
}}} // namespace boost::python::converter

41
src/converter/wrapper.cpp Normal file
View File

@@ -0,0 +1,41 @@
// 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.
#include <boost/python/converter/registry.hpp>
#include <boost/python/converter/wrapper.hpp>
namespace boost { namespace python { namespace converter {
wrapper_base::wrapper_base(type_id_t type)
: body(type)
{
registry::insert(*this);
}
wrapper_base::~wrapper_base()
{
if (can_unregister())
registry::remove(*this);
}
namespace
{
// This doesn't actually get called, but we need something to fill
// in the slot in the wrap<PyObject*> class.
struct identity_wrapper_t : wrapper<PyObject*>
{
PyObject* convert(PyObject* source) const
{
return source;
}
};
identity_wrapper_t identity_wrapper_object;
}
BOOST_PYTHON_DECL body& identity_wrapper = identity_wrapper_object;
}}} // namespace boost::python::converter

View File

@@ -1,4 +1,4 @@
# (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell and
# (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.
@@ -8,8 +8,8 @@
from gen_function import *
import string
header = '''// (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright notice appears
header = '''// (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.
//
@@ -24,10 +24,11 @@ body_sections = (
#ifndef RETURNING_DWA20011201_HPP
# define RETURNING_DWA20011201_HPP
//# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/config.hpp>
# include <boost/python/convert.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/python/from_python.hpp>
namespace boost { namespace python { namespace detail {
@@ -61,49 +62,32 @@ struct returning<void>
#'
member_function = ''' template <class P, class A0%(, class A%+%)>
static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args_, PyObject*, P const& policies)
member_function = ''' template <class A0%(, class A%+%)>
static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args, PyObject* /* keywords */ )
{
// check that each of the arguments is convertible
from_python<A0%1*> c0(PyTuple_GET_ITEM(args_, 0));
if (!c0.convertible()) return 0;
%( from_python<A%+> c%+(PyTuple_GET_ITEM(args_, %+));
if (!c%+.convertible()) return 0;
unwrap<A0%1&> c0(PyTuple_GET_ITEM(args, 0));
%( unwrap_more<A%+> c%+(PyTuple_GET_ITEM(args, %+), c%n);
%)
%[r%: // find the result converter
typedef typename P::result_converter result_converter;
typename eval<result_converter,R>::type cr;
if (!cr.convertible()) return 0;
%] if (!policies.precall(args_)) return 0;
%[r%:PyObject* result = cr( %]((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)(
%(c%+(PyTuple_GET_ITEM(args_, %+))%:
, %))%[r%: )%];
return policies.postcall(args_, %[r%:result%]%[v%:detail::none()%]);
wrap_more<R> r(c%n);
%] if (!c0) return 0;
%[r%:return r( %]((*c0).*pmf)(%(*c%+%:, %))%[r%: )%];%[v%:
return detail::none();%]
}
'''
free_function = ''' template <class P%(, class A%n%%)>
static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject* args_, PyObject*, P const& policies)
free_function = '''%{ template <%(class A%n%:, %)>
%} static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject*%{ args%}, PyObject* /* keywords */ )
{%{
// check that each of the arguments is convertible
%}%( from_python<A%n> c%n(PyTuple_GET_ITEM(args_, %n));
if (!c%n.convertible()) return 0;
%)
%[r%: // find the result converter
typedef typename P::result_converter result_converter;
typename eval<result_converter,R>::type cr;
if (!cr.convertible()) return 0;
%]%[not-void-and-0-arg%: if (!policies.precall(args_)) return 0;
%] %[r%:PyObject* result = cr( %](*pf)(
%(c%n(PyTuple_GET_ITEM(args_, %n))%:
, %))%[r%: )%];
return policies.postcall(args_, %[r%:result%]%[v%:detail::none()%]);
%}%( unwrap%{_more%}<A%n> c%n(PyTuple_GET_ITEM(args, %n)%{, c%-%});
%)%[r%:
// find the result converter
wrap%{_more%}<R> c%n%{(c%-)%};%]%[not-void-and-0-arg%:
if (!c0) return 0;%]
%[r%:return c%n( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%:
return detail::none();%]
}
'''

View File

@@ -6,10 +6,9 @@
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
#include <boost/python/detail/module_base.hpp>
#include <boost/python/object/function.hpp>
#include <boost/python/module.hpp>
namespace boost { namespace python { namespace detail {
namespace boost { namespace python {
module_base::module_base(const char* name)
: m_module(
@@ -47,4 +46,4 @@ void module_base::add_type(ref x)
PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } };
}}} // namespace boost::python::detail
}} // namespace boost::python

View File

@@ -3,7 +3,8 @@
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/registry.hpp>
#include <boost/python/detail/config.hpp>
#include <boost/python/detail/wrap_python.hpp>
#include <boost/python/object/class.hpp>
#include <boost/python/objects.hpp>
#include <boost/python/detail/map_entry.hpp>
@@ -44,8 +45,8 @@ PyTypeObject class_metatype_object = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -118,8 +119,8 @@ PyTypeObject class_type_object = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -162,7 +163,7 @@ void instance_holder::install(PyObject* self) throw()
}
BOOST_PYTHON_DECL void*
find_instance_impl(PyObject* inst, converter::undecorated_type_id_t type)
find_instance_impl(PyObject* inst, converter::type_id_t type)
{
if (inst->ob_type->ob_type != &class_metatype_object)
return 0;
@@ -204,7 +205,7 @@ namespace
std::vector<entry>::const_iterator p
= boost::detail::lower_bound(start, finish, id);
if (p == finish || p->key != id)
if (p == finish && p->key != id)
{
string report("extension class wrapper for base class ");
(report += id.name()) += " has not been created yet";

View File

@@ -27,8 +27,8 @@ namespace bpl_test {
// example: Foo, Bar, and Baz are C++ classes we want to wrap.
//
class Foo // prohibit copying, proving that it doesn't choke
: private boost::noncopyable // our generation of to_python().
class Foo // prohibit copying, proving that it doesn't choke
: boost::noncopyable // our generation of to_python().
{
public: // constructor/destructor
Foo(int x) : m_x(x) {}

View File

@@ -1,81 +0,0 @@
#include <boost/python/detail/destroy.hpp>
#include <cassert>
struct bar;
namespace boost
{
// lie to the library about bar so we can show that it's destructor is optimized away.
template <>
struct has_trivial_destructor<bar>
{
BOOST_STATIC_CONSTANT(bool, value=true);
};
}
int count;
int marks[] = {
-1
, -1, -1
, -1, -1, -1, -1
, -1
};
int* kills = marks;
struct foo
{
foo() : n(count++) {}
~foo()
{
*kills++ = n;
}
int n;
};
struct bar : foo {};
void assert_destructions(int n)
{
for (int i = 0; i < n; ++i)
assert(marks[i] == i);
assert(marks[n] == -1);
}
int main()
{
assert_destructions(0);
typedef int a[2];
foo* f1 = new foo;
boost::python::detail::destroy_reference<foo const volatile&>(f1);
assert_destructions(1);
foo* f2 = new foo[2];
typedef foo x[2];
boost::python::detail::destroy_reference<x const&>(f2);
assert_destructions(3);
typedef foo y[2][2];
x* f3 = new y;
boost::python::detail::destroy_reference<y&>(f3);
assert_destructions(7);
bar* b1 = new bar;
boost::python::detail::destroy_reference<bar&>(b1);
assert_destructions(7);
bar* b2 = new bar[2];
typedef bar xb[2];
boost::python::detail::destroy_reference<xb&>(b2);
assert_destructions(7);
typedef bar yb[2][2];
xb* b3 = new yb;
boost::python::detail::destroy_reference<yb&>(b3);
assert_destructions(7);
return 0;
}

View File

@@ -1,48 +0,0 @@
//#include <stdio.h>
#include <cassert>
#include <boost/python/detail/indirect_traits.hpp>
//#define print(expr) printf("%s ==> %s\n", #expr, expr)
int main()
{
using namespace boost::python::detail;
assert(is_reference_to_pointer<int*&>::value);
assert(is_reference_to_pointer<int* const&>::value);
assert(is_reference_to_pointer<int*volatile&>::value);
assert(is_reference_to_pointer<int*const volatile&>::value);
assert(!is_reference_to_pointer<int const volatile>::value);
assert(!is_reference_to_pointer<int>::value);
assert(!is_reference_to_pointer<int*>::value);
assert(!is_reference_to_const<int*&>::value);
assert(is_reference_to_const<int* const&>::value);
assert(!is_reference_to_const<int*volatile&>::value);
assert(is_reference_to_const<int*const volatile&>::value);
assert(!is_reference_to_const<int const volatile>::value);
assert(!is_reference_to_const<int>::value);
assert(!is_reference_to_const<int*>::value);
assert(is_reference_to_non_const<int*&>::value);
assert(!is_reference_to_non_const<int* const&>::value);
assert(is_reference_to_non_const<int*volatile&>::value);
assert(!is_reference_to_non_const<int*const volatile&>::value);
assert(!is_reference_to_non_const<int const volatile>::value);
assert(!is_reference_to_non_const<int>::value);
assert(!is_reference_to_non_const<int*>::value);
assert(!is_reference_to_volatile<int*&>::value);
assert(!is_reference_to_volatile<int* const&>::value);
assert(is_reference_to_volatile<int*volatile&>::value);
assert(is_reference_to_volatile<int*const volatile&>::value);
assert(!is_reference_to_volatile<int const volatile>::value);
assert(!is_reference_to_volatile<int>::value);
assert(!is_reference_to_volatile<int*>::value);
return 0;
}

View File

@@ -9,13 +9,15 @@
#include "complicated.hpp"
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/type_from_python.hpp>
#include <boost/python/object/value_holder.hpp>
#include <boost/python/object/pointer_holder.hpp>
#include <boost/python/object/class.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/converter/class.hpp>
#include <boost/python/reference_from_python.hpp>
#include <boost/python/to_python_converter.hpp>
#include <boost/python/value_from_python.hpp>
#include <boost/python/errors.hpp>
#include <boost/mpl/type_list.hpp>
#include <string.h>
@@ -103,6 +105,7 @@ PyObject* new_simple()
// description of how the type parameters to wrapper<> and unwrapper<>
// are selected.
//
using boost::python::converter::from_python_data;
using boost::python::to_python_converter;
// Wrap a simple by copying it into a Simple
@@ -117,13 +120,16 @@ struct simple_to_python
}
};
struct int_from_noddy_extractor
int noddy_to_int(PyObject* p, from_python_data&)
{
static int& execute(NoddyObject& p)
{
return p.x;
}
};
return static_cast<NoddyObject*>(p)->x;
}
// Extract a mutable reference to an int from a Noddy.
int& noddy_to_int_ref(PyObject* p, from_python_data&)
{
return static_cast<NoddyObject*>(p)->x;
}
//
// Some C++ functions to expose to Python
@@ -135,26 +141,6 @@ int f(simple const& s)
return strlen(s.s);
}
int f_mutable_ref(simple& s)
{
return strlen(s.s);
}
int f_mutable_ptr(simple* s)
{
return strlen(s->s);
}
int f_const_ptr(simple const* s)
{
return strlen(s->s);
}
int f2(SimpleObject const& s)
{
return strlen(s.x.s);
}
// A trivial passthru function for simple objects
simple const& g(simple const& x)
{
@@ -199,24 +185,34 @@ D take_d(D const& d) { return d; }
BOOST_PYTHON_MODULE_INIT(m1)
{
using namespace boost::python;
using boost::python::module;
using boost::python::class_;
using boost::python::converter::from_python_converter;
using boost::python::reference_from_python;
using boost::python::value_from_python;
using boost::python::type_from_python;
using boost::python::get_member;
using boost::python::copy_const_reference;
using boost::python::return_value_policy;
using boost::mpl::type_list;
simple_to_python();
// Create the converters; they are self-registering/unregistering.
static simple_to_python c1;
type_from_python<&NoddyType,int_from_noddy_extractor>();
boost::python::type_from_python<
&SimpleType
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
, member_extractor<SimpleObject, simple, &SimpleObject::x>
#else
, extract_simple_object
#endif
>();
type_from_python<&SimpleType, identity_extractor<SimpleObject> >();
static from_python_converter<int> c2(
&(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int);
static from_python_converter<int&> c3(
&(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int_ref);
static boost::python::reference_from_python<
&SimpleType
, simple
, SimpleObject
, extract_simple_object
>
unwrap_simple;
module m1("m1");
typedef boost::python::objects::pointer_holder_generator<
@@ -233,14 +229,9 @@ BOOST_PYTHON_MODULE_INIT(m1)
.def("new_noddy", new_noddy)
.def("new_simple", new_simple)
// Expose f() in all its variations
// Expose f()
.def("f", f)
.def("f_mutable_ref", f_mutable_ref)
.def("f_mutable_ptr", f_mutable_ptr)
.def("f_const_ptr", f_const_ptr)
.def("f2", f2)
// Expose g()
.def("g", g , return_value_policy<copy_const_reference>()
)

View File

@@ -57,18 +57,6 @@ try: wrap_int_ref(n)
>>> f(g(s))
12
>>> f_mutable_ref(g(s))
12
>>> f_const_ptr(g(s))
12
>>> f_mutable_ptr(g(s))
12
>>> f2(g(s))
12
Create an extension class which wraps "complicated" (init1 and get_n)
are a complicated constructor and member function, respectively.

View File

@@ -1,39 +0,0 @@
#include <boost/python/converter/type_id.hpp>
#include <cassert>
#include <boost/python/converter/pointer_type_id.hpp>
int main()
{
using namespace boost::python::converter;
undecorated_type_id_t x
= undecorated_type_id<int>();
assert(pointer_type_id<int*>() == x);
assert(pointer_type_id<int const*>() == x);
assert(pointer_type_id<int volatile*>() == x);
assert(pointer_type_id<int const volatile*>() == x);
assert(pointer_type_id<int*&>() == x);
assert(pointer_type_id<int const*&>() == x);
assert(pointer_type_id<int volatile*&>() == x);
assert(pointer_type_id<int const volatile*&>() == x);
assert(pointer_type_id<int*const&>() == x);
assert(pointer_type_id<int const*const&>() == x);
assert(pointer_type_id<int volatile*const&>() == x);
assert(pointer_type_id<int const volatile*const&>() == x);
assert(pointer_type_id<int*volatile&>() == x);
assert(pointer_type_id<int const*volatile&>() == x);
assert(pointer_type_id<int volatile*volatile&>() == x);
assert(pointer_type_id<int const volatile*volatile&>() == x);
assert(pointer_type_id<int*const volatile&>() == x);
assert(pointer_type_id<int const*const volatile&>() == x);
assert(pointer_type_id<int volatile*const volatile&>() == x);
assert(pointer_type_id<int const volatile*const volatile&>() == x);
return 0;
}

View File

@@ -1,148 +0,0 @@
#include <boost/python/converter/from_python.hpp>
//#include <cassert>
//#include <boost/type_traits.hpp>
#include <boost/python/converter/type_id.hpp>
#include <iostream>
int result;
#define ASSERT_SAME(T1,T2) \
if (!is_same< T1, T2 >::value) { \
std::cout << "*********************\n"; \
std::cout << type_id< T1 >() << " != " << type_id< T2 >() << "\n"; \
std::cout << "*********************\n"; \
result = 1; \
}
int main()
{
using namespace boost::python::converter;
using namespace boost;
ASSERT_SAME(
select_from_python<int>::type, rvalue_from_python<int>
);
ASSERT_SAME(
select_from_python<int const>::type, rvalue_from_python<int const>
);
ASSERT_SAME(
select_from_python<int volatile>::type, rvalue_from_python<int volatile>
);
ASSERT_SAME(
select_from_python<int const volatile>::type, rvalue_from_python<int const volatile>
);
ASSERT_SAME(
select_from_python<int*>::type, pointer_from_python<int*>
);
ASSERT_SAME(
select_from_python<int const*>::type, pointer_from_python<int const*>
);
ASSERT_SAME(
select_from_python<int volatile*>::type, pointer_from_python<int volatile*>
);
ASSERT_SAME(
select_from_python<int const volatile*>::type, pointer_from_python<int const volatile*>
);
ASSERT_SAME(
select_from_python<int&>::type, reference_from_python<int&>
);
ASSERT_SAME(
select_from_python<int const&>::type, rvalue_from_python<int const&>
);
ASSERT_SAME(
select_from_python<int volatile&>::type, reference_from_python<int volatile&>
);
ASSERT_SAME(
select_from_python<int const volatile&>::type, reference_from_python<int const volatile&>
);
ASSERT_SAME(
select_from_python<int*&>::type, reference_from_python<int*&>
);
ASSERT_SAME(
select_from_python<int const*&>::type, reference_from_python<int const*&>
);
ASSERT_SAME(
select_from_python<int volatile*&>::type, reference_from_python<int volatile*&>
);
ASSERT_SAME(
select_from_python<int const volatile*&>::type, reference_from_python<int const volatile*&>
);
ASSERT_SAME(
select_from_python<int* const&>::type, pointer_const_reference_from_python<int*const&>
);
ASSERT_SAME(
select_from_python<int const* const&>::type, pointer_const_reference_from_python<int const*const&>
);
ASSERT_SAME(
select_from_python<int volatile* const&>::type, pointer_const_reference_from_python<int volatile*const&>
);
ASSERT_SAME(
select_from_python<int const volatile* const&>::type, pointer_const_reference_from_python<int const volatile*const&>
);
ASSERT_SAME(
select_from_python<int*volatile&>::type, reference_from_python<int*volatile&>
);
ASSERT_SAME(
select_from_python<int const*volatile&>::type, reference_from_python<int const*volatile&>
);
ASSERT_SAME(
select_from_python<int volatile*volatile&>::type, reference_from_python<int volatile*volatile&>
);
ASSERT_SAME(
select_from_python<int const volatile*volatile&>::type, reference_from_python<int const volatile*volatile&>
);
ASSERT_SAME(
select_from_python<int*const volatile&>::type, reference_from_python<int*const volatile&>
);
ASSERT_SAME(
select_from_python<int const*const volatile&>::type, reference_from_python<int const*const volatile&>
);
ASSERT_SAME(
select_from_python<int volatile*const volatile&>::type, reference_from_python<int volatile*const volatile&>
);
ASSERT_SAME(
select_from_python<int const volatile*const volatile&>::type, reference_from_python<int const volatile*const volatile&>
);
return result;
}

View File

@@ -5,7 +5,7 @@
// to its suitability for any purpose.
#include <string>
#include <boost/python/module.hpp>
#include <complex>
template <class T>
struct by_value
@@ -29,7 +29,6 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters_ext)
{
boost::python::module("builtin_converters_ext")
.def("rewrap_value_bool", by_value<bool>::rewrap)
.def("rewrap_value_signed_char", by_value<signed char>::rewrap)
.def("rewrap_value_unsigned_char", by_value<unsigned char>::rewrap)
.def("rewrap_value_int", by_value<int>::rewrap)
@@ -41,14 +40,10 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters_ext)
.def("rewrap_value_float", by_value<float>::rewrap)
.def("rewrap_value_double", by_value<double>::rewrap)
.def("rewrap_value_long_double", by_value<long double>::rewrap)
.def("rewrap_value_complex_float", by_value<std::complex<float> >::rewrap)
.def("rewrap_value_complex_double", by_value<std::complex<double> >::rewrap)
.def("rewrap_value_complex_long_double", by_value<std::complex<long double> >::rewrap)
.def("rewrap_value_string", by_value<std::string>::rewrap)
.def("rewrap_value_cstring", by_value<char const*>::rewrap)
.def("rewrap_const_reference_bool", by_const_reference<bool>::rewrap)
.def("rewrap_const_reference_signed_char", by_const_reference<signed char>::rewrap)
.def("rewrap_const_reference_unsigned_char", by_const_reference<unsigned char>::rewrap)
.def("rewrap_const_reference_int", by_const_reference<int>::rewrap)
@@ -60,9 +55,6 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters_ext)
.def("rewrap_const_reference_float", by_const_reference<float>::rewrap)
.def("rewrap_const_reference_double", by_const_reference<double>::rewrap)
.def("rewrap_const_reference_long_double", by_const_reference<long double>::rewrap)
.def("rewrap_const_reference_complex_float", by_const_reference<std::complex<float> >::rewrap)
.def("rewrap_const_reference_complex_double", by_const_reference<std::complex<double> >::rewrap)
.def("rewrap_const_reference_complex_long_double", by_const_reference<std::complex<long double> >::rewrap)
.def("rewrap_const_reference_string", by_const_reference<std::string>::rewrap)
.def("rewrap_const_reference_cstring", by_const_reference<char const*>::rewrap)

View File

@@ -1,11 +1,5 @@
"""
>>> from builtin_converters_ext import *
>>> rewrap_value_bool(None)
0
>>> rewrap_value_bool(0)
0
>>> rewrap_value_bool(33)
1
>>> rewrap_value_signed_char(42)
42
>>> rewrap_value_unsigned_char(42)
@@ -30,24 +24,11 @@
>>> rewrap_value_long_double(4.2) - 4.2
0.0
>>> abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001
1
>>> rewrap_value_cstring('hello, world')
'hello, world'
>>> rewrap_value_string('yo, wassup?')
'yo, wassup?'
>>> rewrap_const_reference_bool(None)
0
>>> rewrap_const_reference_bool(0)
0
>>> rewrap_const_reference_bool('yes')
1
>>> rewrap_const_reference_signed_char(42)
42
>>> rewrap_const_reference_unsigned_char(42)
@@ -64,7 +45,6 @@
42
>>> rewrap_const_reference_unsigned_long(42)
42
>>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001
1
>>> rewrap_const_reference_double(4.2) - 4.2
@@ -72,29 +52,11 @@
>>> rewrap_const_reference_long_double(4.2) - 4.2
0.0
>>> abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001
1
>>> rewrap_const_reference_cstring('hello, world')
'hello, world'
>>> rewrap_const_reference_string('yo, wassup?')
'yo, wassup?'
Check that None <==> NULL
>>> rewrap_const_reference_cstring(None)
But when converted to a string rvalue, None becomes 'None':
>>> rewrap_const_reference_string(None)
'None'
Now check implicit conversions between floating/integer types
>>> rewrap_const_reference_float(42)
@@ -109,27 +71,6 @@ Now check implicit conversions between floating/integer types
>>> rewrap_value_int(42.0)
42
Check that classic classes also work
>>> class FortyTwo:
... def __int__(self):
... return 42
... def __float__(self):
... return 42.0
... def __complex__(self):
... return complex(4+.2j)
... def __str__(self):
... return '42'
>>> rewrap_const_reference_float(FortyTwo())
42.0
>>> rewrap_value_int(FortyTwo())
42
>>> rewrap_const_reference_string(FortyTwo())
'42'
>>> abs(rewrap_value_complex_double(FortyTwo()) - (4+.2j)) < .000001
1
"""
def run(args = None):
import sys