mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 04:42:28 +00:00
Compare commits
51 Commits
boost-1.27
...
svn-tags/m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bd3ec9877 | ||
|
|
0e597f5768 | ||
|
|
b28dc55237 | ||
|
|
a2dec7a05d | ||
|
|
db9fb22cf4 | ||
|
|
412a00249f | ||
|
|
ccb7a8f94f | ||
|
|
ee26e13bea | ||
|
|
493ff9c685 | ||
|
|
bbc49e1ba3 | ||
|
|
0ef39e4440 | ||
|
|
8a956bcdf6 | ||
|
|
a16ff29638 | ||
|
|
f6381e7e5e | ||
|
|
e014765797 | ||
|
|
3899684686 | ||
|
|
e11b457b79 | ||
|
|
a04cbd111c | ||
|
|
6c7d3e1eab | ||
|
|
d965b41bdd | ||
|
|
d660c12a74 | ||
|
|
43bcbf771e | ||
|
|
7f420361b1 | ||
|
|
361455678a | ||
|
|
47c1c6288c | ||
|
|
07abc9fac4 | ||
|
|
266923d9e8 | ||
|
|
622ff9d764 | ||
|
|
b75d11da3a | ||
|
|
8af49161fb | ||
|
|
ca872af3c8 | ||
|
|
aeccf45d4e | ||
|
|
dcae0eadd5 | ||
|
|
80effaa541 | ||
|
|
edd93c80a1 | ||
|
|
39646acf5b | ||
|
|
f697d2daa1 | ||
|
|
607631604f | ||
|
|
09d012a10b | ||
|
|
b303d49634 | ||
|
|
371723a5d4 | ||
|
|
4481c3bada | ||
|
|
70bb30b95a | ||
|
|
ebc641440e | ||
|
|
586b4db968 | ||
|
|
12c7981450 | ||
|
|
08c909fd41 | ||
|
|
44e43d3b47 | ||
|
|
9e8273c7f7 | ||
|
|
93735c7bf1 | ||
|
|
e37a97e2d5 |
66
Jamfile
66
Jamfile
@@ -4,14 +4,24 @@ 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
|
||||
@@ -26,45 +36,61 @@ PYTHON_PROPERTIES
|
||||
src/objects.cpp
|
||||
src/converter/builtin_converters.cpp
|
||||
:
|
||||
$(PYTHON_PROPERTIES)
|
||||
$(BOOST_PYTHON_V2_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
;
|
||||
|
||||
# -------- general test -------
|
||||
extension m1 : test/m1.cpp <lib>bpl
|
||||
extension m1 : test/m1.cpp <dll>bpl
|
||||
:
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
extension m2 : test/m2.cpp <lib>bpl
|
||||
extension m2 : test/m2.cpp <dll>bpl
|
||||
:
|
||||
: debug-python ;
|
||||
: ;
|
||||
|
||||
boost-python-runtest try : test/newtest.py <lib>m1 <lib>m2 : : debug-python ;
|
||||
boost-python-runtest try : test/newtest.py <pyd>m1 <pyd>m2 : : ;
|
||||
|
||||
# ----------- builtin converters -----------
|
||||
|
||||
extension builtin_converters_ext : test/test_builtin_converters.cpp <lib>bpl
|
||||
extension builtin_converters_ext : test/test_builtin_converters.cpp <dll>bpl
|
||||
:
|
||||
: debug-python
|
||||
:
|
||||
;
|
||||
|
||||
boost-python-runtest test_builtin_converters : test/test_builtin_converters.py
|
||||
<lib>builtin_converters_ext
|
||||
<pyd>builtin_converters_ext
|
||||
:
|
||||
: debug-python
|
||||
:
|
||||
;
|
||||
|
||||
# ----------- pointer adoption -----------
|
||||
|
||||
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <lib>bpl
|
||||
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <dll>bpl
|
||||
:
|
||||
: debug-python
|
||||
:
|
||||
;
|
||||
|
||||
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
|
||||
<lib>test_pointer_adoption_ext
|
||||
<pyd>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)
|
||||
;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test
|
||||
#
|
||||
# Declares the following targets:
|
||||
# 1. libboost_python, a static link library to be linked with all
|
||||
# 1. libboost_python.dll/.so, a dynamic 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) <lib>libboost_python ;
|
||||
boost-python-test $(test-name) : $(sources) <dll>boost_python ;
|
||||
}
|
||||
|
||||
#######################
|
||||
@@ -81,14 +81,14 @@ local CPP_SOURCES =
|
||||
init_function module_builder objects cross_module errors
|
||||
;
|
||||
|
||||
lib libboost_python_static : ../src/$(CPP_SOURCES).cpp
|
||||
lib boost_python_static : ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<define>BOOST_PYTHON_STATIC_LIB=1
|
||||
$(PYTHON_PROPERTIES) ;
|
||||
|
||||
dll libboost_python
|
||||
dll boost_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 <lib>boost_python_test <lib>libboost_python ;
|
||||
: ../test/comprehensive.py <pyd>boost_python_test <dll>boost_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 <lib>$(name) ;
|
||||
: ../example/test_$(name).py <pyd>$(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 <lib>$(modules) <lib>libboost_python
|
||||
: ../example/tst_$(test-name).py <pyd>$(modules) <dll>boost_python
|
||||
: : : $(PYTHON_VECT_ITERATIONS) ;
|
||||
}
|
||||
|
||||
|
||||
59
doc/boost.css
Normal file
59
doc/boost.css
Normal file
@@ -0,0 +1,59 @@
|
||||
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
|
||||
}
|
||||
@@ -37,19 +37,12 @@ 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>
|
||||
|
||||
@@ -47,8 +47,6 @@ 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");
|
||||
|
||||
@@ -65,11 +63,6 @@ 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>
|
||||
|
||||
@@ -78,26 +78,19 @@ namespace python = boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(my_module)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder my_module("my_module");
|
||||
|
||||
python::class_builder<Base> base_class(my_module, "Base");
|
||||
base_class.def(python::constructor<void>());
|
||||
|
||||
python::class_builder<Derived> derived_class(my_module, "Derived");
|
||||
derived_class.def(python::constructor<void>());
|
||||
<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
|
||||
}
|
||||
python::module_builder my_module("my_module");
|
||||
|
||||
python::class_builder<Base> base_class(my_module, "Base");
|
||||
base_class.def(python::constructor<void>());
|
||||
|
||||
python::class_builder<Derived> derived_class(my_module, "Derived");
|
||||
derived_class.def(python::constructor<void>());
|
||||
<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");
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
@@ -151,16 +151,9 @@ struct baz_callback {
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(foobar)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::python::module_builder foobar("foobar");
|
||||
boost::python::class_builder<baz,baz_callback> baz_class("baz");
|
||||
baz_class.def(&baz::calls_pure, "calls_pure");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
boost::python::module_builder foobar("foobar");
|
||||
boost::python::class_builder<baz,baz_callback> baz_class("baz");
|
||||
baz_class.def(&baz::calls_pure, "calls_pure");
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
31
doc/v2/acknowledgments.html
Normal file
31
doc/v2/acknowledgments.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
31
doc/v2/bibliography.html
Normal file
31
doc/v2/bibliography.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
62
doc/v2/call.html
Normal file
62
doc/v2/call.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<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 - <call.hpp></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 <call.hpp></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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
337
doc/v2/class.html
Normal file
337
doc/v2/class.html
Normal file
@@ -0,0 +1,337 @@
|
||||
<!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 - <boost/python/class.hpp>,
|
||||
<boost/python/class_fwd.hpp></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 <boost/python/class.hpp>,
|
||||
<boost/python/class_fwd.hpp></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><boost/python/class.hpp></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><boost/python/class_fwd.hpp></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_<T, Bases, <a
|
||||
href="HolderGenerator.html">HolderGenerator</a>></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 <class T
|
||||
, class Bases = <i>none</i>
|
||||
, class HolderGenerator = objects::value_holder_generator>
|
||||
class class_
|
||||
{
|
||||
class_();
|
||||
class_(char const* name);
|
||||
|
||||
template <class F>
|
||||
class_& def(char const* name, F f);
|
||||
|
||||
template <class Fn, class CallPolicy>
|
||||
class_& def(char const* name, Fn fn, CallPolicy policy);
|
||||
|
||||
template <class Args>
|
||||
class_& def_init(Args const& = Args());
|
||||
|
||||
class_& 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 <class F>
|
||||
class_& def(char const* name, F f)
|
||||
|
||||
template <class Fn, class CallPolicy>
|
||||
class_& 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 <class Args>
|
||||
class_& def_init(Args const& argument_types)
|
||||
|
||||
class_& 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><T,Args,HolderGenerator>()</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<T1, T2,</code>...<code>TN></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 <T1 = <i>unspecified</i>,...TN = <i>unspecified</i>>
|
||||
struct args : ::boost::mpl::type_list<T1,...TN>::type
|
||||
{};
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3><a name="bases-spec"></a>Class template
|
||||
<code>bases<T1, T2,</code>...<code>TN></code></h3>
|
||||
|
||||
<p>Essentially an alias for <code>boost::mpl::type_list</code> which users
|
||||
can use in <code>class_<</code>...<code>></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 <T1 = <i>unspecified</i>,...TN = <i>unspecified</i>>
|
||||
struct bases : ::boost::mpl::type_list<T1,...TN>::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& 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_<Foo,bases<Bar,Baz> >()
|
||||
.def_init(args<int,char const*>())
|
||||
.def_init(args<double>())
|
||||
.def("get_name", &Foo::get_name, return_internal_reference<>())
|
||||
.def("set_name", &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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
90
doc/v2/configuration.html
Normal file
90
doc/v2/configuration.html
Normal file
@@ -0,0 +1,90 @@
|
||||
<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"><boost/config.hpp></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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
135
doc/v2/copy_const_reference.html
Normal file
135
doc/v2/copy_const_reference.html
Normal file
@@ -0,0 +1,135 @@
|
||||
<!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 - <boost/python/copy_const_reference.hpp></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
|
||||
<boost/python/copy_const_reference.hpp></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 <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="copy_const_reference-spec-metafunctions"></a>Class
|
||||
<code>copy_const_reference</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> struct apply
|
||||
</pre>
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is <code>U const&</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><T>
|
||||
type;</code>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<h3>C++ Module Definition</h3>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/copy_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
// classes to wrap
|
||||
struct Bar { int x; }
|
||||
|
||||
struct Foo {
|
||||
Foo(int x) : { b.x = x; }
|
||||
Bar const& 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_<Bar>()
|
||||
)
|
||||
.add(
|
||||
class_<Foo>()
|
||||
.def_init(args<int>())
|
||||
.def("get_bar", &Foo::get_bar
|
||||
, return_value_policy<copy_const_reference>())
|
||||
)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
<h3>Python Code</h3>
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> f = Foo(3) # create a Foo object
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
135
doc/v2/copy_non_const_reference.html
Normal file
135
doc/v2/copy_non_const_reference.html
Normal file
@@ -0,0 +1,135 @@
|
||||
<!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 -
|
||||
<boost/python/copy_non_const_reference.hpp></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
|
||||
<boost/python/copy_non_const_reference.hpp></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 <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="copy_non_const_reference-spec-metafunctions"></a>Class
|
||||
<code>copy_non_const_reference</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> struct apply
|
||||
</pre>
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is <code>U&</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><T>
|
||||
type;</code>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<p>C++ code:
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/copy_non_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
// classes to wrap
|
||||
struct Bar { int x; }
|
||||
|
||||
struct Foo {
|
||||
Foo(int x) : { b.x = x; }
|
||||
Bar& 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_<Bar>()
|
||||
)
|
||||
.add(
|
||||
class_<Foo>()
|
||||
.def_init(args<int>())
|
||||
.def("get_bar", &Foo::get_bar
|
||||
, return_value_policy<copy_non_const_reference>())
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
Python Code:
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> f = Foo(3) # create a Foo object
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
170
doc/v2/default_call_policies.html
Normal file
170
doc/v2/default_call_policies.html
Normal file
@@ -0,0 +1,170 @@
|
||||
<!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 -
|
||||
<boost/python/default_call_policies.hpp></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
|
||||
<boost/python/default_call_policies.hpp></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 <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="default_result_converter-spec-metafunctions"></a>Class
|
||||
<code>default_result_converter</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> 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><T
|
||||
const&> 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 <class Handler, class Base = default_call_policies>
|
||||
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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
34
doc/v2/definitions.html
Normal file
34
doc/v2/definitions.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
232
doc/v2/errors.html
Normal file
232
doc/v2/errors.html
Normal file
@@ -0,0 +1,232 @@
|
||||
<!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 - <{{header}}></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 <boost/python/errors.hpp></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><boost/python/errors.hpp></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 <class T> 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><void>(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 <class T> 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 <string>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/reference.hpp>
|
||||
|
||||
// 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*& 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<char*>("OO"), &a1, &a2))
|
||||
return 0;
|
||||
|
||||
// Use boost::bind to make an object compatible with
|
||||
// boost::Function0<void>
|
||||
if (boost::python::handle_exception(
|
||||
boost::bind<void>(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<char*>("OO"), &a1, &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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
38
doc/v2/faq.html
Normal file
38
doc/v2/faq.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
166
doc/v2/from_python.html
Normal file
166
doc/v2/from_python.html
Normal file
@@ -0,0 +1,166 @@
|
||||
<!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 - <boost/python/from_python.hpp></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 <boost/python/from_python.hpp></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><boost/python/from_python.hpp></code> introduces a class
|
||||
template <code>from_python<T></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<class T></code></h3>
|
||||
|
||||
<p><code>from_python<T></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 <class T>
|
||||
struct from_python : private <a href=
|
||||
"../../../utility/utility.htm#Class noncopyable">boost::noncopyable</a> // Exposition only.
|
||||
// from_python<T> 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<></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 <string>
|
||||
#include <boost/python/from_python.hpp>
|
||||
|
||||
// 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<std::string> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
288
doc/v2/header.html
Normal file
288
doc/v2/header.html
Normal file
@@ -0,0 +1,288 @@
|
||||
<!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 - <{{header}}></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 <{{header}}></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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
41
doc/v2/index.html
Normal file
41
doc/v2/index.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
279
doc/v2/lvalue_from_python.html
Normal file
279
doc/v2/lvalue_from_python.html
Normal file
@@ -0,0 +1,279 @@
|
||||
<!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 - <boost/python/lvalue_from_python.hpp></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 <boost/python/lvalue_from_python.hpp></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><boost/python/lvalue_from_python.hpp></code> supplies
|
||||
a facility for extracting C++ objects from within instances of a
|
||||
given Python type. This is typically useful for dealing with
|
||||
"traditional" 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&</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& 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 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 <
|
||||
PyTypeObject const* python_type
|
||||
, class Value
|
||||
, class PythonObject = Value
|
||||
, class Extract = <i>unspecified</i>
|
||||
>
|
||||
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&</code>, <code>Value const&</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 <class Class, class Member, Member (Class::*mp)>
|
||||
struct get_member
|
||||
{
|
||||
static Member& execute(Class& c);
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="get_member-spec-statics"></a>Class template <code>get_member</code> static functions</h4>
|
||||
<pre>
|
||||
Member& execute(Class& 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 <boost/python/reference.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
|
||||
// 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("noddy_cache")
|
||||
.def("is_cached", is_cached)
|
||||
.def("set_cache", set_cache)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python code</h3>
|
||||
|
||||
<pre>
|
||||
>>> import noddy
|
||||
>>> n = noddy.new_noddy()
|
||||
>>> import noddy_cache
|
||||
>>> noddy_cache.is_cached(n)
|
||||
0
|
||||
>>> noddy_cache.set_cache(n)
|
||||
>>> noddy_cache.is_cached(n)
|
||||
1
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
146
doc/v2/make_function.html
Normal file
146
doc/v2/make_function.html
Normal file
@@ -0,0 +1,146 @@
|
||||
<!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 - <boost/python/make_function.hpp></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 <boost/python/make_function.hpp></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_<>::<a href=
|
||||
"class.html#class_-spec-modifiers">def</a></code>, <code>class_<>::<a
|
||||
href="module.html#module-spec-modifiers">def</a></code>, and
|
||||
<code>class_<>::<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 <class F></a>
|
||||
objects::function* make_function(F f)</a>
|
||||
|
||||
template <class F, class Policies>
|
||||
objects::function* make_function(F f, Policies const& 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 <class T, class ArgList, class Generator>
|
||||
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<T>::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<T>::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 <boost/python/make_function.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
|
||||
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>
|
||||
>>> from make_function_test import *
|
||||
>>> f = choose_function(1)
|
||||
>>> g = choose_function(0)
|
||||
>>> f()
|
||||
'foo'
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
130
doc/v2/manage_new_object.html
Normal file
130
doc/v2/manage_new_object.html
Normal file
@@ -0,0 +1,130 @@
|
||||
<!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 - <boost/python/manage_new_object.hpp></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
|
||||
<boost/python/manage_new_object.hpp></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 <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="manage_new_object-spec-metafunctions"></a>Class
|
||||
<code>manage_new_object</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> 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><T>
|
||||
type;</code>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<p>In C++:
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/manage_new_object.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
|
||||
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_<Foo>()
|
||||
.def("get_x", &Foo::get_x)
|
||||
)
|
||||
}
|
||||
</pre>
|
||||
In Python:
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> f = make_foo(3) # create a Foo object
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
262
doc/v2/module.html
Normal file
262
doc/v2/module.html
Normal file
@@ -0,0 +1,262 @@
|
||||
<!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 - <boost/python/module.hpp></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 <boost/python/module.hpp></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& setattr(const char* name, PyObject*);
|
||||
module& setattr(const char* name, PyTypeObject*);
|
||||
module& setattr(const char* name, ref const&);
|
||||
|
||||
module& add(PyTypeObject* x);
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
module& add(class_<T,Bases,HolderGenerator> const& c);
|
||||
|
||||
template <class Fn>
|
||||
module& def(char const* name, Fn fn);
|
||||
template <class Fn, class ResultHandler>
|
||||
module& 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& setattr(const char* name, PyObject* obj);
|
||||
module& setattr(const char* name, PyTypeObject* obj);
|
||||
module& setattr(const char* name, ref const& 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& add(PyTypeObject* x);
|
||||
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
module& add(class_<T,Bases,HolderGenerator> const& 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 <class Fn>
|
||||
module& def(char const* name, Fn f);
|
||||
|
||||
template <class Fn, class ResultHandler>
|
||||
module& 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 <boost/python/module.hpp>
|
||||
|
||||
char const* greet()
|
||||
{
|
||||
return "hello, Boost.Python!";
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(boost_greet)
|
||||
{
|
||||
module("boost_greet")
|
||||
.def("greet", greet);
|
||||
}
|
||||
</pre>
|
||||
|
||||
Interactive Python:
|
||||
<pre>
|
||||
>>> import boost_greet
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
47
doc/v2/overview.html
Normal file
47
doc/v2/overview.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
47
doc/v2/rationale.html
Normal file
47
doc/v2/rationale.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<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>© Copyright <a href="../../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
383
doc/v2/reference.html
Normal file
383
doc/v2/reference.html
Normal file
@@ -0,0 +1,383 @@
|
||||
<!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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
161
doc/v2/reference_existing_object.html
Normal file
161
doc/v2/reference_existing_object.html
Normal file
@@ -0,0 +1,161 @@
|
||||
<!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 -
|
||||
<boost/python/reference_existing_object.hpp></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
|
||||
<boost/python/reference_existing_object.hpp></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 <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="reference_existing_object-spec-metafunctions"></a>Class
|
||||
<code>reference_existing_object</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> struct apply
|
||||
</pre>
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is <code>U&</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><T,V>
|
||||
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 <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/reference_existing_object.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <utility>
|
||||
|
||||
// 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& 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_<Singleton>()
|
||||
.def("exchange", &Singleton::exchange)
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
In Python:
|
||||
<pre>
|
||||
>>> import singleton
|
||||
>>> s1 = singleton.get_it()
|
||||
>>> s2 = singleton.get_it()
|
||||
>>> id(s1) == id(s2) # s1 and s2 are not the same object
|
||||
0
|
||||
>>> s1.exchange(42) # but they reference the same C++ Singleton
|
||||
0
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
210
doc/v2/return_internal_reference.html
Normal file
210
doc/v2/return_internal_reference.html
Normal file
@@ -0,0 +1,210 @@
|
||||
<!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 - <boost/python/return_internal_reference.hpp></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 <boost/python/return_internal_reference.hpp></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 <std::size_t owner_arg = 1, class Base = default_call_policies>
|
||||
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 <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/return_internal_reference.hpp>
|
||||
|
||||
class Bar
|
||||
{
|
||||
Bar(int x) : x(x) {}
|
||||
int get_x() const { return x; }
|
||||
void set_x(int x) { this->x = x; }
|
||||
private:
|
||||
int x;
|
||||
}
|
||||
|
||||
class Foo
|
||||
{
|
||||
public:
|
||||
Foo(int x) : b(x) {}
|
||||
|
||||
// Returns an internal reference
|
||||
Bar const& get_bar() const { return b; }
|
||||
|
||||
private:
|
||||
Bar b;
|
||||
};
|
||||
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE_INIT(internal_refs)
|
||||
{
|
||||
module m("internal_refs")
|
||||
.add(
|
||||
class_<Bar>()
|
||||
.def("get_x", &Bar::get_x)
|
||||
.def("set_x", &Bar::set_x)
|
||||
)
|
||||
.add(
|
||||
class_<Foo>()
|
||||
.def_init(args<int>())
|
||||
.def("get_bar", &Foo::get_bar
|
||||
, return_internal_reference<>())
|
||||
)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python code</h3>
|
||||
|
||||
<pre>
|
||||
>>> from internal_refs import *
|
||||
>>> f = Foo(3)
|
||||
>>> b1 = f.get_bar()
|
||||
>>> b2 = f.get_bar()
|
||||
>>> b1.get_x()
|
||||
3
|
||||
>>> b2.get_x()
|
||||
3
|
||||
>>> b1.set_x(42)
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
148
doc/v2/return_value_policy.html
Normal file
148
doc/v2/return_value_policy.html
Normal file
@@ -0,0 +1,148 @@
|
||||
<!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 - <boost/python/return_value_policy.hpp></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 <boost/python/return_value_policy.hpp></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 <class ResultConverterGenerator, class Base = default_call_policies>
|
||||
struct return_value_policy : Base
|
||||
{
|
||||
typedef ResultConverterGenerator result_converter;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<h3>C++ Module Definition</h3>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/copy_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
// classes to wrap
|
||||
struct Bar { int x; }
|
||||
|
||||
struct Foo {
|
||||
Foo(int x) : { b.x = x; }
|
||||
Bar const& 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_<Bar>()
|
||||
)
|
||||
.add(
|
||||
class_<Foo>()
|
||||
.def_init(args<int>())
|
||||
.def("get_bar", &Foo::get_bar
|
||||
, return_value_policy<copy_const_reference>())
|
||||
)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
<h3>Python Code</h3>
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> f = Foo(3) # create a Foo object
|
||||
>>> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
189
doc/v2/to_python_converter.html
Normal file
189
doc/v2/to_python_converter.html
Normal file
@@ -0,0 +1,189 @@
|
||||
<!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 - <boost/python/to_python_converter.hpp></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 <boost/python/to_python_converter.hpp></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* p = Conversion::convert(x)</code>,<br>
|
||||
if <code>p == 0</code>, <code><a href="http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>() != 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 <class T, class Conversion>
|
||||
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>"noddy.h"</code>. Because
|
||||
<code>noddy_NoddyObject</code> is the ultimate trivial extension type,
|
||||
the example is a bit contrived: it wraps a function for which all
|
||||
information is contained in the <i>type</i> of its return value.
|
||||
|
||||
<h3>C++ module definition</h3>
|
||||
|
||||
<pre>
|
||||
#include <boost/python/reference.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include "noddy.h"
|
||||
|
||||
struct tag {};
|
||||
tag make_tag() { return tag(); }
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct tag_to_noddy
|
||||
{
|
||||
static PyObject* convert(tag const& x)
|
||||
{
|
||||
return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(to_python_converter)
|
||||
{
|
||||
module to_python("to_python_converter")
|
||||
.def("make_tag", make_tag)
|
||||
;
|
||||
to_python_converter<tag, tag_to_noddy>();
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python code</h3>
|
||||
|
||||
<pre>
|
||||
>>> import to_python_converter
|
||||
>>> def always_none():
|
||||
... return None
|
||||
...
|
||||
>>> def choose_function(x):
|
||||
... if (x % 2 != 0):
|
||||
... return to_python_converter.make_tag
|
||||
... else:
|
||||
... return always_none
|
||||
...
|
||||
>>> a = [ choose_function(x) for x in range(5) ]
|
||||
>>> b = [ f() for f in a ]
|
||||
>>> type(b[0])
|
||||
<type 'NoneType'>
|
||||
>>> type(b[1])
|
||||
<type 'Noddy'>
|
||||
>>> type(b[2])
|
||||
<type 'NoneType'>
|
||||
>>> type(b[3])
|
||||
<type 'Noddy'>
|
||||
</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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
194
doc/v2/to_python_indirect.html
Normal file
194
doc/v2/to_python_indirect.html
Normal file
@@ -0,0 +1,194 @@
|
||||
<!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 - <boost/python/to_python_indirect.hpp></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 <boost/python/to_python_indirect.hpp></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><boost/python/to_python_indirect.hpp></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> <i>cv</i><code>&</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&</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 <class T, class MakeHolder>
|
||||
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 <class T>
|
||||
static result_type execute(T* p)
|
||||
{
|
||||
return new boost::python::objects::pointer_holder<T*, T>(p);
|
||||
}
|
||||
};
|
||||
|
||||
struct reference_existing_object
|
||||
{
|
||||
// metafunction returning the <a href="ResultConverter.html">ResultConverter</a>
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef boost::python::to_python_indirect<T,make_reference_holder> 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>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
@@ -16,10 +16,15 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
// 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
|
||||
|
||||
@@ -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& = Args())
|
||||
self& def_init(Args const&)
|
||||
{
|
||||
def("__init__", make_constructor<T,Args,HolderGenerator>());
|
||||
return *this;
|
||||
|
||||
@@ -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> > > > > >,
|
||||
boost::noncopyable
|
||||
private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
meta_class();
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// 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
|
||||
@@ -6,7 +6,9 @@
|
||||
#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 {
|
||||
|
||||
@@ -44,18 +46,22 @@ 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*, PyString_FromString(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : detail::none())
|
||||
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)
|
||||
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()))
|
||||
|
||||
namespace converter
|
||||
{
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
// 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
|
||||
25
include/boost/python/converter/find_from_python.hpp
Normal file
25
include/boost/python/converter/find_from_python.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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
|
||||
@@ -6,192 +6,282 @@
|
||||
#ifndef FROM_PYTHON_DWA2002127_HPP
|
||||
# define FROM_PYTHON_DWA2002127_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/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.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/converter/from_python_data.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// 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
|
||||
struct from_python_base
|
||||
{
|
||||
from_python_converter_base(type_id_t, from_python_check); // registers
|
||||
public: // member functions
|
||||
from_python_base(void* result);
|
||||
from_python_base(PyObject*, lvalue_from_python_registration const* chain);
|
||||
bool convertible() const;
|
||||
|
||||
protected: // member functions
|
||||
void*const& result() const;
|
||||
|
||||
private: // data members
|
||||
void* m_result;
|
||||
};
|
||||
|
||||
// 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);
|
||||
// Used when T == U*const&
|
||||
template <class T>
|
||||
struct pointer_const_reference_from_python
|
||||
{
|
||||
pointer_const_reference_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
bool convertible() const;
|
||||
|
||||
private:
|
||||
from_python_check m_convertible;
|
||||
from_python_converter_base* m_next;
|
||||
typename detail::referent_storage<T>::type m_result;
|
||||
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
|
||||
// Used when T == U*
|
||||
template <class T>
|
||||
struct from_python_converter : from_python_converter_base
|
||||
struct pointer_from_python : from_python_base
|
||||
{
|
||||
public: // types
|
||||
typedef typename from_python_function<T>::type conversion_function;
|
||||
pointer_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
|
||||
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
|
||||
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;
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
// Initialized to refer to a common place in the registry.
|
||||
// Used when T == U& and (T != V const& or T == W volatile&)
|
||||
template <class T>
|
||||
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
|
||||
struct reference_from_python : from_python_base
|
||||
{
|
||||
public: // types
|
||||
reference_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
|
||||
public: // member functions
|
||||
from_python_lookup(PyObject* source);
|
||||
~from_python_lookup();
|
||||
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;
|
||||
T operator()(PyObject*);
|
||||
|
||||
public: // functions for use by conversion implementations
|
||||
// Get the converter object
|
||||
from_python_converter<T> const* converter() const;
|
||||
|
||||
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;
|
||||
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;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline void* from_python_converter_base::convertible(PyObject* o) const
|
||||
inline from_python_base::from_python_base(void* result)
|
||||
: m_result(result)
|
||||
{
|
||||
return m_convertible(o);
|
||||
}
|
||||
|
||||
inline from_python_converter_base const*
|
||||
from_python_converter_base::find(
|
||||
from_python_converter_base const* chain, PyObject* p, void*& data)
|
||||
inline from_python_base::from_python_base(
|
||||
PyObject* source
|
||||
, lvalue_from_python_registration const* chain)
|
||||
: m_result(find(source, chain))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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)
|
||||
inline pointer_const_reference_from_python<T>::pointer_const_reference_from_python(PyObject* p)
|
||||
{
|
||||
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>
|
||||
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;
|
||||
}
|
||||
rvalue_from_python_registration*& rvalue_from_python<T>::chain
|
||||
= registry::rvalue_converters(undecorated_type_id<T>());
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
|
||||
@@ -9,26 +9,22 @@
|
||||
# include <boost/python/detail/char_array.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type.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>
|
||||
|
||||
// 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;
|
||||
@@ -74,8 +70,8 @@ namespace detail
|
||||
|
||||
template <class T> struct referent_size
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t));
|
||||
static T f();
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f()));
|
||||
};
|
||||
|
||||
# endif
|
||||
@@ -111,36 +107,31 @@ namespace detail
|
||||
bool, choose_t2 = (
|
||||
aligned2 && (
|
||||
is_same<T1,unknown_alignment>::value
|
||||
| (align2 < alignment_of<T1>::value)
|
||||
| (align2 < align1)
|
||||
| (sizeof(T2) < sizeof(T1)))
|
||||
));
|
||||
|
||||
typedef mpl::select_type<choose_t2, T2, T1>::type type;
|
||||
typedef typename 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>
|
||||
struct aligned_storage
|
||||
union aligned_storage
|
||||
{
|
||||
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)];
|
||||
};
|
||||
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)];
|
||||
};
|
||||
|
||||
template <class Reference>
|
||||
@@ -151,56 +142,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 anyway
|
||||
typedef double align_t;
|
||||
#endif
|
||||
// maximal alignment, but that fails on some platforms
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, target_align = alignment_of<referent>::value);
|
||||
|
||||
// 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 from_python_intermediate_data
|
||||
struct rvalue_data
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_reference<T>::value, T, void>::type just_reference_t;
|
||||
|
||||
typedef detail::intermediate_data<just_reference_t> type;
|
||||
rvalue_stage1_data stage1;
|
||||
|
||||
typename detail::referent_storage<
|
||||
typename add_reference<T>::type
|
||||
>::type storage;
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
@@ -10,13 +10,8 @@
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct from_python_data;
|
||||
|
||||
template <class T>
|
||||
struct from_python_function
|
||||
{
|
||||
typedef T (*type)(PyObject*, from_python_data&);
|
||||
};
|
||||
struct rvalue_stage1_data;
|
||||
typedef void (*constructor_function)(PyObject* source, rvalue_stage1_data*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
|
||||
21
include/boost/python/converter/from_python_stage1_data.hpp
Normal file
21
include/boost/python/converter/from_python_stage1_data.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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
|
||||
69
include/boost/python/converter/pointer_type_id.hpp
Normal file
69
include/boost/python/converter/pointer_type_id.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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
|
||||
28
include/boost/python/converter/registrations.hpp
Normal file
28
include/boost/python/converter/registrations.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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
|
||||
@@ -9,20 +9,33 @@
|
||||
# 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 BOOST_PYTHON_DECL from_python_converter_base;
|
||||
struct lvalue_from_python_registration;
|
||||
struct rvalue_from_python_registration;
|
||||
|
||||
// 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);
|
||||
|
||||
BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(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 PyTypeObject*& class_object(undecorated_type_id_t key);
|
||||
}
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
// 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
|
||||
@@ -1,36 +0,0 @@
|
||||
// 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
|
||||
83
include/boost/python/detail/destroy.hpp
Normal file
83
include/boost/python/detail/destroy.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
// 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
|
||||
@@ -27,13 +27,14 @@ struct is_reference_to_const<T const&>
|
||||
template <class T>
|
||||
struct is_reference_to_non_const
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
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)
|
||||
);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
||||
44
include/boost/python/detail/module_base.hpp
Normal file
44
include/boost/python/detail/module_base.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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
@@ -28,6 +28,13 @@ 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>
|
||||
|
||||
@@ -7,15 +7,14 @@
|
||||
# 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::from_python_lookup<typename converter::target<T>::type>
|
||||
: converter::select_from_python<T>::type
|
||||
{
|
||||
typedef converter::from_python_lookup<typename converter::target<T>::type> base;
|
||||
typedef typename converter::select_from_python<T>::type base;
|
||||
from_python(PyObject*);
|
||||
};
|
||||
|
||||
@@ -28,6 +27,14 @@ 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
|
||||
//
|
||||
|
||||
@@ -8,36 +8,14 @@
|
||||
|
||||
# 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 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
|
||||
class module : public detail::module_base
|
||||
{
|
||||
public:
|
||||
module(const char* name)
|
||||
@@ -76,11 +54,6 @@ class module : public 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);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#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>
|
||||
@@ -26,7 +25,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 : noncopyable
|
||||
struct BOOST_PYTHON_DECL class_base : private noncopyable
|
||||
{
|
||||
// constructor
|
||||
class_base(
|
||||
@@ -44,7 +43,7 @@ struct BOOST_PYTHON_DECL class_base : noncopyable
|
||||
};
|
||||
|
||||
// Base class for all holders
|
||||
struct BOOST_PYTHON_DECL instance_holder : noncopyable
|
||||
struct BOOST_PYTHON_DECL instance_holder : private noncopyable
|
||||
{
|
||||
public:
|
||||
instance_holder();
|
||||
@@ -53,7 +52,7 @@ struct BOOST_PYTHON_DECL instance_holder : noncopyable
|
||||
// return the next holder in a chain
|
||||
instance_holder* next() const;
|
||||
|
||||
virtual void* holds(converter::type_id_t) = 0;
|
||||
virtual void* holds(converter::undecorated_type_id_t) = 0;
|
||||
|
||||
void install(PyObject* inst) throw();
|
||||
|
||||
@@ -85,15 +84,19 @@ struct instance
|
||||
instance_holder* objects;
|
||||
};
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
// This produces a function with the right signature for use in from_python conversions
|
||||
template <class T>
|
||||
T* find_instance(PyObject* p, T* = 0)
|
||||
struct instance_finder
|
||||
{
|
||||
return static_cast<T*>(find_instance_impl(p, converter::type_id<T>()));
|
||||
}
|
||||
static inline void* execute(PyObject* p)
|
||||
{
|
||||
return find_instance_impl(p, converter::undecorated_type_id<T>());
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_DECL ref class_metatype();
|
||||
BOOST_PYTHON_DECL ref class_type();
|
||||
|
||||
@@ -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,7 +24,6 @@ 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;
|
||||
};
|
||||
|
||||
@@ -90,6 +89,10 @@ 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>();
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ struct pointer_holder : instance_holder
|
||||
{}
|
||||
|
||||
private: // required holder implementation
|
||||
void* holds(converter::type_id_t);
|
||||
void* holds(converter::undecorated_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::type_id_t dst_t)
|
||||
void* pointer_holder<Pointer, Value>::holds(converter::undecorated_type_id_t dst_t)
|
||||
{
|
||||
if (dst_t == converter::type_id<Pointer>())
|
||||
if (dst_t == converter::undecorated_type_id<Pointer>())
|
||||
return &this->m_p;
|
||||
|
||||
converter::type_id_t src_t = converter::type_id<Value>();
|
||||
converter::type_id_t src_t = converter::undecorated_type_id<Value>();
|
||||
return src_t == dst_t ? &*this->m_p
|
||||
: find_dynamic_type(&*this->m_p, src_t, dst_t);
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ struct value_holder : instance_holder
|
||||
{}
|
||||
|
||||
private: // required holder implementation
|
||||
void* holds(converter::type_id_t);
|
||||
void* holds(converter::undecorated_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::type_id_t dst_t)
|
||||
void* value_holder<Held>::holds(converter::undecorated_type_id_t dst_t)
|
||||
{
|
||||
converter::type_id_t src_t = converter::type_id<Held>();
|
||||
converter::undecorated_type_id_t src_t = converter::undecorated_type_id<Held>();
|
||||
return src_t == dst_t ? &m_held
|
||||
: find_static_type(&m_held, src_t, dst_t);
|
||||
}
|
||||
|
||||
@@ -1,62 +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 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
|
||||
@@ -7,41 +7,34 @@
|
||||
# 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 <class T>
|
||||
struct return_internal_reference_requires_a_pointer_or_reference_return_type
|
||||
template <std::size_t>
|
||||
struct return_internal_reference_owner_arg_must_be_greater_than_zero
|
||||
# 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>
|
||||
{
|
||||
typedef reference_existing_object result_converter;
|
||||
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;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class Handler, class Base = default_call_policies>
|
||||
template <class ResultConverterGenerator, class Base = default_call_policies>
|
||||
struct return_value_policy : Base
|
||||
{
|
||||
typedef Handler result_converter;
|
||||
typedef ResultConverterGenerator result_converter;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T, class Derived>
|
||||
template <class T, class Conversion>
|
||||
struct to_python_converter
|
||||
{
|
||||
to_python_converter();
|
||||
@@ -22,11 +22,11 @@ struct to_python_converter
|
||||
// implementation
|
||||
//
|
||||
|
||||
template <class T, class Derived>
|
||||
to_python_converter<T,Derived>::to_python_converter()
|
||||
template <class T, class Conversion>
|
||||
to_python_converter<T,Conversion>::to_python_converter()
|
||||
{
|
||||
typedef converter::as_to_python_value_function<
|
||||
T, Derived
|
||||
T, Conversion
|
||||
> normalized;
|
||||
|
||||
converter::registry::insert(
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
# 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 HolderGenerator>
|
||||
template <class T, class MakeHolder>
|
||||
struct to_python_indirect
|
||||
{
|
||||
static bool convertible();
|
||||
@@ -34,8 +35,15 @@ namespace detail
|
||||
template <class T>
|
||||
static result_type execute(T* p)
|
||||
{
|
||||
return new objects::pointer_holder<std::auto_ptr<T>, T>(
|
||||
std::auto_ptr<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));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -61,14 +69,14 @@ namespace detail
|
||||
};
|
||||
}
|
||||
|
||||
template <class T, class HolderGenerator>
|
||||
inline bool to_python_indirect<T,HolderGenerator>::convertible()
|
||||
template <class T, class MakeHolder>
|
||||
inline bool to_python_indirect<T,MakeHolder>::convertible()
|
||||
{
|
||||
return type() != 0;
|
||||
}
|
||||
|
||||
template <class T, class HolderGenerator>
|
||||
inline PyObject* to_python_indirect<T,HolderGenerator>::operator()(T x) const
|
||||
template <class T, class MakeHolder>
|
||||
inline PyObject* to_python_indirect<T,MakeHolder>::operator()(T x) const
|
||||
{
|
||||
PyObject* raw_result = type()->tp_alloc(type(), 0);
|
||||
|
||||
@@ -82,7 +90,7 @@ inline PyObject* to_python_indirect<T,HolderGenerator>::operator()(T x) const
|
||||
// Build a value_holder to contain the object using the copy
|
||||
// constructor
|
||||
objects::instance_holder* p =
|
||||
detail::unwind_type<HolderGenerator>(x);
|
||||
detail::unwind_type<MakeHolder>(x);
|
||||
|
||||
// Install it in the instance
|
||||
p->install(raw_result);
|
||||
@@ -91,8 +99,8 @@ inline PyObject* to_python_indirect<T,HolderGenerator>::operator()(T x) const
|
||||
return result.release();
|
||||
}
|
||||
|
||||
template <class T, class HolderGenerator>
|
||||
inline PyTypeObject* to_python_indirect<T,HolderGenerator>::type()
|
||||
template <class T, class MakeHolder>
|
||||
inline PyTypeObject* to_python_indirect<T,MakeHolder>::type()
|
||||
{
|
||||
return detail::unwind_type<detail::get_pointer_class,T>();
|
||||
}
|
||||
|
||||
@@ -6,15 +6,94 @@
|
||||
#ifndef TYPE_FROM_PYTHON_DWA2002130_HPP
|
||||
# define TYPE_FROM_PYTHON_DWA2002130_HPP
|
||||
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <PyTypeObject const* python_type>
|
||||
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>
|
||||
struct type_from_python
|
||||
{
|
||||
static void* convertible(PyObject* op)
|
||||
type_from_python()
|
||||
{
|
||||
return PyObject_TypeCheck(
|
||||
op, const_cast<PyTypeObject*>(python_type)) ? op : 0;
|
||||
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
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,73 +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 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
|
||||
@@ -1,18 +0,0 @@
|
||||
// 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
|
||||
@@ -7,221 +7,259 @@
|
||||
#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
|
||||
{
|
||||
// Only an object which we know is holding a char const* can be
|
||||
// converted to one
|
||||
struct convertible_to_cstring
|
||||
// An lvalue conversion function which extracts a char const* from a
|
||||
// Python String.
|
||||
void* convert_to_cstring(PyObject* obj)
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
return PyString_Check(obj) ? &obj->ob_type->tp_str : 0;
|
||||
}
|
||||
};
|
||||
return PyString_Check(obj) ? PyString_AsString(obj) : 0;
|
||||
}
|
||||
|
||||
struct extract_cstring
|
||||
// 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
|
||||
{
|
||||
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)
|
||||
slot_rvalue_from_python()
|
||||
{
|
||||
unaryfunc converter = *(unaryfunc*)data.stage1;
|
||||
ref converted(converter(obj));
|
||||
return TExtract::execute(converted.get());
|
||||
registry::insert(
|
||||
&slot_rvalue_from_python<T,SlotPolicy>::convertible
|
||||
, &slot_rvalue_from_python<T,SlotPolicy>::construct
|
||||
, undecorated_type_id<T>()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 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)
|
||||
static void* convertible(PyObject* obj)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
struct convertible_to_int
|
||||
// A SlotPolicy for extracting integer types from Python objects
|
||||
struct int_rvalue_from_python
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
static unaryfunc* get_slot(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 in
|
||||
// py_int_or_float_as_long, below
|
||||
if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float)
|
||||
// creating a new object. We'll handle that below
|
||||
if (PyFloat_Check(obj))
|
||||
return &number_methods->nb_float;
|
||||
|
||||
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 (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__int__"))
|
||||
return 0;
|
||||
|
||||
return &number_methods->nb_int;
|
||||
}
|
||||
|
||||
static long extract(PyObject* intermediate)
|
||||
{
|
||||
if (PyObject_TypeCheck(obj, &PyFloat_Type))
|
||||
if (PyFloat_Check(intermediate))
|
||||
{
|
||||
return numeric_cast<long>(PyFloat_AS_DOUBLE(obj));
|
||||
return numeric_cast<long>(PyFloat_AS_DOUBLE(intermediate));
|
||||
}
|
||||
else
|
||||
{
|
||||
return PyInt_AS_LONG(obj);
|
||||
return PyInt_AS_LONG(intermediate);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct convertible_to_double
|
||||
|
||||
// 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)
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
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)
|
||||
{
|
||||
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 in
|
||||
// py_float_or_int_as_double, below
|
||||
if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int)
|
||||
// creating a new object. We'll handle that below
|
||||
if (PyInt_Check(obj))
|
||||
return &number_methods->nb_int;
|
||||
|
||||
return number_methods && number_methods->nb_float
|
||||
? &number_methods->nb_float : 0;
|
||||
if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__float__"))
|
||||
return 0;
|
||||
|
||||
return &number_methods->nb_float;
|
||||
}
|
||||
};
|
||||
|
||||
struct py_float_or_int_as_double
|
||||
{
|
||||
static double execute(PyObject* obj)
|
||||
|
||||
static double extract(PyObject* intermediate)
|
||||
{
|
||||
if (PyObject_TypeCheck(obj, &PyInt_Type))
|
||||
if (PyInt_Check(intermediate))
|
||||
{
|
||||
return PyInt_AS_LONG(obj);
|
||||
return PyInt_AS_LONG(intermediate);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PyFloat_AS_DOUBLE(obj);
|
||||
return PyFloat_AS_DOUBLE(intermediate);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Convertible, class Convert>
|
||||
struct scalar_from_python
|
||||
// A SlotPolicy for extracting C++ strings from Python objects.
|
||||
struct string_rvalue_from_python
|
||||
{
|
||||
tp_cref_from_python<T,Convertible,Convert> cref_converter;
|
||||
tp_scalar_from_python<T,Convertible,Convert> value_converter;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void register_int_converters(T* = 0)
|
||||
{
|
||||
static scalar_from_python<T, convertible_to_int, py_int_or_float_as_long> x;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
};
|
||||
|
||||
#define REGISTER_INT_CONVERTERS(U) register_int_converters<U>()
|
||||
// Remember that this will be used to construct the result object
|
||||
static char const* extract(PyObject* intermediate)
|
||||
{
|
||||
return PyString_AsString(intermediate);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 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)
|
||||
{
|
||||
return PyObject_CallMethod(x, "__complex__", const_cast<char*>("()"));
|
||||
}
|
||||
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_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);
|
||||
|
||||
static scalar_from_python<
|
||||
float,convertible_to_double,py_float_or_int_as_double> float_from_python;
|
||||
// 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<
|
||||
double,convertible_to_double,py_float_or_int_as_double> double_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<
|
||||
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;
|
||||
// Add an lvalue converter for char which gets us char const*
|
||||
registry::insert(convert_to_cstring,undecorated_type_id<char>());
|
||||
|
||||
static tp_cref_from_python<
|
||||
std::string, convertible_to_string, extract_cstring> string_from_python;
|
||||
// Register by-value converters to std::string
|
||||
slot_rvalue_from_python<std::string, string_rvalue_from_python>();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
@@ -4,23 +4,40 @@
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/converter/from_python.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/converter/find_from_python.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/converter/from_python_data.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
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
|
||||
, rvalue_from_python_registration const* chain
|
||||
, rvalue_stage1_data& data)
|
||||
{
|
||||
// Insert this in the converter chain.
|
||||
from_python_converter_base*& head = registry::from_python_chain(type);
|
||||
m_next = head;
|
||||
head = this;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// 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
|
||||
@@ -4,6 +4,7 @@
|
||||
// "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>
|
||||
@@ -19,20 +20,23 @@ 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.
|
||||
from_python_converter_base* m_from_python_converters;
|
||||
lvalue_from_python_registration* m_lvalue_from_python;
|
||||
rvalue_from_python_registration* m_rvalue_from_python;
|
||||
|
||||
// The class object associated with this type
|
||||
PyTypeObject* m_class_object;
|
||||
};
|
||||
|
||||
typedef std::map<type_id_t, entry> registry_t;
|
||||
typedef std::map<undecorated_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)
|
||||
{
|
||||
@@ -42,17 +46,19 @@ namespace // <unnamed>
|
||||
|
||||
initialize_builtin_converters();
|
||||
}
|
||||
#endif
|
||||
return registry;
|
||||
}
|
||||
|
||||
entry* find(type_id_t type)
|
||||
entry* find(undecorated_type_id_t type)
|
||||
{
|
||||
return &entries()[type];
|
||||
}
|
||||
|
||||
entry::entry()
|
||||
: m_to_python_converter(0)
|
||||
, m_from_python_converters(0)
|
||||
, m_lvalue_from_python(0)
|
||||
, m_rvalue_from_python(0)
|
||||
, m_class_object(0)
|
||||
{
|
||||
}
|
||||
@@ -78,15 +84,46 @@ namespace registry
|
||||
slot = f;
|
||||
}
|
||||
|
||||
from_python_converter_base*& from_python_chain(type_id_t key)
|
||||
// Insert an lvalue from_python converter
|
||||
void insert(void* (*convert)(PyObject*), undecorated_type_id_t key)
|
||||
{
|
||||
return find(key)->m_from_python_converters;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// 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
|
||||
@@ -1,31 +0,0 @@
|
||||
// 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
|
||||
@@ -1,41 +0,0 @@
|
||||
// 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
|
||||
@@ -1,4 +1,4 @@
|
||||
# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
# (C) Copyright David Abrahams 2001,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.
|
||||
@@ -8,8 +8,8 @@
|
||||
from gen_function import *
|
||||
import string
|
||||
|
||||
header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
header = '''// (C) Copyright David Abrahams 2001,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.
|
||||
//
|
||||
@@ -24,11 +24,10 @@ 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 {
|
||||
|
||||
@@ -62,32 +61,49 @@ struct returning<void>
|
||||
|
||||
#'
|
||||
|
||||
member_function = ''' template <class A0%(, class A%+%)>
|
||||
static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args, PyObject* /* keywords */ )
|
||||
member_function = ''' template <class P, class A0%(, class A%+%)>
|
||||
static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args_, PyObject*, P const& policies)
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0%1&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
%( unwrap_more<A%+> c%+(PyTuple_GET_ITEM(args, %+), c%n);
|
||||
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;
|
||||
%)
|
||||
%[r%: // find the result converter
|
||||
wrap_more<R> r(c%n);
|
||||
%] if (!c0) return 0;
|
||||
%[r%:return r( %]((*c0).*pmf)(%(*c%+%:, %))%[r%: )%];%[v%:
|
||||
return detail::none();%]
|
||||
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()%]);
|
||||
}
|
||||
'''
|
||||
|
||||
free_function = '''%{ template <%(class A%n%:, %)>
|
||||
%} static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject*%{ args%}, PyObject* /* keywords */ )
|
||||
free_function = ''' template <class P%(, class A%n%%)>
|
||||
static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject* args_, PyObject*, P const& policies)
|
||||
{%{
|
||||
// check that each of the arguments is convertible
|
||||
%}%( 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();%]
|
||||
%}%( 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()%]);
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/detail/module_base.hpp>
|
||||
#include <boost/python/object/function.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
module_base::module_base(const char* name)
|
||||
: m_module(
|
||||
@@ -46,4 +47,4 @@ void module_base::add_type(ref x)
|
||||
|
||||
PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } };
|
||||
|
||||
}} // namespace boost::python
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
// 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/detail/config.hpp>
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/object/class.hpp>
|
||||
#include <boost/python/objects.hpp>
|
||||
#include <boost/python/detail/map_entry.hpp>
|
||||
@@ -45,8 +44,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 */
|
||||
@@ -119,8 +118,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 */
|
||||
@@ -163,7 +162,7 @@ void instance_holder::install(PyObject* self) throw()
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void*
|
||||
find_instance_impl(PyObject* inst, converter::type_id_t type)
|
||||
find_instance_impl(PyObject* inst, converter::undecorated_type_id_t type)
|
||||
{
|
||||
if (inst->ob_type->ob_type != &class_metatype_object)
|
||||
return 0;
|
||||
@@ -205,7 +204,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";
|
||||
|
||||
@@ -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
|
||||
: boost::noncopyable // our generation of to_python().
|
||||
class Foo // prohibit copying, proving that it doesn't choke
|
||||
: private boost::noncopyable // our generation of to_python().
|
||||
{
|
||||
public: // constructor/destructor
|
||||
Foo(int x) : m_x(x) {}
|
||||
|
||||
81
test/destroy_test.cpp
Normal file
81
test/destroy_test.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#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;
|
||||
}
|
||||
48
test/indirect_traits_test.cpp
Normal file
48
test/indirect_traits_test.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
//#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;
|
||||
}
|
||||
79
test/m1.cpp
79
test/m1.cpp
@@ -9,15 +9,13 @@
|
||||
#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>
|
||||
@@ -105,7 +103,6 @@ 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
|
||||
@@ -120,16 +117,13 @@ struct simple_to_python
|
||||
}
|
||||
};
|
||||
|
||||
int noddy_to_int(PyObject* p, from_python_data&)
|
||||
struct int_from_noddy_extractor
|
||||
{
|
||||
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;
|
||||
}
|
||||
static int& execute(NoddyObject& p)
|
||||
{
|
||||
return p.x;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Some C++ functions to expose to Python
|
||||
@@ -141,6 +135,26 @@ 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)
|
||||
{
|
||||
@@ -185,34 +199,24 @@ D take_d(D const& d) { return d; }
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(m1)
|
||||
{
|
||||
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 namespace boost::python;
|
||||
using boost::mpl::type_list;
|
||||
|
||||
// Create the converters; they are self-registering/unregistering.
|
||||
static simple_to_python c1;
|
||||
simple_to_python();
|
||||
|
||||
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);
|
||||
type_from_python<&NoddyType,int_from_noddy_extractor>();
|
||||
|
||||
static boost::python::reference_from_python<
|
||||
boost::python::type_from_python<
|
||||
&SimpleType
|
||||
, simple
|
||||
, SimpleObject
|
||||
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
, member_extractor<SimpleObject, simple, &SimpleObject::x>
|
||||
#else
|
||||
, extract_simple_object
|
||||
>
|
||||
unwrap_simple;
|
||||
#endif
|
||||
>();
|
||||
|
||||
type_from_python<&SimpleType, identity_extractor<SimpleObject> >();
|
||||
|
||||
module m1("m1");
|
||||
|
||||
typedef boost::python::objects::pointer_holder_generator<
|
||||
@@ -229,9 +233,14 @@ BOOST_PYTHON_MODULE_INIT(m1)
|
||||
.def("new_noddy", new_noddy)
|
||||
.def("new_simple", new_simple)
|
||||
|
||||
// Expose f()
|
||||
// Expose f() in all its variations
|
||||
.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>()
|
||||
)
|
||||
|
||||
@@ -57,6 +57,18 @@ 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.
|
||||
|
||||
|
||||
39
test/pointer_type_id_test.cpp
Normal file
39
test/pointer_type_id_test.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#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;
|
||||
}
|
||||
148
test/select_from_python_test.cpp
Normal file
148
test/select_from_python_test.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#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;
|
||||
}
|
||||
@@ -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,6 +29,7 @@ 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)
|
||||
@@ -40,10 +41,14 @@ 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)
|
||||
@@ -55,6 +60,9 @@ 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)
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
"""
|
||||
>>> 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)
|
||||
@@ -24,11 +30,24 @@
|
||||
>>> 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)
|
||||
@@ -45,6 +64,7 @@
|
||||
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
|
||||
@@ -52,11 +72,29 @@
|
||||
>>> 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)
|
||||
@@ -71,6 +109,27 @@ 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
|
||||
|
||||
Reference in New Issue
Block a user