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

lvalue_from_pytype + documentation

[SVN r14030]
This commit is contained in:
Dave Abrahams
2002-05-23 16:38:44 +00:00
parent 051994bdf4
commit 67b3cdc7b7
4 changed files with 410 additions and 31 deletions

93
doc/v2/Extractor.html Executable file
View File

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

283
doc/v2/lvalue_from_pytype.html Executable file
View File

@@ -0,0 +1,283 @@
<!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_pytype.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_pytype-spec">Class Template <code>lvalue_from_pytype</code></a>
<dd>
<dl class="page-index">
<dt><a href="#lvalue_from_pytype-spec-synopsis">Class Template
<code>lvalue_from_pytype</code> synopsis</a>
<dt><a href="#lvalue_from_pytype-spec-ctors">Class Template
<code>lvalue_from_pytype</code> constructor</a>
</dl>
</dl>
<dl class="page-index">
<dt><a href="#extract_identity-spec">Class Template <code>extract_identity</code></a>
<dd>
<dl class="page-index">
<dt><a href="#extract_identity-spec-synopsis">Class Template
<code>extract_identity</code> synopsis</a>
<dt><a href="#extract_identity-spec-statics">Class Template
<code>extract_identity</code> static functions</a>
</dl>
<dt><a href="#extract_member-spec">Class Template <code>extract_member</code></a>
<dd>
<dl class="page-index">
<dt><a href="#extract_member-spec-synopsis">Class Template
<code>extract_member</code> synopsis</a>
<dt><a href="#extract_member-spec-statics">Class Template
<code>extract_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_pytype.hpp&gt;</code> supplies
a facility for extracting C++ objects from within Python instances
of a given type. This is typically useful for dealing with
&quot;traditional&quot; Python extension types.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="lvalue_from_pytype-spec"></a>Class template <code>lvalue_from_pytype</code></h3>
<p>Class template <code>lvalue_from_pytype</code> will register
from_python converters which, given an object of the given Python
type, can extract references and pointers to a particular C++
type. Its template arguments are:
<p>
<table border="1" summary="lvalue_from_pytype template parameters">
<caption>
<b><code>lvalue_from_pytype</code> Requirements</b><br>
In the table below, <b><code>x</code></b> denotes an object of type <code>PythonObject&amp;</code>
</caption>
<tr>
<th>Parameter
<th>Requirements
<th>Semantics
<tr>
<td><code>Extractor</code>
<td>a model of <a
href="Extractor.html#Extractor-concept">Extractor</a> whose
execute function returns a reference type.
<td>Extracts the lvalue from the Python object once its type has been confirmed
<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.
</table>
<h4><a name="lvalue_from_pytype-spec-synopsis"></a>Class template <code>lvalue_from_pytype</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class Extractor, PyTypeObject const* python_type&gt;
struct lvalue_from_pytype
{
lvalue_from_pytype();
};
}}
</pre>
<h4><a name="lvalue_from_pytype-spec-ctors"></a>Class template <code>lvalue_from_pytype</code> constructor</h4>
<pre>
lvalue_from_pytype();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Registers converters which can convert
Python objects of the given type to lvalues of the type returned
by <code>Extractor::execute</code>.
</dl>
<h3><a name="extract_identity-spec"></a>Class template <code>extract_identity</code></h3>
<p><code>extract_identity</code> is a model of <a
href="Extractor.html#Extractor-concept">Extractor</a> which can be
used in the common case where the C++ type to be extracted is the
same as the Python object type.
<h4><a name="extract_identity-spec-synopsis"></a>Class template
<code>extract_identity</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class InstanceType&gt;
struct extract_identity
{
static InstanceType&amp; execute(InstanceType&amp; c);
};
}}
</pre>
<h4><a name="extract_identity-spec-statics"></a>Class template <code>extract_identity</code> static functions</h4>
<pre>
InstanceType&amp; execute(InstanceType&amp; c);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>c</code>
</dl>
<h3><a name="extract_member-spec"></a>Class template <code>extract_member</code></h3>
<p><code>extract_member</code> is a model of <a
href="Extractor.html#Extractor-concept">Extractor</a> which can be
used in the common case in the common case where the C++
type to be extracted is a member of the Python object.
<h4><a name="extract_member-spec-synopsis"></a>Class template <code>extract_member</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class InstanceType, class MemberType, MemberType (InstanceType::*member)&gt;
struct extract_member
{
static MemberType&amp; execute(InstanceType&amp; c);
};
}}
</pre>
<h4><a name="extract_member-spec-statics"></a>Class template <code>extract_member</code> static functions</h4>
<pre>
static MemberType&amp; execute(InstanceType&amp; c);
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>c.*member</code>
</dl>
<h2><a name="examples"></a>Example</h2>
This example presumes that someone has implemented the standard <a
href="http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy
example module</a> from the Python documentation, and we want to build
a module which manipulates <code>Noddy</code>s. Since
<code>noddy_NoddyObject</code> is so simple that it carries no
interesting information, the example is a bit contrived: it assumes
you want to keep track of one particular object for some reason. This
module would have to be dynamically linked to the module which defines
<code>noddy_NoddyType</code>.
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/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 reference&lt;PyObject&gt; 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)
;
// register Noddy lvalue converter
lvalue_from_pytype&lt;extract_identity&lt;noddy_NoddyObject&gt;,&amp;noddy_NoddyType&gt;();
}
</pre>
<h3>Python code</h3>
<pre>
&gt;&gt;&gt; import noddy
&gt;&gt;&gt; n = noddy.new_noddy()
&gt;&gt;&gt; import noddy_cache
&gt;&gt;&gt; noddy_cache.is_cached(n)
0
&gt;&gt;&gt; noddy_cache.set_cache(n)
&gt;&gt;&gt; noddy_cache.is_cached(n)
1
&gt;&gt;&gt; noddy_cache.is_cached(noddy.new_noddy())
0
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
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

@@ -61,6 +61,9 @@
<dt><a href=
"Dereferenceable.html#Dereferenceable-concept">Dereferenceable</a>
<dt><a href=
"Dereferenceable.html#Extractor-concept">Extractor</a>
<dt><a href=
"HolderGenerator.html#HolderGenerator-concept">HolderGenerator</a>
@@ -350,7 +353,6 @@
<dt><a href=
"copy_non_const_reference.html">copy_non_const_reference.hpp</a>
<dd>
<dl class="index">
<dt><a href=
@@ -366,7 +368,6 @@
<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>
@@ -380,7 +381,6 @@
<dt><a href=
"reference_existing_object.html">reference_existing_object.hpp</a>
<dd>
<dl class="index">
<dt><a href=
@@ -394,22 +394,6 @@
</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>
@@ -443,6 +427,23 @@
</dl>
</dl>
<dt><a href=
"lvalue_from_pytype.html">lvalue_from_pytype.hpp</a>
<dd>
<dl class="index">
<dt><a href="lvalue_from_pytype.html#classes">Classes</a>
<dd>
<dl class="index">
<dt><a href=
"lvalue_from_pytype.html#lvalue_from_pytype-spec">lvalue_from_pytype</a>
<dt><a href=
"lvalue_from_pytype.html#extract_identity-spec">extract_identity</a>
<dt><a href=
"lvalue_from_pytype.html#extract_member-spec">extract_member</a>
</dl>
</dl>
<dt><a href=
"to_python_converter.html">to_python_converter.hpp</a>
@@ -483,16 +484,18 @@
</dl>
</dl>
<dt><a href="type_from_python.html">type_from_python.hpp</a>
<dt><a href="lvalue_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>
<dt><a href=
"type_from_python.html#identity_extractor-spec">identity_extractor</a>
<dt><a href=
"type_from_python.html#member_extractor-spec">member_extractor</a>
</dl>
</dl>

View File

@@ -9,7 +9,7 @@
#include "complicated.hpp"
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/type_from_python.hpp>
#include <boost/python/lvalue_from_pytype.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/to_python_converter.hpp>
@@ -111,7 +111,7 @@ struct simple_to_python
}
};
struct int_from_noddy_extractor
struct int_from_noddy
{
static int& execute(NoddyObject& p)
{
@@ -198,18 +198,18 @@ BOOST_PYTHON_MODULE_INIT(m1)
simple_to_python();
type_from_python<&NoddyType,int_from_noddy_extractor>();
lvalue_from_pytype<int_from_noddy,&NoddyType>();
boost::python::type_from_python<
&SimpleType
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
, member_extractor<SimpleObject, simple, &SimpleObject::x>
lvalue_from_pytype<
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters
extract_member<SimpleObject, simple, &SimpleObject::x>
#else
, extract_simple_object
extract_simple_object
#endif
, &SimpleType
>();
type_from_python<&SimpleType, identity_extractor<SimpleObject> >();
lvalue_from_pytype<extract_identity<SimpleObject>,&SimpleType>();
module m1("m1");