mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 04:42:28 +00:00
Compare commits
434 Commits
boost-1.30
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c8f1fb5d3 | ||
|
|
d79c063b97 | ||
|
|
386bfcf20a | ||
|
|
61b03a8ce2 | ||
|
|
e163e0cc10 | ||
|
|
494bede2c0 | ||
|
|
183918be07 | ||
|
|
b9ff2f1a11 | ||
|
|
c7ad999adb | ||
|
|
04e16988ae | ||
|
|
272559c3be | ||
|
|
31bc1a4466 | ||
|
|
aa0dc52c94 | ||
|
|
dfcce0f2a9 | ||
|
|
182d9e9447 | ||
|
|
3c65122e1d | ||
|
|
7107628ae0 | ||
|
|
415016191a | ||
|
|
7430b7c4a6 | ||
|
|
d5c9831da8 | ||
|
|
1d295d7f11 | ||
|
|
0bc4ee884f | ||
|
|
bdde13d1bc | ||
|
|
887faad373 | ||
|
|
712b90dfe0 | ||
|
|
922a1b9194 | ||
|
|
3cadfa529e | ||
|
|
b5cd8c537f | ||
|
|
91db6f2d50 | ||
|
|
997467c29f | ||
|
|
2b127f9533 | ||
|
|
3bf081fcf9 | ||
|
|
a1da924e28 | ||
|
|
5a740d06c6 | ||
|
|
ef80b390cd | ||
|
|
e425a15fd2 | ||
|
|
1addeee962 | ||
|
|
f415f18574 | ||
|
|
5e6f06fde3 | ||
|
|
eaf784b024 | ||
|
|
4c4676db3e | ||
|
|
54114b2bd1 | ||
|
|
e2c58fcb7c | ||
|
|
c9de2a660f | ||
|
|
cbbc52e9d1 | ||
|
|
4e414c5371 | ||
|
|
0af5dc09c8 | ||
|
|
264ec8ddca | ||
|
|
5295f58aff | ||
|
|
88c03a6ef4 | ||
|
|
d9478fb117 | ||
|
|
d17ce4e588 | ||
|
|
06814a2251 | ||
|
|
cb26cf1a5b | ||
|
|
87217f8009 | ||
|
|
ecfd820d62 | ||
|
|
d91baaaa59 | ||
|
|
27bc69adbf | ||
|
|
0fd414f8cd | ||
|
|
5fc0aba562 | ||
|
|
b81435f4aa | ||
|
|
7482040832 | ||
|
|
2daf80f91e | ||
|
|
d3a25d2e72 | ||
|
|
a653c321f9 | ||
|
|
4f7abba608 | ||
|
|
b1a0f0a373 | ||
|
|
bb3887660e | ||
|
|
10bc8a3709 | ||
|
|
f57c10905a | ||
|
|
e39ede3116 | ||
|
|
b07d2e8591 | ||
|
|
d4ad3f55d5 | ||
|
|
324bba771c | ||
|
|
b032914876 | ||
|
|
43e1dc9d5b | ||
|
|
3847f1d455 | ||
|
|
5f9c0e5b50 | ||
|
|
1c5450292d | ||
|
|
2c93ea31dc | ||
|
|
89122d2415 | ||
|
|
20896e809d | ||
|
|
ba6cbe42de | ||
|
|
fbf82cc6e9 | ||
|
|
278bb1a861 | ||
|
|
82b1fd637d | ||
|
|
26d5ca22aa | ||
|
|
18279496da | ||
|
|
536ef11cce | ||
|
|
32f1d028e2 | ||
|
|
c7913267d4 | ||
|
|
73a65235c6 | ||
|
|
3267d5a2f3 | ||
|
|
e0ae98ee56 | ||
|
|
62a213fbbe | ||
|
|
1ddd2b800d | ||
|
|
9e593f1f79 | ||
|
|
237cce7dae | ||
|
|
55a33c287c | ||
|
|
f9ddcdf61b | ||
|
|
5c5ed38973 | ||
|
|
2ecb9c6232 | ||
|
|
7c14b3fac4 | ||
|
|
6b4d0a1119 | ||
|
|
05dd7bf52a | ||
|
|
125d2084df | ||
|
|
314dbcae33 | ||
|
|
e13f2f11db | ||
|
|
28ad5ff233 | ||
|
|
41bf4105c2 | ||
|
|
9c773b5387 | ||
|
|
4eb977b511 | ||
|
|
1dff9421dd | ||
|
|
ec7b352178 | ||
|
|
186693f710 | ||
|
|
d7a88b6f7e | ||
|
|
c8898caba0 | ||
|
|
9983782b2c | ||
|
|
87f1985463 | ||
|
|
13e118b0dd | ||
|
|
f7c034d510 | ||
|
|
2f68553e18 | ||
|
|
9980a5824e | ||
|
|
c3ac52a4a8 | ||
|
|
14a7d7fba4 | ||
|
|
7d77f80036 | ||
|
|
6eeb6e6650 | ||
|
|
0b1e457c77 | ||
|
|
3533bd0504 | ||
|
|
1a51a7df9e | ||
|
|
615be89951 | ||
|
|
912ca36a1f | ||
|
|
fba93805dc | ||
|
|
96d66f4624 | ||
|
|
c3bae63e41 | ||
|
|
6c22aceabc | ||
|
|
92a77dfe7f | ||
|
|
4f2dbeda28 | ||
|
|
bec2de08fe | ||
|
|
db192e1e01 | ||
|
|
454654a9cc | ||
|
|
1018bc56eb | ||
|
|
f920dc87d0 | ||
|
|
8b97caae46 | ||
|
|
3b74aab818 | ||
|
|
e78b4939b3 | ||
|
|
621b5fc2db | ||
|
|
6ada069d5a | ||
|
|
50db384be1 | ||
|
|
ae7225ae83 | ||
|
|
911ba333a2 | ||
|
|
5cd8cce531 | ||
|
|
6a2a76cea9 | ||
|
|
7a9a3d30c9 | ||
|
|
034ca4d5eb | ||
|
|
00e3fa32fb | ||
|
|
0133bdfbe3 | ||
|
|
e563def5ba | ||
|
|
b3910f4e4d | ||
|
|
4a7b8fe839 | ||
|
|
fc56544da4 | ||
|
|
c839d25722 | ||
|
|
c6b5ecbbdb | ||
|
|
d3473afa23 | ||
|
|
379b28eb85 | ||
|
|
7f5bd33ead | ||
|
|
eef6fb9891 | ||
|
|
4a7f52ab2c | ||
|
|
10b249a162 | ||
|
|
5fc5fce663 | ||
|
|
f00fe3c0b1 | ||
|
|
3047d51613 | ||
|
|
f9f7146960 | ||
|
|
ca9dc3103a | ||
|
|
c03afa379c | ||
|
|
cbacc98e3f | ||
|
|
84daf14f1b | ||
|
|
4af28b2a46 | ||
|
|
acbc01933c | ||
|
|
7ec78eecbd | ||
|
|
87c5e37f5e | ||
|
|
d02959e3ed | ||
|
|
b844d8b750 | ||
|
|
0a3010b29f | ||
|
|
2b380d03c9 | ||
|
|
3f70253a3f | ||
|
|
165e294298 | ||
|
|
f7c9f45508 | ||
|
|
af2a924301 | ||
|
|
3981e83de5 | ||
|
|
88b9721e3f | ||
|
|
4946af1448 | ||
|
|
9959dcfa49 | ||
|
|
cfb13fad22 | ||
|
|
4e3f3a052d | ||
|
|
dc7ae9ed20 | ||
|
|
929badf4c6 | ||
|
|
c4a3f2c04f | ||
|
|
a933e458b3 | ||
|
|
06b8320815 | ||
|
|
7f3aceafd2 | ||
|
|
da5979931c | ||
|
|
d8c7e75095 | ||
|
|
187506c97f | ||
|
|
145c6d1e4f | ||
|
|
e2973f27f9 | ||
|
|
976b8180ae | ||
|
|
37acf41d43 | ||
|
|
6f26778491 | ||
|
|
834d815c87 | ||
|
|
57e58c445b | ||
|
|
8a1a8342d6 | ||
|
|
fa70ddc2c5 | ||
|
|
8ca32bb494 | ||
|
|
f6c82eba0c | ||
|
|
344044a315 | ||
|
|
b10805dc4c | ||
|
|
07f397e2ed | ||
|
|
054dc439d2 | ||
|
|
5008dcbdd4 | ||
|
|
9c6650963f | ||
|
|
d482d57689 | ||
|
|
edf6516085 | ||
|
|
957ac66e14 | ||
|
|
07ce84c4e7 | ||
|
|
918636ff03 | ||
|
|
83a6adbfa9 | ||
|
|
fcbc1d562f | ||
|
|
c3b4b58075 | ||
|
|
568b62a8a4 | ||
|
|
da34e7f507 | ||
|
|
a0c31b47e5 | ||
|
|
5fb677c0c5 | ||
|
|
168476382a | ||
|
|
7fa6a29814 | ||
|
|
f2b51da0ab | ||
|
|
53726746b8 | ||
|
|
fe0b59f559 | ||
|
|
c014dee6dc | ||
|
|
90c69d961e | ||
|
|
342f7db678 | ||
|
|
9eb704f85a | ||
|
|
7754a91929 | ||
|
|
e4dc639e54 | ||
|
|
5d90101671 | ||
|
|
437fb70852 | ||
|
|
d598404c48 | ||
|
|
32c7088600 | ||
|
|
ccede29816 | ||
|
|
b55b7e2f7b | ||
|
|
9217a6a253 | ||
|
|
07c1319b99 | ||
|
|
714b5dc26e | ||
|
|
1f715958f9 | ||
|
|
0922aca873 | ||
|
|
30ec6181b5 | ||
|
|
b28d586612 | ||
|
|
f48aacf477 | ||
|
|
bfa868a440 | ||
|
|
f01ff3a277 | ||
|
|
d88e6bf688 | ||
|
|
a3cdacd088 | ||
|
|
81d99c855f | ||
|
|
5cd110f625 | ||
|
|
416895ff30 | ||
|
|
e41abb6e92 | ||
|
|
a6440a3fa6 | ||
|
|
2dece7ecaf | ||
|
|
7aae525587 | ||
|
|
ac5314093b | ||
|
|
1524fb9fa9 | ||
|
|
957549460b | ||
|
|
3b33f54fb8 | ||
|
|
42ab6b6b66 | ||
|
|
f59a5bbabc | ||
|
|
0be371d747 | ||
|
|
2b52210291 | ||
|
|
96a7bce78e | ||
|
|
c1e1ea697c | ||
|
|
874d6ebf2c | ||
|
|
77f5eb703c | ||
|
|
af53ae8329 | ||
|
|
8f76b8880e | ||
|
|
fa398734be | ||
|
|
362d20a8c7 | ||
|
|
6a33b8aeeb | ||
|
|
d4e06ac436 | ||
|
|
817dcd37e0 | ||
|
|
25bfd3c50f | ||
|
|
b13c902fb0 | ||
|
|
c95ef44b02 | ||
|
|
162727590c | ||
|
|
7e159844fb | ||
|
|
787b79cc2c | ||
|
|
b77652b499 | ||
|
|
0c8444b8ed | ||
|
|
3e6ee799ba | ||
|
|
dd14ccb115 | ||
|
|
ba0fcd27c3 | ||
|
|
d476e67067 | ||
|
|
4588f5e9ab | ||
|
|
68f54d364b | ||
|
|
7dba18e7b9 | ||
|
|
67b265fe96 | ||
|
|
8289269a86 | ||
|
|
9f711ed821 | ||
|
|
73e2ab5125 | ||
|
|
7ea2ab1672 | ||
|
|
c821e903f8 | ||
|
|
54db04521a | ||
|
|
91fdecd76f | ||
|
|
f140a74a13 | ||
|
|
4854a2a81b | ||
|
|
d94bb65006 | ||
|
|
6ca5280b2c | ||
|
|
5da3e1deea | ||
|
|
1ae85d0e39 | ||
|
|
256e3a467c | ||
|
|
4477fe4dd6 | ||
|
|
5d1e245858 | ||
|
|
ec750a44c9 | ||
|
|
006f1d9802 | ||
|
|
638b3d4ee1 | ||
|
|
a1cc1651fa | ||
|
|
9fe141f5ad | ||
|
|
d52f0c7d40 | ||
|
|
bb55c4a855 | ||
|
|
f1a06b14de | ||
|
|
286f3dc093 | ||
|
|
a731322782 | ||
|
|
0db07ec25e | ||
|
|
bc112ba65f | ||
|
|
62ba322658 | ||
|
|
02135b550d | ||
|
|
ee4b06bb50 | ||
|
|
16c5435ca8 | ||
|
|
2595049748 | ||
|
|
5911691c0d | ||
|
|
e369bddc84 | ||
|
|
dccf2bbb4a | ||
|
|
eaab3fc038 | ||
|
|
858e1aba67 | ||
|
|
19eff7791d | ||
|
|
c81af4ffe0 | ||
|
|
9675e4233b | ||
|
|
e6a176bb1e | ||
|
|
ff0980914b | ||
|
|
43e5ccd0a7 | ||
|
|
66d6272942 | ||
|
|
2f1b828967 | ||
|
|
622636dcf1 | ||
|
|
0c22c276bf | ||
|
|
7a4a79c74e | ||
|
|
06f454e1d3 | ||
|
|
c1dbd52de1 | ||
|
|
c3f5679188 | ||
|
|
97e2628f95 | ||
|
|
6cecfcb704 | ||
|
|
022a5a16f5 | ||
|
|
a39a834e75 | ||
|
|
2a1210384a | ||
|
|
d497611069 | ||
|
|
46d8786f5a | ||
|
|
b8028729eb | ||
|
|
30e7768a87 | ||
|
|
10dc663e07 | ||
|
|
42fc57d761 | ||
|
|
74cd2f4844 | ||
|
|
a15135f1c1 | ||
|
|
ccd84c0be6 | ||
|
|
510215f284 | ||
|
|
c7ea0aacd6 | ||
|
|
f7f089d2d4 | ||
|
|
82721c77a1 | ||
|
|
1c9bf7d91c | ||
|
|
9bf78396cb | ||
|
|
d994e4719c | ||
|
|
44b886bb76 | ||
|
|
8d2f012bcf | ||
|
|
a86deed5f6 | ||
|
|
3fd9ad7a60 | ||
|
|
319a5cf97c | ||
|
|
0fd503d6af | ||
|
|
bf696026bd | ||
|
|
734657244b | ||
|
|
d2470e4f9c | ||
|
|
28a2792280 | ||
|
|
cd985a33d8 | ||
|
|
726d2beffd | ||
|
|
f04be3fc1b | ||
|
|
b6927410d9 | ||
|
|
44b2e1ef8b | ||
|
|
3d01e6af89 | ||
|
|
00387b2076 | ||
|
|
f9bf514801 | ||
|
|
fa27bddfab | ||
|
|
f27e8f8ddc | ||
|
|
5b2623ff2e | ||
|
|
a83a726b6e | ||
|
|
93df7e00a7 | ||
|
|
6b7748a88d | ||
|
|
f102c77fa2 | ||
|
|
a4fa261b77 | ||
|
|
8a15fefc6c | ||
|
|
12a4cc16be | ||
|
|
6335716342 | ||
|
|
db0602ac2a | ||
|
|
390ad530f1 | ||
|
|
6eb2e8d68a | ||
|
|
b804b3b221 | ||
|
|
936c1118bd | ||
|
|
4ba7b8a8ff | ||
|
|
70601e9da0 | ||
|
|
c32d1f9614 | ||
|
|
e031f78ad4 | ||
|
|
7d0273051a | ||
|
|
29d537571b | ||
|
|
39f243f76b | ||
|
|
0712360cc9 | ||
|
|
02c125cbb4 | ||
|
|
13256fb7e9 | ||
|
|
f11d757807 | ||
|
|
2e123849fb | ||
|
|
2f6cfaf0e9 | ||
|
|
f9b216d6f9 | ||
|
|
5fdd10d77e | ||
|
|
41de02d528 | ||
|
|
1c3d08f23a | ||
|
|
0f1dc1fd50 | ||
|
|
cd06018820 | ||
|
|
7816eb6344 | ||
|
|
9813f4b55f | ||
|
|
f81ca21b22 | ||
|
|
f1b7620c9e |
@@ -10,8 +10,7 @@
|
||||
subproject libs/python/build ;
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
import python ;
|
||||
|
||||
if [ check-python-config ]
|
||||
{
|
||||
@@ -53,6 +52,8 @@ if [ check-python-config ]
|
||||
object/iterator.cpp
|
||||
object_protocol.cpp
|
||||
object_operators.cpp
|
||||
indexing/slice.cpp
|
||||
indexing/python_iterator.cpp
|
||||
;
|
||||
|
||||
dll boost_python
|
||||
@@ -63,6 +64,11 @@ if [ check-python-config ]
|
||||
<msvc-stlport><release>$(msvc-stlport-workarounds)
|
||||
;
|
||||
|
||||
template extension
|
||||
: <dll>boost_python
|
||||
: <sysinclude>../../..
|
||||
;
|
||||
|
||||
lib boost_python
|
||||
: # sources
|
||||
../src/$(sources)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import os ;
|
||||
import modules ;
|
||||
|
||||
# Use a very crude way to sense there python is locatted
|
||||
|
||||
local PYTHON_PATH ;
|
||||
|
||||
local PYTHON_PATH = [ modules.peek : PYTHON_PATH ] ;
|
||||
ECHO "XXX" $(PYTHON_PATH) ;
|
||||
|
||||
if [ GLOB /usr/local/include/python2.2 : * ]
|
||||
{
|
||||
@@ -19,7 +22,7 @@ if [ os.name ] in CYGWIN NT
|
||||
defines = USE_DL_IMPORT ;
|
||||
|
||||
# Declare a target for the python interpreter library
|
||||
lib python : : <name>python2.2.dll ;
|
||||
lib python : : <name>python22 <search>$(PYTHON_PATH)/libs ;
|
||||
PYTHON_LIB = python ;
|
||||
}
|
||||
else
|
||||
@@ -35,12 +38,12 @@ if $(PYTHON_PATH) {
|
||||
|
||||
project boost/python
|
||||
: source-location ../src
|
||||
: requirements <include>$(PYTHON_PATH)/include/python2.2
|
||||
$(lib_condition)<library-path>$(PYTHON_PATH)/lib/python2.2/config
|
||||
: requirements <include>$(PYTHON_PATH)/include
|
||||
$(lib_condition)<library-path>$(PYTHON_PATH)/libs
|
||||
<link>shared:<library>$(PYTHON_LIB)
|
||||
<define>$(defines)
|
||||
: usage-requirements # requirement that will be propageted to *users* of this library
|
||||
<include>$(PYTHON_PATH)/include/python2.2
|
||||
<include>$(PYTHON_PATH)/include
|
||||
|
||||
# We have a bug which causes us to conclude that conditionalized
|
||||
# properties in this section are not free.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<title>Building Hybrid Systems with Boost.Python</title>
|
||||
<meta name="author" content="David Abrahams" />
|
||||
<meta name="organization" content="Boost Consulting" />
|
||||
<meta name="date" content="2003-03-13" />
|
||||
<meta name="date" content="2003-03-19" />
|
||||
<meta name="author" content="Ralf W. Grosse-Kunstleve" />
|
||||
<meta name="copyright" content="Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved" />
|
||||
<style type="text/css"><!--
|
||||
@@ -217,7 +217,7 @@ ul.auto-toc {
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first last reference" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-03-13</td></tr>
|
||||
<td>2003-03-19</td></tr>
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Ralf W. Grosse-Kunstleve</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
@@ -227,31 +227,33 @@ ul.auto-toc {
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#abstract" id="id8" name="id8">Abstract</a></li>
|
||||
<li><a class="reference" href="#introduction" id="id9" name="id9">Introduction</a></li>
|
||||
<li><a class="reference" href="#boost-python-design-goals" id="id10" name="id10">Boost.Python Design Goals</a></li>
|
||||
<li><a class="reference" href="#hello-boost-python-world" id="id11" name="id11">Hello Boost.Python World</a></li>
|
||||
<li><a class="reference" href="#library-overview" id="id12" name="id12">Library Overview</a><ul>
|
||||
<li><a class="reference" href="#exposing-classes" id="id13" name="id13">Exposing Classes</a><ul>
|
||||
<li><a class="reference" href="#constructors" id="id14" name="id14">Constructors</a></li>
|
||||
<li><a class="reference" href="#data-members-and-properties" id="id15" name="id15">Data Members and Properties</a></li>
|
||||
<li><a class="reference" href="#operator-overloading" id="id16" name="id16">Operator Overloading</a></li>
|
||||
<li><a class="reference" href="#inheritance" id="id17" name="id17">Inheritance</a></li>
|
||||
<li><a class="reference" href="#virtual-functions" id="id18" name="id18">Virtual Functions</a></li>
|
||||
<li><a class="reference" href="#deeper-reflection-on-the-horizon" id="id19" name="id19">Deeper Reflection on the Horizon?</a></li>
|
||||
<li><a class="reference" href="#abstract" id="id5" name="id5">Abstract</a></li>
|
||||
<li><a class="reference" href="#introduction" id="id6" name="id6">Introduction</a></li>
|
||||
<li><a class="reference" href="#boost-python-design-goals" id="id7" name="id7">Boost.Python Design Goals</a></li>
|
||||
<li><a class="reference" href="#hello-boost-python-world" id="id8" name="id8">Hello Boost.Python World</a></li>
|
||||
<li><a class="reference" href="#library-overview" id="id9" name="id9">Library Overview</a><ul>
|
||||
<li><a class="reference" href="#exposing-classes" id="id10" name="id10">Exposing Classes</a><ul>
|
||||
<li><a class="reference" href="#constructors" id="id11" name="id11">Constructors</a></li>
|
||||
<li><a class="reference" href="#data-members-and-properties" id="id12" name="id12">Data Members and Properties</a></li>
|
||||
<li><a class="reference" href="#operator-overloading" id="id13" name="id13">Operator Overloading</a></li>
|
||||
<li><a class="reference" href="#inheritance" id="id14" name="id14">Inheritance</a></li>
|
||||
<li><a class="reference" href="#virtual-functions" id="id15" name="id15">Virtual Functions</a></li>
|
||||
<li><a class="reference" href="#deeper-reflection-on-the-horizon" id="id16" name="id16">Deeper Reflection on the Horizon?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#serialization" id="id20" name="id20">Serialization</a></li>
|
||||
<li><a class="reference" href="#object-interface" id="id21" name="id21">Object interface</a></li>
|
||||
<li><a class="reference" href="#serialization" id="id17" name="id17">Serialization</a></li>
|
||||
<li><a class="reference" href="#object-interface" id="id18" name="id18">Object interface</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#thinking-hybrid" id="id22" name="id22">Thinking hybrid</a></li>
|
||||
<li><a class="reference" href="#development-history" id="id23" name="id23">Development history</a></li>
|
||||
<li><a class="reference" href="#conclusions" id="id24" name="id24">Conclusions</a></li>
|
||||
<li><a class="reference" href="#thinking-hybrid" id="id19" name="id19">Thinking hybrid</a></li>
|
||||
<li><a class="reference" href="#development-history" id="id20" name="id20">Development history</a></li>
|
||||
<li><a class="reference" href="#conclusions" id="id21" name="id21">Conclusions</a></li>
|
||||
<li><a class="reference" href="#citations" id="id22" name="id22">Citations</a></li>
|
||||
<li><a class="reference" href="#footnotes" id="id23" name="id23">Footnotes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="abstract">
|
||||
<h1><a class="toc-backref" href="#id8" name="abstract">Abstract</a></h1>
|
||||
<h1><a class="toc-backref" href="#id5" name="abstract">Abstract</a></h1>
|
||||
<p>Boost.Python is an open source C++ library which provides a concise
|
||||
IDL-like interface for binding C++ classes and functions to
|
||||
Python. Leveraging the full power of C++ compile-time introspection
|
||||
@@ -264,7 +266,7 @@ compile-time polymorphism of C++ and the extremely convenient run-time
|
||||
polymorphism of Python.</p>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
<h1><a class="toc-backref" href="#id9" name="introduction">Introduction</a></h1>
|
||||
<h1><a class="toc-backref" href="#id6" name="introduction">Introduction</a></h1>
|
||||
<p>Python and C++ are in many ways as different as two languages could
|
||||
be: while C++ is usually compiled to machine-code, Python is
|
||||
interpreted. Python's dynamic type system is often cited as the
|
||||
@@ -356,7 +358,7 @@ code being exposed, the user has unprecedented power available when
|
||||
she does need to take control.</p>
|
||||
</div>
|
||||
<div class="section" id="boost-python-design-goals">
|
||||
<h1><a class="toc-backref" href="#id10" name="boost-python-design-goals">Boost.Python Design Goals</a></h1>
|
||||
<h1><a class="toc-backref" href="#id7" name="boost-python-design-goals">Boost.Python Design Goals</a></h1>
|
||||
<p>The primary goal of Boost.Python is to allow users to expose C++
|
||||
classes and functions to Python using nothing more than a C++
|
||||
compiler. In broad strokes, the user experience should be one of
|
||||
@@ -382,7 +384,7 @@ to be wrappable by third parties who only have access to header files
|
||||
and binaries.</p>
|
||||
</div>
|
||||
<div class="section" id="hello-boost-python-world">
|
||||
<h1><a class="toc-backref" href="#id11" name="hello-boost-python-world">Hello Boost.Python World</a></h1>
|
||||
<h1><a class="toc-backref" href="#id8" name="hello-boost-python-world">Hello Boost.Python World</a></h1>
|
||||
<p>And now for a preview of Boost.Python, and how it improves on the raw
|
||||
facilities offered by Python. Here's a function we might want to
|
||||
expose:</p>
|
||||
@@ -477,12 +479,12 @@ registry allows users to add arbitrary conversion methods.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="library-overview">
|
||||
<h1><a class="toc-backref" href="#id12" name="library-overview">Library Overview</a></h1>
|
||||
<h1><a class="toc-backref" href="#id9" name="library-overview">Library Overview</a></h1>
|
||||
<p>This section outlines some of the library's major features. Except as
|
||||
neccessary to avoid confusion, details of library implementation are
|
||||
omitted.</p>
|
||||
<div class="section" id="exposing-classes">
|
||||
<h2><a class="toc-backref" href="#id13" name="exposing-classes">Exposing Classes</a></h2>
|
||||
<h2><a class="toc-backref" href="#id10" name="exposing-classes">Exposing Classes</a></h2>
|
||||
<p>C++ classes and structs are exposed with a similarly-terse interface.
|
||||
Given:</p>
|
||||
<pre class="literal-block">
|
||||
@@ -552,7 +554,7 @@ will stick to the terse syntax.</p>
|
||||
'howdy'
|
||||
</pre>
|
||||
<div class="section" id="constructors">
|
||||
<h3><a class="toc-backref" href="#id14" name="constructors">Constructors</a></h3>
|
||||
<h3><a class="toc-backref" href="#id11" name="constructors">Constructors</a></h3>
|
||||
<p>Since our <tt class="literal"><span class="pre">World</span></tt> class is just a plain <tt class="literal"><span class="pre">struct</span></tt>, it has an
|
||||
implicit no-argument (nullary) constructor. Boost.Python exposes the
|
||||
nullary constructor by default, which is why we were able to write:</p>
|
||||
@@ -589,7 +591,7 @@ class_<World>("World", init<std::string>())
|
||||
constructors to be overloaded to mirror C++ overloading.</p>
|
||||
</div>
|
||||
<div class="section" id="data-members-and-properties">
|
||||
<h3><a class="toc-backref" href="#id15" name="data-members-and-properties">Data Members and Properties</a></h3>
|
||||
<h3><a class="toc-backref" href="#id12" name="data-members-and-properties">Data Members and Properties</a></h3>
|
||||
<p>Any publicly-accessible data members in a C++ class can be easily
|
||||
exposed as either <tt class="literal"><span class="pre">readonly</span></tt> or <tt class="literal"><span class="pre">readwrite</span></tt> attributes:</p>
|
||||
<pre class="literal-block">
|
||||
@@ -637,7 +639,7 @@ class_<World>("World", init<std::string>())
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="operator-overloading">
|
||||
<h3><a class="toc-backref" href="#id16" name="operator-overloading">Operator Overloading</a></h3>
|
||||
<h3><a class="toc-backref" href="#id13" name="operator-overloading">Operator Overloading</a></h3>
|
||||
<p>The ability to write arithmetic operators for user-defined types has
|
||||
been a major factor in the success of both languages for numerical
|
||||
computation, and the success of packages like <a class="reference" href="http://www.pfdubois.com/numpy/">NumPy</a> attests to the
|
||||
@@ -669,7 +671,7 @@ Boost.Python uses the same technique to build an appropriate Python
|
||||
method object based on expressions involving <tt class="literal"><span class="pre">self</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="inheritance">
|
||||
<h3><a class="toc-backref" href="#id17" name="inheritance">Inheritance</a></h3>
|
||||
<h3><a class="toc-backref" href="#id14" name="inheritance">Inheritance</a></h3>
|
||||
<p>C++ inheritance relationships can be represented to Boost.Python by adding
|
||||
an optional <tt class="literal"><span class="pre">bases<...></span></tt> argument to the <tt class="literal"><span class="pre">class_<...></span></tt> template
|
||||
parameter list as follows:</p>
|
||||
@@ -731,7 +733,7 @@ by either removing <tt class="literal"><span class="pre">D</span></tt>'s <tt cla
|
||||
<tt class="literal"><span class="pre">SomeBoostPythonClass.__init__(...)</span></tt> explicitly.</p>
|
||||
</div>
|
||||
<div class="section" id="virtual-functions">
|
||||
<h3><a class="toc-backref" href="#id18" name="virtual-functions">Virtual Functions</a></h3>
|
||||
<h3><a class="toc-backref" href="#id15" name="virtual-functions">Virtual Functions</a></h3>
|
||||
<p>Deriving new types in Python from extension classes is not very
|
||||
interesting unless they can be used polymorphically from C++. In
|
||||
other words, Python method implementations should appear to override
|
||||
@@ -803,7 +805,7 @@ called on an object of type <tt class="literal"><span class="pre">BaseWrap</span
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="deeper-reflection-on-the-horizon">
|
||||
<h3><a class="toc-backref" href="#id19" name="deeper-reflection-on-the-horizon">Deeper Reflection on the Horizon?</a></h3>
|
||||
<h3><a class="toc-backref" href="#id16" name="deeper-reflection-on-the-horizon">Deeper Reflection on the Horizon?</a></h3>
|
||||
<p>Admittedly, this formula is tedious to repeat, especially on a project
|
||||
with many polymorphic classes. That it is neccessary reflects some
|
||||
limitations in C++'s compile-time introspection capabilities: there's
|
||||
@@ -827,7 +829,7 @@ will be "thinking hybrid" about their own code.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="serialization">
|
||||
<h2><a class="toc-backref" href="#id20" name="serialization">Serialization</a></h2>
|
||||
<h2><a class="toc-backref" href="#id17" name="serialization">Serialization</a></h2>
|
||||
<p><em>Serialization</em> is the process of converting objects in memory to a
|
||||
form that can be stored on disk or sent over a network connection. The
|
||||
serialized object (most often a plain string) can be retrieved and
|
||||
@@ -897,7 +899,7 @@ more work than is shown in the example above. Fortunately the
|
||||
code manageable.</p>
|
||||
</div>
|
||||
<div class="section" id="object-interface">
|
||||
<h2><a class="toc-backref" href="#id21" name="object-interface">Object interface</a></h2>
|
||||
<h2><a class="toc-backref" href="#id18" name="object-interface">Object interface</a></h2>
|
||||
<p>Experienced 'C' language extension module authors will be familiar
|
||||
with the ubiquitous <tt class="literal"><span class="pre">PyObject*</span></tt>, manual reference-counting, and the
|
||||
need to remember which API calls return "new" (owned) references or
|
||||
@@ -943,7 +945,7 @@ C++. Of course we can wrap C++ functions which accept or return
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="thinking-hybrid">
|
||||
<h1><a class="toc-backref" href="#id22" name="thinking-hybrid">Thinking hybrid</a></h1>
|
||||
<h1><a class="toc-backref" href="#id19" name="thinking-hybrid">Thinking hybrid</a></h1>
|
||||
<p>Because of the practical and mental difficulties of combining
|
||||
programming languages, it is common to settle a single language at the
|
||||
outset of any development effort. For many applications, performance
|
||||
@@ -984,15 +986,15 @@ to access all of our code from Python allows a broader group of
|
||||
developers to use it in the rapid development of new applications.</p>
|
||||
</div>
|
||||
<div class="section" id="development-history">
|
||||
<h1><a class="toc-backref" href="#id23" name="development-history">Development history</a></h1>
|
||||
<h1><a class="toc-backref" href="#id20" name="development-history">Development history</a></h1>
|
||||
<p>The first version of Boost.Python was developed in 2000 by Dave
|
||||
Abrahams at Dragon Systems, where he was privileged to have Tim Peters
|
||||
as a guide to "The Zen of Python". One of Dave's jobs was to develop
|
||||
a Python-based natural language processing system. Since it was
|
||||
eventually going to be targeting embedded hardware, it was always
|
||||
assumed that the compute-intensive core would be rewritten in C++ to
|
||||
optimize speed and memory footprint <a class="footnote-reference" href="#id5" id="id2" name="id2"><sup>4</sup></a>. The project also wanted to
|
||||
test all of its C++ code using Python test scripts <a class="footnote-reference" href="#id6" id="id3" name="id3"><sup>5</sup></a>. The only
|
||||
optimize speed and memory footprint <a class="footnote-reference" href="#proto" id="id2" name="id2"><sup>1</sup></a>. The project also wanted to
|
||||
test all of its C++ code using Python test scripts <a class="footnote-reference" href="#test" id="id3" name="id3"><sup>2</sup></a>. The only
|
||||
tool we knew of for binding C++ and Python was <a class="reference" href="http://www.swig.org/">SWIG</a>, and at the time
|
||||
its handling of C++ was weak. It would be false to claim any deep
|
||||
insight into the possible advantages of Boost.Python's approach at
|
||||
@@ -1005,7 +1007,7 @@ described in this paper, differing most-noticeably by having a
|
||||
slightly more cumbersome syntax and by lack of special support for
|
||||
operator overloading, pickling, and component-based development.
|
||||
These last three features were quickly added by Ullrich Koethe and
|
||||
Ralf Grosse-Kunstleve <a class="footnote-reference" href="#id7" id="id4" name="id4"><sup>6</sup></a>, and other enthusiastic contributors arrived
|
||||
Ralf Grosse-Kunstleve <a class="footnote-reference" href="#feature" id="id4" name="id4"><sup>3</sup></a>, and other enthusiastic contributors arrived
|
||||
on the scene to contribute enhancements like support for nested
|
||||
modules and static member functions.</p>
|
||||
<p>By early 2001 development had stabilized and few new features were
|
||||
@@ -1056,7 +1058,7 @@ Python C++-sig and a backlog of desired improvements show that the
|
||||
library is getting used. To us, the future looks bright.</p>
|
||||
</div>
|
||||
<div class="section" id="conclusions">
|
||||
<h1><a class="toc-backref" href="#id24" name="conclusions">Conclusions</a></h1>
|
||||
<h1><a class="toc-backref" href="#id21" name="conclusions">Conclusions</a></h1>
|
||||
<p>Boost.Python achieves seamless interoperability between two rich and
|
||||
complimentary language environments. Because it leverages template
|
||||
metaprogramming to introspect about types and functions, the user
|
||||
@@ -1069,6 +1071,9 @@ often impossible to implement efficiently in pure Python, while jobs
|
||||
like serialization that are trivial in Python can be very difficult in
|
||||
pure C++. Given the luxury of building a hybrid software system from
|
||||
the ground up, we can approach design with new confidence and power.</p>
|
||||
</div>
|
||||
<div class="section" id="citations">
|
||||
<h1><a class="toc-backref" href="#id22" name="citations">Citations</a></h1>
|
||||
<table class="citation" frame="void" id="veld1995" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<col />
|
||||
@@ -1078,30 +1083,35 @@ Vol. 7 No. 5 June 1995, pp. 26-31.
|
||||
<a class="reference" href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="footnote" frame="void" id="id5" rules="none">
|
||||
</div>
|
||||
<div class="section" id="footnotes">
|
||||
<h1><a class="toc-backref" href="#id23" name="footnotes">Footnotes</a></h1>
|
||||
<table class="footnote" frame="void" id="proto" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id2" name="id5">[4]</a></td><td>In retrospect, it seems that "thinking hybrid" from the ground up
|
||||
might have been better for the NLP system: the natural component
|
||||
boundaries defined by the pure python prototype turned out to be
|
||||
inappropriate for getting the desired performance and memory footprint
|
||||
out of the C++ core, which eventually caused some redesign overhead on
|
||||
the Python side when the core was moved to C++.</td></tr>
|
||||
<tr><td class="label"><a class="fn-backref" href="#id2" name="proto">[1]</a></td><td>In retrospect, it seems that "thinking hybrid" from the
|
||||
ground up might have been better for the NLP system: the
|
||||
natural component boundaries defined by the pure python
|
||||
prototype turned out to be inappropriate for getting the
|
||||
desired performance and memory footprint out of the C++ core,
|
||||
which eventually caused some redesign overhead on the Python
|
||||
side when the core was moved to C++.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="footnote" frame="void" id="id6" rules="none">
|
||||
<table class="footnote" frame="void" id="test" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id3" name="id6">[5]</a></td><td>We also have some reservations about driving all C++ testing through a
|
||||
Python interface, unless that's the only way it will be ultimately
|
||||
used. Any transition across language boundaries with such different
|
||||
object models can inevitably mask bugs.</td></tr>
|
||||
<tr><td class="label"><a class="fn-backref" href="#id3" name="test">[2]</a></td><td>We also have some reservations about driving all C++
|
||||
testing through a Python interface, unless that's the only way
|
||||
it will be ultimately used. Any transition across language
|
||||
boundaries with such different object models can inevitably
|
||||
mask bugs.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="footnote" frame="void" id="id7" rules="none">
|
||||
<table class="footnote" frame="void" id="feature" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id4" name="id7">[6]</a></td><td>These features were expressed very differently in v1 of
|
||||
<tr><td class="label"><a class="fn-backref" href="#id4" name="feature">[3]</a></td><td>These features were expressed very differently in v1 of
|
||||
Boost.Python</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1110,7 +1120,7 @@ Boost.Python</td></tr>
|
||||
<hr class="footer"/>
|
||||
<div class="footer">
|
||||
<a class="reference" href="bpl.txt">View document source</a>.
|
||||
Generated on: 2003-03-19 01:41 UTC.
|
||||
Generated on: 2003-03-19 03:31 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
|
||||
Binary file not shown.
@@ -828,8 +828,8 @@ as a guide to "The Zen of Python". One of Dave's jobs was to develop
|
||||
a Python-based natural language processing system. Since it was
|
||||
eventually going to be targeting embedded hardware, it was always
|
||||
assumed that the compute-intensive core would be rewritten in C++ to
|
||||
optimize speed and memory footprint [#1]_. The project also wanted to
|
||||
test all of its C++ code using Python test scripts [#2]_. The only
|
||||
optimize speed and memory footprint [#proto]_. The project also wanted to
|
||||
test all of its C++ code using Python test scripts [#test]_. The only
|
||||
tool we knew of for binding C++ and Python was SWIG_, and at the time
|
||||
its handling of C++ was weak. It would be false to claim any deep
|
||||
insight into the possible advantages of Boost.Python's approach at
|
||||
@@ -843,7 +843,7 @@ described in this paper, differing most-noticeably by having a
|
||||
slightly more cumbersome syntax and by lack of special support for
|
||||
operator overloading, pickling, and component-based development.
|
||||
These last three features were quickly added by Ullrich Koethe and
|
||||
Ralf Grosse-Kunstleve [#3]_, and other enthusiastic contributors arrived
|
||||
Ralf Grosse-Kunstleve [#feature]_, and other enthusiastic contributors arrived
|
||||
on the scene to contribute enhancements like support for nested
|
||||
modules and static member functions.
|
||||
|
||||
@@ -917,21 +917,31 @@ like serialization that are trivial in Python can be very difficult in
|
||||
pure C++. Given the luxury of building a hybrid software system from
|
||||
the ground up, we can approach design with new confidence and power.
|
||||
|
||||
===========
|
||||
Citations
|
||||
===========
|
||||
|
||||
.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
|
||||
Vol. 7 No. 5 June 1995, pp. 26-31.
|
||||
http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
|
||||
|
||||
.. [#1] In retrospect, it seems that "thinking hybrid" from the ground up
|
||||
might have been better for the NLP system: the natural component
|
||||
boundaries defined by the pure python prototype turned out to be
|
||||
inappropriate for getting the desired performance and memory footprint
|
||||
out of the C++ core, which eventually caused some redesign overhead on
|
||||
the Python side when the core was moved to C++.
|
||||
===========
|
||||
Footnotes
|
||||
===========
|
||||
|
||||
.. [#2] We also have some reservations about driving all C++ testing through a
|
||||
Python interface, unless that's the only way it will be ultimately
|
||||
used. Any transition across language boundaries with such different
|
||||
object models can inevitably mask bugs.
|
||||
.. [#proto] In retrospect, it seems that "thinking hybrid" from the
|
||||
ground up might have been better for the NLP system: the
|
||||
natural component boundaries defined by the pure python
|
||||
prototype turned out to be inappropriate for getting the
|
||||
desired performance and memory footprint out of the C++ core,
|
||||
which eventually caused some redesign overhead on the Python
|
||||
side when the core was moved to C++.
|
||||
|
||||
.. [#3] These features were expressed very differently in v1 of
|
||||
.. [#test] We also have some reservations about driving all C++
|
||||
testing through a Python interface, unless that's the only way
|
||||
it will be ultimately used. Any transition across language
|
||||
boundaries with such different object models can inevitably
|
||||
mask bugs.
|
||||
|
||||
.. [#feature] These features were expressed very differently in v1 of
|
||||
Boost.Python
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="boost.css">
|
||||
|
||||
@@ -39,25 +39,22 @@
|
||||
<dl class="index">
|
||||
<dt><a href="#configuration">Configuration</a></dt>
|
||||
|
||||
<dt><a href="#cygwin_configuration">Configuration for Cygwin GCC
|
||||
from a Windows prompt</a></dt>
|
||||
|
||||
<dt><a href="#results">Results</a></dt>
|
||||
|
||||
<dt><a href="#cygwin">Notes for Cygwin GCC Users</a></dt>
|
||||
|
||||
<dt><a href="#mingw">Notes for MinGW (and Cygwin with -mno-cygwin)
|
||||
GCC Users</a></dt>
|
||||
|
||||
<dt><a href="#testing">Testing</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#building_ext">Building your Extension Module</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl>
|
||||
<dt><a href="#easy">The Easy Way</a></dt>
|
||||
|
||||
<dt><a href="#outside">Building your module outside the Boost
|
||||
project tree</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#variants">Build Variants</a></dt>
|
||||
|
||||
<dt><a href="#VisualStudio">Building Using the Microsoft Visual Studio
|
||||
@@ -77,7 +74,7 @@
|
||||
<p>Normally, Boost.Python extension modules must be linked with the
|
||||
<code>boost_python</code> shared library. In special circumstances you
|
||||
may want to link to a static version of the <code>boost_python</code>
|
||||
library, but if multiple Boost.Pythone extension modules are used
|
||||
library, but if multiple Boost.Python extension modules are used
|
||||
together, it will prevent sharing of types across extension modules, and
|
||||
consume extra code space. To build <code>boost_python</code>, use <a
|
||||
href="../../../tools/build/index.html">Boost.Build</a> in the usual way
|
||||
@@ -85,7 +82,7 @@
|
||||
installation (if you have already built boost from the top level this may
|
||||
have no effect, since the work is already done).</p>
|
||||
|
||||
<h3><a name="configuration">Configuration</a></h3>
|
||||
<h3><a name="configuration">Basic Configuration</a></h3>
|
||||
You may need to configure the following variables to point Boost.Build at
|
||||
your Python installation:
|
||||
|
||||
@@ -128,7 +125,8 @@
|
||||
|
||||
<td>path to Python <code>#include</code> directories</td>
|
||||
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code>. Try the default
|
||||
before attempting to set it yourself.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -136,37 +134,50 @@
|
||||
|
||||
<td>path to Python library object.</td>
|
||||
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code>. Try the default
|
||||
before attempting to set it yourself.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3><a name="cygwin_configuration">Configuration for Cygwin GCC from a
|
||||
Windows prompt</a></h3>
|
||||
The following settings may be useful when building with <a href=
|
||||
"http://www.cygwin.com">Cygwin</a> GCC (not MinGW) from a Windows command
|
||||
shell using a Windows build of <code>bjam</code>. <b>If
|
||||
"<code>bjam -v</code>" does not report "<code>OS=NT</code>", these
|
||||
settings do not apply to you</b>; you should use the <a href=
|
||||
"#configuration">normal configuration</a> variables instead. They are
|
||||
only useful when building and testing with multiple toolsets on Windows
|
||||
using a single build command, since Cygwin GCC requires a different build
|
||||
of Python.
|
||||
|
||||
<table border="1" summary=
|
||||
"Cygwin GCC under NT build configuration variables">
|
||||
<tr>
|
||||
<th>Variable Name</th>
|
||||
|
||||
<th>Semantics</th>
|
||||
|
||||
<th>Default</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>CYGWIN_PYTHON_[DEBUG_]VERSION</code></td>
|
||||
|
||||
<td>The version of python being used under Cygwin. </td>
|
||||
<td>The version of python being used under Cygwin.</td>
|
||||
|
||||
<td>$(PYTHON_VERSION)
|
||||
|
||||
</td>
|
||||
|
||||
<td>Use only when building with <a href=
|
||||
"http://www.cygwin.com">Cygwin</a> GCC. This and the following
|
||||
settings are useful when building with multiple toolsets on
|
||||
Windows, since Cygwin GCC requires a different build of
|
||||
Python.</td> </tr>
|
||||
<td>$(PYTHON_VERSION)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>CYGWIN_PYTHON_[DEBUG_]ROOT</code></td>
|
||||
|
||||
<td>unix-style path containing the <code>include/</code>
|
||||
directory containing
|
||||
<code>python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h</code>. </td>
|
||||
<td>unix-style path containing the <code>include/</code> directory
|
||||
containing
|
||||
<code>python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h</code>.</td>
|
||||
|
||||
<td>$(PYTHON_ROOT)
|
||||
|
||||
</td>
|
||||
|
||||
<td>Use only when building with <a href=
|
||||
"http://www.cygwin.com">Cygwin</a> GCC.</td> </tr>
|
||||
<td>$(PYTHON_ROOT)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>CYGWIN_PYTHON_[DEBUG_]LIB_PATH</code></td>
|
||||
@@ -175,9 +186,7 @@
|
||||
<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.a</code></td>
|
||||
|
||||
<td>Autoconfigured from <code>CYGWIN_PYTHON_ROOT</code></td>
|
||||
|
||||
<td>Use only when building with <a href=
|
||||
"http://www.cygwin.com">Cygwin</a> GCC.</td> </tr>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>CYGWIN_PYTHON_[DEBUG_]DLL_PATH</code></td>
|
||||
@@ -186,10 +195,6 @@
|
||||
(<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll</code>)</td>
|
||||
|
||||
<td><code>/bin</code></td>
|
||||
|
||||
<td>Use only when building with <a href=
|
||||
"http://www.cygwin.com">Cygwin</a> GCC.</td> </tr>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -206,10 +211,23 @@
|
||||
"http://www.python.org/download/download_source.html">Unix installation
|
||||
process</a> to build Python from source.</p>
|
||||
|
||||
<p>The special build configuration variables listed above as "Cygwin
|
||||
only" make it possible to use a regular Win32 build of bjam to build and
|
||||
test Boost.Python and Boost.Python extensions using Cygwin GCC and
|
||||
targeting a Cygwin build of Python.</p>
|
||||
<p>The special build configuration variables listed <a href=
|
||||
"#cygwin_configuration">above</a> make it possible to use a regular Win32
|
||||
build of bjam to build and test Boost.Python and Boost.Python extensions
|
||||
using Cygwin GCC and targeting a Cygwin build of Python.</p>
|
||||
|
||||
<h3><a name="mingw">Notes for MinGW (and Cygwin with -mno-cygwin) GCC
|
||||
Users</a></h3>
|
||||
|
||||
<p>You will need to create a MinGW-compatible version of the Python
|
||||
library; the one shipped with Python will only work with a
|
||||
Microsoft-compatible linker. Follow the instructions in the
|
||||
"Non-Microsoft" section of the "Building Extensions: Tips And Tricks"
|
||||
chapter in <a href=
|
||||
"http://www.python.org/doc/current/inst/index.html">Installing Python
|
||||
Modules</a> to create <code>libpythonXX.a</code>, where <code>XX</code>
|
||||
corresponds to the major and minor version numbers of your Python
|
||||
installation.</p>
|
||||
|
||||
<h3><a name="results">Results</a></h3>
|
||||
|
||||
@@ -248,45 +266,49 @@ bjam -sTOOLS=<i><a href=
|
||||
passes.
|
||||
|
||||
<h2><a name="building_ext">Building your Extension Module</a></h2>
|
||||
Though there are other approaches, the best way to build an extension
|
||||
module using Boost.Python is with Boost.Build. If you have to use another
|
||||
build system, you should use Boost.Build at least once with the
|
||||
Though there are other approaches, the smoothest and most reliable
|
||||
way to build an extension module using Boost.Python is with
|
||||
Boost.Build. If you have to use another build system, you should
|
||||
use Boost.Build at least once with the
|
||||
"<code><b>-n</b></code>" option so you can see the command-lines it uses,
|
||||
and replicate them. You are likely to run into compilation or linking
|
||||
problems otherwise.
|
||||
|
||||
<h3><a name="easy">The Easy Way</a></h3>
|
||||
Until Boost.Build v2 is released, cross-project build dependencies are
|
||||
not supported, so it works most smoothly if you add a new subproject to
|
||||
your boost installation. The <code>libs/python/example</code>
|
||||
subdirectory of your boost installation contains a minimal example (along
|
||||
with many extra sources). To copy the example subproject:
|
||||
The <code><a href="../example">libs/python/example</a></code>
|
||||
subdirectory of your boost installation contains a small example
|
||||
which builds and tests two extensions. To build your own
|
||||
extensions copy the example subproject and make the following two edits:
|
||||
|
||||
<ol>
|
||||
<li>Create a new subdirectory in, <code>libs/python</code>, say
|
||||
<code>libs/python/my_project</code>.</li>
|
||||
<ol>
|
||||
<li><code><a
|
||||
href="../example/boost-build.jam"><b>boost-build.jam</b></a></code> -
|
||||
edit the line which reads
|
||||
|
||||
<li>Copy <code><a href=
|
||||
"../example/Jamfile">libs/python/example/Jamfile</a></code> to your new
|
||||
directory.</li>
|
||||
<blockquote>
|
||||
<pre>
|
||||
boost-build ../../../tools/build ;
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<li>Edit the Jamfile as appropriate for your project. You'll want to
|
||||
change the "<code>subproject</code>" rule invocation at the top, and
|
||||
the names of some of the source files and/or targets.</li>
|
||||
</ol>
|
||||
so that the path refers to the <code>tools/build</code> subdirectory
|
||||
of your Boost installation.
|
||||
|
||||
|
||||
<li><code><a href="../example/Jamrules"><b>Jamrules</b></a></code> -
|
||||
edit the line which reads
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
path-global BOOST_ROOT : ../../.. ;
|
||||
</pre>
|
||||
</blockquote>
|
||||
so that the path refers to the root directory of your Boost installation.
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
The instructions <a href="#testing">above</a> for testing Boost.Python
|
||||
apply equally to your new extension modules in this subproject.
|
||||
|
||||
<h3><a name="outside">Building your module outside the Boost project
|
||||
tree</a></h3>
|
||||
If you can't (or don't wish to) modify your boost installation, the
|
||||
alternative is to create your own Boost.Build project. A similar example
|
||||
you can use as a starting point is available in <code><a href=
|
||||
"../example/project.zip">this archive</a></code>. You'll need to edit the
|
||||
Jamfile and Jamrules files, depending on the relative location of your
|
||||
Boost installation and the new project. Note that automatic testing of
|
||||
extension modules is not available in this configuration.
|
||||
|
||||
<h2><a name="variants">Build Variants</a></h2>
|
||||
Three <a href=
|
||||
"../../../tools/build/build_system.htm#variants">variant</a>
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
href="http://www.llnl.gov/">Lawrence Livermore National Laboratories</a>
|
||||
and by the <a href="http://cci.lbl.gov/">Computational Crystallography
|
||||
Initiative</a> at Lawrence Berkeley National Laboratories.
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
@@ -87,22 +88,34 @@
|
||||
|
||||
<dt><a href="../pyste/index.html">Pyste (Boost.Python code generator)</a></dt>
|
||||
|
||||
<dt><a href="news.html">News/Change Log</a></dt>
|
||||
<dt><a href="internals.html">Internals Documentation</a></dt>
|
||||
|
||||
<dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
|
||||
<dt><a href="news.html">News/Change Log</a></dt>
|
||||
|
||||
<dt><a href="../todo.html">TODO list</a></dt>
|
||||
|
||||
<dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
|
||||
|
||||
<dt><a href="v2/acknowledgments.html">Acknowledgments</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2>Articles</h2>
|
||||
|
||||
"<a href="PyConDC_2003/bpl.html">Building Hybrid
|
||||
Systems With Boost Python</a>", by Dave Abrahams and Ralf
|
||||
W. Grosse-Kunstleve (<a href="PyConDC_2003/bpl.pdf">PDF</a>)
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
17 November, 2002
|
||||
26 August, 2003
|
||||
<!--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>
|
||||
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
186
doc/internals.html
Executable file
186
doc/internals.html
Executable file
@@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
|
||||
<title>Boost.Python Internals Boost</title>
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="boost-python-internals-logo">
|
||||
<h1 class="title"><a class="reference" href="index.html">Boost.Python</a> Internals <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../c++boost.gif" /></a></h1>
|
||||
<div class="section" id="a-conversation-between-brett-calcott-and-david-abrahams">
|
||||
<h1><a name="a-conversation-between-brett-calcott-and-david-abrahams">A conversation between Brett Calcott and David Abrahams</a></h1>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams and Brett Calcott 2003. See
|
||||
accompanying <a class="reference" href="../../../LICENSE">license</a> for terms of use.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>In both of these cases, I'm quite capable of reading code - but the
|
||||
thing I don't get from scanning the source is a sense of the
|
||||
architecture, both structurally, and temporally (er, I mean in what
|
||||
order things go on).</p>
|
||||
<ol class="arabic">
|
||||
<li><p class="first">What happens when you do the following:</p>
|
||||
<pre class="literal-block">
|
||||
struct boring {};
|
||||
...etc...
|
||||
class_<boring>("boring")
|
||||
;
|
||||
</pre>
|
||||
</li>
|
||||
</ol>
|
||||
<p>There seems to be a fair bit going on.</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>Python needs a new ClassType to be registered.</li>
|
||||
<li>We need to construct a new type that can hold our boring struct.</li>
|
||||
<li>Inward and outward converters need to be registered for the type.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>Can you gesture in the general direction where these things are done?</p>
|
||||
<blockquote>
|
||||
<p>I only have time for a "off-the-top-of-my-head" answer at the moment;
|
||||
I suggest you step through the code with a debugger after reading this
|
||||
to see how it works, fill in details, and make sure I didn't forget
|
||||
anything.</p>
|
||||
<blockquote>
|
||||
<p>A new (Python) subclass of Boost.Python.Instance (see
|
||||
libs/python/src/object/class.cpp) is created by invoking
|
||||
Boost.Python.class, the metatype:</p>
|
||||
<pre class="literal-block">
|
||||
>>> boring = Boost.Python.class(
|
||||
... 'boring'
|
||||
... , bases_tuple # in this case, just ()
|
||||
... , {
|
||||
... '__module__' : module_name
|
||||
... , '__doc__' : doc_string # optional
|
||||
... }
|
||||
... )
|
||||
</pre>
|
||||
<p>A handle to this object is stuck in the m_class_object field
|
||||
of the registration associated with <tt class="literal"><span class="pre">typeid(boring)</span></tt>. The
|
||||
registry will keep that object alive forever, even if you
|
||||
wipe out the 'boring' attribute of the extension module
|
||||
(probably not a good thing).</p>
|
||||
<p>Because you didn't specify <tt class="literal"><span class="pre">class<boring,</span> <span class="pre">non_copyable,</span>
|
||||
<span class="pre">...></span></tt>, a to-python converter for boring is registered which
|
||||
copies its argument into a value_holder held by the the
|
||||
Python boring object.</p>
|
||||
<p>Because you didn't specify <tt class="literal"><span class="pre">class<boring</span> <span class="pre">...>(no_init)</span></tt>,
|
||||
an <tt class="literal"><span class="pre">__init__</span></tt> function object is added to the class
|
||||
dictionary which default-constructs a boring in a
|
||||
value_holder (because you didn't specify some smart pointer
|
||||
or derived wrapper class as a holder) held by the Python
|
||||
boring object.</p>
|
||||
<p><tt class="literal"><span class="pre">register_class_from_python</span></tt> is used to register a
|
||||
from-python converter for <tt class="literal"><span class="pre">shared_ptr<boring></span></tt>.
|
||||
<tt class="literal"><span class="pre">boost::shared_ptr</span></tt>s are special among smart pointers
|
||||
because their Deleter argument can be made to manage the
|
||||
whole Python object, not just the C++ object it contains, no
|
||||
matter how the C++ object is held.</p>
|
||||
<p>If there were any <tt class="literal"><span class="pre">bases<></span></tt>, we'd also be registering the
|
||||
relationship between these base classes and boring in the
|
||||
up/down cast graph (<tt class="literal"><span class="pre">inheritance.[hpp/cpp]</span></tt>).</p>
|
||||
<p>In earlier versions of the code, we'd be registering lvalue
|
||||
from-python converters for the class here, but now
|
||||
from-python conversion for wrapped classes is handled as a
|
||||
special case, before consulting the registry, if the source
|
||||
Python object's metaclass is the Boost.Python metaclass.</p>
|
||||
<p>Hmm, that from-python converter probably ought to be handled
|
||||
the way class converters are, with no explicit conversions
|
||||
registered.</p>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<ol class="arabic" start="2">
|
||||
<li><p class="first">Can you give a brief overview of the data structures that are
|
||||
present in the registry</p>
|
||||
<blockquote>
|
||||
<p>The registry is simple: it's just a map from typeid ->
|
||||
registration (see boost/python/converter/registrations.hpp).
|
||||
<tt class="literal"><span class="pre">lvalue_chain</span></tt> and <tt class="literal"><span class="pre">rvalue_chain</span></tt> are simple endogenous
|
||||
linked lists.</p>
|
||||
<p>If you want to know more, just ask.</p>
|
||||
<p>If you want to know about the cast graph, ask me something specific in
|
||||
a separate message.</p>
|
||||
</blockquote>
|
||||
<p>and an overview of the process that happens as a type makes its
|
||||
way from c++ to python and back again.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<p>Big subject. I suggest some background reading: look for relevant
|
||||
info in the LLNL progress reports and the messages they link to.
|
||||
Also,</p>
|
||||
<blockquote>
|
||||
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a></p>
|
||||
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-December/003115.html">http://mail.python.org/pipermail/c++-sig/2002-December/003115.html</a></p>
|
||||
<p><a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1280898">http://aspn.activestate.com/ASPN/Mail/Message/1280898</a></p>
|
||||
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-July/001755.html">http://mail.python.org/pipermail/c++-sig/2002-July/001755.html</a></p>
|
||||
</blockquote>
|
||||
<p>from c++ to python:</p>
|
||||
<blockquote>
|
||||
<p>It depends on the type and the call policies in use or, for
|
||||
<tt class="literal"><span class="pre">call<>(...)</span></tt>, <tt class="literal"><span class="pre">call_method<>(...)</span></tt>, or <tt class="literal"><span class="pre">object(...)</span></tt>, if
|
||||
<tt class="literal"><span class="pre">ref</span></tt> or <tt class="literal"><span class="pre">ptr</span></tt> is used. There are also two basic
|
||||
categories to to-python conversion, "return value" conversion
|
||||
(for Python->C++ calls) and "argument" conversion (for
|
||||
C++->Python calls and explicit <tt class="literal"><span class="pre">object()</span></tt> conversions). The
|
||||
behavior of these two categories differs subtly in various ways
|
||||
whose details I forget at the moment. You can probably find
|
||||
the answers in the above references, and certainly in the code.</p>
|
||||
<p>The "default" case is by-value (copying) conversion, which uses
|
||||
to_python_value as a to-python converter.</p>
|
||||
<blockquote>
|
||||
<p>Since there can sensibly be only one way to convert any type
|
||||
to python (disregarding the idea of scoped registries for the
|
||||
moment), it makes sense that to-python conversions can be
|
||||
handled by specializing a template. If the type is one of
|
||||
the types handled by a built-in conversion
|
||||
(builtin_converters.hpp), the corresponding template
|
||||
specialization of to_python_value gets used.</p>
|
||||
<p>Otherwise, to_python_value uses the <tt class="literal"><span class="pre">m_to_python</span></tt>
|
||||
function in the registration for the C++ type.</p>
|
||||
</blockquote>
|
||||
<p>Other conversions, like by-reference conversions, are only
|
||||
available for wrapped classes, and are requested explicitly by
|
||||
using <tt class="literal"><span class="pre">ref(...)</span></tt>, <tt class="literal"><span class="pre">ptr(...)</span></tt>, or by specifying different
|
||||
CallPolicies for a call, which can cause a different to-python
|
||||
converter to be used. These conversions are never registered
|
||||
anywhere, though they do need to use the registration to find
|
||||
the Python class corresponding to the C++ type being referred
|
||||
to. They just build a new Python instance and stick the
|
||||
appropriate Holder instance in it.</p>
|
||||
</blockquote>
|
||||
<p>from python to C++:</p>
|
||||
<blockquote>
|
||||
<p>Once again I think there is a distinction between "return value"
|
||||
and "argument" conversions, and I forget exactly what that is.</p>
|
||||
<p>What happens depends on whether an lvalue conversion is needed
|
||||
(see <a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a>)
|
||||
All lvalue conversions are also registered in a type's rvalue
|
||||
conversion chain, since when an rvalue will do, an lvalue is
|
||||
certainly good enough.</p>
|
||||
<p>An lvalue conversion can be done in one step (just get me the
|
||||
pointer to the object - it can be <tt class="literal"><span class="pre">NULL</span></tt> if no conversion is
|
||||
possible) while an rvalue conversion requires two steps to
|
||||
support wrapped function overloading and multiple converters for
|
||||
a given C++ target type: first tell me if a conversion is
|
||||
possible, then construct the converted object as a second step.</p>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer"/>
|
||||
<div class="footer">
|
||||
<a class="reference" href="internals.rst">View document source</a>.
|
||||
Generated on: 2003-09-12 14:51 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
181
doc/internals.rst
Executable file
181
doc/internals.rst
Executable file
@@ -0,0 +1,181 @@
|
||||
===================================
|
||||
Boost.Python_ Internals |(logo)|__
|
||||
===================================
|
||||
|
||||
.. |(logo)| image:: ../../../c++boost.gif
|
||||
:alt: Boost
|
||||
|
||||
__ ../../../index.htm
|
||||
|
||||
.. _`Boost.Python`: index.html
|
||||
|
||||
.. _license: ../../../LICENSE
|
||||
|
||||
|
||||
-------------------------------------------------------
|
||||
A conversation between Brett Calcott and David Abrahams
|
||||
-------------------------------------------------------
|
||||
|
||||
:copyright: Copyright David Abrahams and Brett Calcott 2003. See
|
||||
accompanying license_ for terms of use.
|
||||
|
||||
In both of these cases, I'm quite capable of reading code - but the
|
||||
thing I don't get from scanning the source is a sense of the
|
||||
architecture, both structurally, and temporally (er, I mean in what
|
||||
order things go on).
|
||||
|
||||
1) What happens when you do the following::
|
||||
|
||||
struct boring {};
|
||||
...etc...
|
||||
class_<boring>("boring")
|
||||
;
|
||||
|
||||
There seems to be a fair bit going on.
|
||||
|
||||
- Python needs a new ClassType to be registered.
|
||||
- We need to construct a new type that can hold our boring struct.
|
||||
- Inward and outward converters need to be registered for the type.
|
||||
|
||||
Can you gesture in the general direction where these things are done?
|
||||
|
||||
I only have time for a "off-the-top-of-my-head" answer at the moment;
|
||||
I suggest you step through the code with a debugger after reading this
|
||||
to see how it works, fill in details, and make sure I didn't forget
|
||||
anything.
|
||||
|
||||
A new (Python) subclass of Boost.Python.Instance (see
|
||||
libs/python/src/object/class.cpp) is created by invoking
|
||||
Boost.Python.class, the metatype::
|
||||
|
||||
>>> boring = Boost.Python.class(
|
||||
... 'boring'
|
||||
... , bases_tuple # in this case, just ()
|
||||
... , {
|
||||
... '__module__' : module_name
|
||||
... , '__doc__' : doc_string # optional
|
||||
... }
|
||||
... )
|
||||
|
||||
A handle to this object is stuck in the m_class_object field
|
||||
of the registration associated with ``typeid(boring)``. The
|
||||
registry will keep that object alive forever, even if you
|
||||
wipe out the 'boring' attribute of the extension module
|
||||
(probably not a good thing).
|
||||
|
||||
Because you didn't specify ``class<boring, non_copyable,
|
||||
...>``, a to-python converter for boring is registered which
|
||||
copies its argument into a value_holder held by the the
|
||||
Python boring object.
|
||||
|
||||
Because you didn't specify ``class<boring ...>(no_init)``,
|
||||
an ``__init__`` function object is added to the class
|
||||
dictionary which default-constructs a boring in a
|
||||
value_holder (because you didn't specify some smart pointer
|
||||
or derived wrapper class as a holder) held by the Python
|
||||
boring object.
|
||||
|
||||
``register_class_from_python`` is used to register a
|
||||
from-python converter for ``shared_ptr<boring>``.
|
||||
``boost::shared_ptr``\ s are special among smart pointers
|
||||
because their Deleter argument can be made to manage the
|
||||
whole Python object, not just the C++ object it contains, no
|
||||
matter how the C++ object is held.
|
||||
|
||||
If there were any ``bases<>``, we'd also be registering the
|
||||
relationship between these base classes and boring in the
|
||||
up/down cast graph (``inheritance.[hpp/cpp]``).
|
||||
|
||||
In earlier versions of the code, we'd be registering lvalue
|
||||
from-python converters for the class here, but now
|
||||
from-python conversion for wrapped classes is handled as a
|
||||
special case, before consulting the registry, if the source
|
||||
Python object's metaclass is the Boost.Python metaclass.
|
||||
|
||||
Hmm, that from-python converter probably ought to be handled
|
||||
the way class converters are, with no explicit conversions
|
||||
registered.
|
||||
|
||||
2) Can you give a brief overview of the data structures that are
|
||||
present in the registry
|
||||
|
||||
The registry is simple: it's just a map from typeid ->
|
||||
registration (see boost/python/converter/registrations.hpp).
|
||||
``lvalue_chain`` and ``rvalue_chain`` are simple endogenous
|
||||
linked lists.
|
||||
|
||||
If you want to know more, just ask.
|
||||
|
||||
If you want to know about the cast graph, ask me something specific in
|
||||
a separate message.
|
||||
|
||||
and an overview of the process that happens as a type makes its
|
||||
way from c++ to python and back again.
|
||||
|
||||
Big subject. I suggest some background reading: look for relevant
|
||||
info in the LLNL progress reports and the messages they link to.
|
||||
Also,
|
||||
|
||||
http://mail.python.org/pipermail/c++-sig/2002-May/001023.html
|
||||
|
||||
http://mail.python.org/pipermail/c++-sig/2002-December/003115.html
|
||||
|
||||
http://aspn.activestate.com/ASPN/Mail/Message/1280898
|
||||
|
||||
http://mail.python.org/pipermail/c++-sig/2002-July/001755.html
|
||||
|
||||
from c++ to python:
|
||||
|
||||
It depends on the type and the call policies in use or, for
|
||||
``call<>(...)``, ``call_method<>(...)``, or ``object(...)``, if
|
||||
``ref`` or ``ptr`` is used. There are also two basic
|
||||
categories to to-python conversion, "return value" conversion
|
||||
(for Python->C++ calls) and "argument" conversion (for
|
||||
C++->Python calls and explicit ``object()`` conversions). The
|
||||
behavior of these two categories differs subtly in various ways
|
||||
whose details I forget at the moment. You can probably find
|
||||
the answers in the above references, and certainly in the code.
|
||||
|
||||
The "default" case is by-value (copying) conversion, which uses
|
||||
to_python_value as a to-python converter.
|
||||
|
||||
Since there can sensibly be only one way to convert any type
|
||||
to python (disregarding the idea of scoped registries for the
|
||||
moment), it makes sense that to-python conversions can be
|
||||
handled by specializing a template. If the type is one of
|
||||
the types handled by a built-in conversion
|
||||
(builtin_converters.hpp), the corresponding template
|
||||
specialization of to_python_value gets used.
|
||||
|
||||
Otherwise, to_python_value uses the ``m_to_python``
|
||||
function in the registration for the C++ type.
|
||||
|
||||
Other conversions, like by-reference conversions, are only
|
||||
available for wrapped classes, and are requested explicitly by
|
||||
using ``ref(...)``, ``ptr(...)``, or by specifying different
|
||||
CallPolicies for a call, which can cause a different to-python
|
||||
converter to be used. These conversions are never registered
|
||||
anywhere, though they do need to use the registration to find
|
||||
the Python class corresponding to the C++ type being referred
|
||||
to. They just build a new Python instance and stick the
|
||||
appropriate Holder instance in it.
|
||||
|
||||
|
||||
from python to C++:
|
||||
|
||||
Once again I think there is a distinction between "return value"
|
||||
and "argument" conversions, and I forget exactly what that is.
|
||||
|
||||
What happens depends on whether an lvalue conversion is needed
|
||||
(see http://mail.python.org/pipermail/c++-sig/2002-May/001023.html)
|
||||
All lvalue conversions are also registered in a type's rvalue
|
||||
conversion chain, since when an rvalue will do, an lvalue is
|
||||
certainly good enough.
|
||||
|
||||
An lvalue conversion can be done in one step (just get me the
|
||||
pointer to the object - it can be ``NULL`` if no conversion is
|
||||
possible) while an rvalue conversion requires two steps to
|
||||
support wrapped function overloading and multiple converters for
|
||||
a given C++ target type: first tell me if a conversion is
|
||||
possible, then construct the converted object as a second step.
|
||||
|
||||
108
doc/news.html
108
doc/news.html
@@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="boost.css">
|
||||
|
||||
@@ -29,18 +29,100 @@
|
||||
<hr>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt>11 Sept 2003</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>Changed the response to multiple to-python converters being
|
||||
registered for the same type from a hard error into warning;
|
||||
Boost.Python now reports the offending type in the message.</li>
|
||||
|
||||
<li>Added builtin <code>std::wstring</code> conversions</li>
|
||||
|
||||
<li>Added <code>std::out_of_range</code> => Python
|
||||
<code>IndexError</code> exception conversion, thanks to <a href=
|
||||
"mailto:RaoulGough-at-yahoo.co.uk">Raoul Gough</a></li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>9 Sept 2003</dt>
|
||||
|
||||
<dd>Added new <code><a href="v2/str.html#str-spec">str</a></code></dd>
|
||||
|
||||
<dt>constructors which take a range of characters, allowing strings
|
||||
containing nul (<code>'\0'</code>) characters.</dt>
|
||||
|
||||
<dt>8 Sept 2003</dt>
|
||||
|
||||
<dd>Added the ability to create methods from function objects (with an
|
||||
<code>operator()</code>); see the <a href=
|
||||
"v2/make_function.html#make_function-spec">make_function</a> docs for
|
||||
more info.</dd>
|
||||
|
||||
<dt>10 August 2003</dt>
|
||||
|
||||
<dd>Added the new <code>properties</code> unit tests contributed by <a
|
||||
href="mailto:romany-at-actimize.com">Roman Yakovenko</a> and documented
|
||||
<code>add_static_property</code> at his urging.</dd>
|
||||
|
||||
<dt>1 August 2003</dt>
|
||||
|
||||
<dd>
|
||||
Added the new <code>arg</code> class contributed by <a href=
|
||||
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a> which supplies the
|
||||
ability to wrap functions that can be called with ommitted arguments
|
||||
in the middle:
|
||||
<pre>
|
||||
void f(int x = 0, double y = 3.14, std::string z = std::string("foo"));
|
||||
|
||||
BOOST_PYTHON_MODULE(test)
|
||||
{
|
||||
def("f", f
|
||||
, (arg("x", 0), arg("y", 3.14), arg("z", "foo")));
|
||||
}
|
||||
|
||||
</pre>
|
||||
And in Python:
|
||||
<pre>
|
||||
>>> import test
|
||||
>>> f(0, z = "bar")
|
||||
>>> f(z = "bar", y = 0.0)
|
||||
</pre>
|
||||
Thanks, Nikolay!
|
||||
</dd>
|
||||
|
||||
<dt>22 July 2003</dt>
|
||||
|
||||
<dd>Killed the dreaded "bad argument type for builtin operation" error.
|
||||
Argument errors now show the actual and expected argument types!</dd>
|
||||
|
||||
<dt>19 July 2003</dt>
|
||||
|
||||
<dd>Added the new <code><a href=
|
||||
"v2/return_arg.html">return_arg</a></code> policy from <a href=
|
||||
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks,
|
||||
Nikolay!</dd>
|
||||
|
||||
<dt>18 March, 2003</dt>
|
||||
|
||||
<dd><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
|
||||
Ganßauge</a> has contributed <a href=
|
||||
"v2/opaque_pointer_converter.html">opaque pointer support</a>.<br>
|
||||
<a href="nicodemus-at-globalite.com.br">Bruno da Silva de Oliveira</a>
|
||||
has contributed the exciting <a href="../pyste/index.html">Pyste</a>
|
||||
("Pie-steh") package.</dd>
|
||||
|
||||
<dt>24 February 2003</dt>
|
||||
|
||||
<dd>Finished improved support
|
||||
for <code>boost::shared_ptr</code>. Now any wrapped object of
|
||||
C++ class <code>X</code> can be converted automatically
|
||||
to <code>shared_ptr<X></code>, regardless of how it was
|
||||
wrapped. The <code>shared_ptr</code> will manage the lifetime
|
||||
of the Python object which supplied the <code>X</code>, rather
|
||||
than just the <code>X</code> object itself, and when such
|
||||
a <code>shared_ptr</code> is converted back to Python, the
|
||||
original Python object will be returned.</dd>
|
||||
|
||||
<dd>Finished improved support for <code>boost::shared_ptr</code>. Now
|
||||
any wrapped object of C++ class <code>X</code> can be converted
|
||||
automatically to <code>shared_ptr<X></code>, regardless of how it
|
||||
was wrapped. The <code>shared_ptr</code> will manage the lifetime of
|
||||
the Python object which supplied the <code>X</code>, rather than just
|
||||
the <code>X</code> object itself, and when such a
|
||||
<code>shared_ptr</code> is converted back to Python, the original
|
||||
Python object will be returned.</dd>
|
||||
|
||||
<dt>19 January 2003</dt>
|
||||
|
||||
<dd>Integrated <code>staticmethod</code> support from <a href=
|
||||
@@ -98,12 +180,12 @@
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
20 December, 2002
|
||||
11 September 2003
|
||||
<!--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>
|
||||
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="boost.css">
|
||||
|
||||
@@ -38,28 +38,23 @@
|
||||
page .</p>
|
||||
<hr>
|
||||
|
||||
<h3>Enterprise Software</h3>
|
||||
<h3>Data Analysis</h3>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
|
||||
<dt><b><a href=
|
||||
"http://www.neuralynx.com/neuralab/index.htm">NeuraLab</a></b></dt>
|
||||
|
||||
<dd>
|
||||
The OpenWBEM project is an effort to develop an open-source
|
||||
implementation of Web Based Enterprise Management suitable for
|
||||
commercial and non-commercial application
|
||||
|
||||
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
|
||||
|
||||
<blockquote>
|
||||
I'm using Boost.Python to wrap the client API of OpenWBEM.This will
|
||||
make it easier to do rapid prototyping, testing, and scripting when
|
||||
developing management solutions that use WBEM.
|
||||
</blockquote>
|
||||
</dd>
|
||||
<dd>Neuralab is a data analysis environment specifically tailored for
|
||||
neural data from <a href="http://www.neuralynx.com">Neuralynx</a>
|
||||
acquisition systems. Neuralab combines presentation quality graphics, a
|
||||
numerical analysis library, and the <a href=
|
||||
"http://www.python.org">Python</a> scripting engine in a single
|
||||
application. With Neuralab, Neuralynx users can perform common analysis
|
||||
tasks with just a few mouse clicks. More advanced users can create
|
||||
custom Python scripts, which can optionally be assigned to menus and
|
||||
mouse clicks.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Financial Analysis</h3>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><b>TSLib</b> - <a href="http://www.fortressinv.com">Fortress
|
||||
Investment Group LLC</a></dt>
|
||||
@@ -87,30 +82,85 @@
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Educational</h3>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="http://edu.kde.org/kig"><b>Kig</b></a></dt>
|
||||
|
||||
<dd>
|
||||
<p>KDE Interactive Geometry is a high-school level educational tool,
|
||||
built for the KDE desktop. It is a nice tool to let students work
|
||||
with geometrical constructions. It is meant to be the most intuitive,
|
||||
yet featureful application of its kind.</p>
|
||||
|
||||
<p>Versions after 0.6.x (will) support objects built by the user
|
||||
himself in the Python language. The exporting of the relevant
|
||||
internal API's were done using Boost.Python, which made the process
|
||||
very easy.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Enterprise Software</h3>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
|
||||
|
||||
<dd>
|
||||
The OpenWBEM project is an effort to develop an open-source
|
||||
implementation of Web Based Enterprise Management suitable for
|
||||
commercial and non-commercial application
|
||||
|
||||
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
|
||||
|
||||
<blockquote>
|
||||
I'm using Boost.Python to wrap the client API of OpenWBEM.This will
|
||||
make it easier to do rapid prototyping, testing, and scripting when
|
||||
developing management solutions that use WBEM.
|
||||
</blockquote>
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="http://www.transversal.com">Metafaq</a></b></dt>
|
||||
|
||||
<dd>
|
||||
Metafaq, from <a href="http://www.transversal.com">Transversal,
|
||||
Inc.</a>, is an enterprise level online knowledge base management
|
||||
system.
|
||||
|
||||
<p><a href="mailto:ben.young-at-transversal.com">Ben Young</a>
|
||||
writes:</p>
|
||||
|
||||
<blockquote>
|
||||
Boost.Python is used in an automated process to generate python
|
||||
bindings to our api which is exposed though multiple backends and
|
||||
frontends. This allows us to write quick tests and bespoke scripts
|
||||
to perform one off tasks without having to go through the full
|
||||
compilation cycle.
|
||||
</blockquote>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Graphics</h3>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><b><a href=
|
||||
"http://www.openscenegraph.org">OpenSceneGraph</a></b></dt>
|
||||
<dt><b><a href="http://sourceforge.net/projects/pyosg">OpenSceneGraph
|
||||
Bindings</a></b></dt>
|
||||
|
||||
<dd><a href="mailto:gideon@computer.org">Gideon May</a> has created a
|
||||
set of bindings for OpenSceneGraph, a cross-platform C++/OpenGL library
|
||||
for the real-time visualization. You can read the release announcement
|
||||
at <a href="http://www.hypereyes.com">www.hypereyes.com</a>. <a href=
|
||||
"mailto:gideon@computer.org">Contact Gideon</a> for more
|
||||
information.<br>
|
||||
set of bindings for <a href=
|
||||
"http://www.openscenegraph.org">OpenSceneGraph</a>, a cross-platform
|
||||
C++/OpenGL library for the real-time visualization.<br>
|
||||
</dd>
|
||||
|
||||
<dt><a href=
|
||||
"http://pythonmagick.procoders.net/"><b>PythonMagick</b></a></dt>
|
||||
"http://www.procoders.net/pythonmagick"><b>PythonMagick</b></a></dt>
|
||||
|
||||
<dd>PythonMagick binds the <a href=
|
||||
"http://www.imagemagick.org">ImageMagick</a> image manipulation library
|
||||
to Python.<br>
|
||||
"http://www.graphicsmagick.org">GraphicsMagick</a> image manipulation
|
||||
library to Python.<br>
|
||||
</dd>
|
||||
|
||||
<dt><b>HippoDraw</b> - <a href="http://www.slac.stanford.edu">Stanford
|
||||
Linear Accelerator Center</a></dt>
|
||||
<dt><b><a href=
|
||||
"http://www.slac.stanford.edu/grp/ek/hippodraw/index.html">HippoDraw</a></b></dt>
|
||||
|
||||
<dd>
|
||||
HippoDraw is a data analysis environment consisting of a canvas upon
|
||||
@@ -120,8 +170,8 @@
|
||||
so that all the manipulation can be done from either Python or the
|
||||
GUI.
|
||||
|
||||
<p><a href="mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a>
|
||||
writes:</p>
|
||||
<p>Before the web page came online, <a href=
|
||||
"mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a> wrote:</p>
|
||||
|
||||
<blockquote>
|
||||
Don't have a web page for the project, but the organization's is <a
|
||||
@@ -207,17 +257,88 @@
|
||||
Boost.Python plays and essential role.</p>
|
||||
</blockquote>
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="http://www.esss.com.br">ESSS</a></b></dt>
|
||||
|
||||
<dd>
|
||||
ESSS (Engineering Simulation and Scientific Software) is a company
|
||||
that provides engineering solutions and acts in the brazilian and
|
||||
south-american market providing products and services related to
|
||||
Computational Fluid Dynamics and Image Analysis.
|
||||
|
||||
<p><a href="mailto:bruno@esss.com.br">Bruno da Silva de Oliveira</a>
|
||||
writes:</p>
|
||||
|
||||
<blockquote>
|
||||
Recently we moved our work from working exclusively with C++ to an
|
||||
hybrid-language approach, using Python and C++, with Boost.Python
|
||||
providing the layer between the two. The results are great so far!
|
||||
</blockquote>
|
||||
|
||||
<p>Two projects have been developed so far with this technology:</p>
|
||||
|
||||
<p><b><a href="http://www.esss.com.br/dev_simba.phtml">Simba</a></b>
|
||||
provides 3D visualization of geological formations gattered from the
|
||||
simulation of the evolution of oil systems, allowing the user to
|
||||
analyse various aspects of the simulation, like deformation, pressure
|
||||
and fluids, along the time of the simulation.</p>
|
||||
|
||||
<p><b><a href="http://www.esss.com.br/dev_aero.phtml">Aero</a></b>
|
||||
aims to construct a CFD with brazilian technology, which involves
|
||||
various companies and universities. ESSS is responsible for various
|
||||
of the application modules, including GUI and post-processing of
|
||||
results.</p>
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
|
||||
LLC</a></b></dt>
|
||||
|
||||
<dd>
|
||||
Rational Discovery provides computational modeling, combinatorial
|
||||
library design and custom software development services to the
|
||||
pharmaceutical, biotech and chemical industries. We do a substantial
|
||||
amount of internal research to develop new approaches for applying
|
||||
machine-learning techniques to solve chemical problems. Because we're
|
||||
a small organization and chemistry is a large and complex field, it
|
||||
is essential that we be able to quickly and easily prototype and test
|
||||
new algorithms.
|
||||
|
||||
<p>For our internal software, we implement core data structures in C
|
||||
and expose them to Python using Boost.Python. Algorithm development
|
||||
is done in Python and then translated to C if required (often it's
|
||||
not). This hybrid development approach not only greatly increases our
|
||||
productivity, but it also allows "non-developers" (people without C
|
||||
experience) to take part in method development. Learning C is a
|
||||
daunting task, but "Python fits your brain." (Thanks to Bruce Eckel
|
||||
for the quote.)</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Tools</h3>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://www.jayacard.org"><b>Jayacard</b></a></dt>
|
||||
|
||||
<dd>
|
||||
Jayacard aims at developing a secure portable open source operating
|
||||
system for contactless smart cards and a complete suite of high
|
||||
quality development tools to ease smart card OS and application
|
||||
development.
|
||||
|
||||
<p>The core of the smart card reader management is written in C++ but
|
||||
all the development tools are written in the friendly Python
|
||||
language. Boost plays the fundamental role of binding the tools to
|
||||
our core smart card reader library.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
16 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
15 July, 2003</p>
|
||||
|
||||
<p><i>© Copyright <a href="../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i></p>
|
||||
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="boost.css">
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<p>This is a list of available resources for support with Boost.Python
|
||||
problems and feature requests.</p>
|
||||
problems and feature requests. <b>Please try to resist emailing the
|
||||
Boost.Python developers directly for support.</b> Use the following
|
||||
resources instead; the developers are listening!</p>
|
||||
<hr>
|
||||
|
||||
<dl class="page-index">
|
||||
@@ -41,9 +43,11 @@
|
||||
you Boost.Python.<br>
|
||||
</dt>
|
||||
|
||||
<dt><b><a href="http://www.python.org/sigs/c++-sig/">The Python
|
||||
<dt><b><a href=
|
||||
"http://www.boost.org/more/mailing_lists.htm#cplussig">The Python
|
||||
C++-sig</a></b> mailing list is a forum for discussing Python/C++
|
||||
interoperability, and Boost.Python in particular.<br>
|
||||
interoperability, and Boost.Python in particular. Post your
|
||||
Boost.Python questions here.<br>
|
||||
</dt>
|
||||
|
||||
<dt>The <b>Boost.Python <a href=
|
||||
@@ -51,18 +55,17 @@
|
||||
Pages</a></b> established by Mike Rovner as part of the <a href=
|
||||
"http://www.python.org/cgi-bin/moinmoin">PythonInfo Wiki</a> serves as
|
||||
a forum to gather peoples' experience and as a cookbook.<br>
|
||||
</dt>
|
||||
</dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
17 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
12 Sept, 2003 <!--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>
|
||||
Abrahams</a> 2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -32,12 +32,15 @@ with every boost distribution: <b>bjam</b>.</p>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
<img src="theme/lens.gif"></img> <b>Building without bjam</b><br><br>
|
||||
|
||||
Besides bjam, there are of course other ways to get your module built.
|
||||
What's written here should not be taken as "the one and only way".
|
||||
There are of course other build tools apart from <tt>bjam</tt>.
|
||||
</td>
|
||||
<p><img src="theme/lens.gif"></img> <b>Building without bjam</b><br>
|
||||
<br>
|
||||
Besides bjam, there are of course other ways to get your module built.
|
||||
What's written here should not be taken as "the one and only way".
|
||||
There are of course other build tools apart from <tt>bjam</tt>. </p>
|
||||
<p>Take note however that the preferred build tool for Boost.Python is <tt>bjam</tt>.
|
||||
There are so many ways to set up the build incorrectly. Experience shows
|
||||
that 90% of the "I can't build Boost.Python" problems come from
|
||||
people who had to use a different tool<tt></tt>.</p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
|
||||
@@ -83,7 +83,7 @@ respectively. In our <tt>foo</tt> function the minimum number of arguments is 1
|
||||
and the maximum number of arguments is 4. The <tt>def(...)</tt> function will
|
||||
automatically add all the foo variants for us:</p>
|
||||
<code><pre>
|
||||
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>"foo"</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
|
||||
<span class=identifier>def</span><span class=special>(</span><span class=string>"foo"</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
|
||||
</span></pre></code>
|
||||
<a name="boost_python_member_function_overloads"></a><h2>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</h2><p>
|
||||
Objects here, objects there, objects here there everywhere. More frequently
|
||||
|
||||
@@ -62,6 +62,11 @@ with every boost distribution: [*bjam].
|
||||
Besides bjam, there are of course other ways to get your module built.
|
||||
What's written here should not be taken as "the one and only way".
|
||||
There are of course other build tools apart from [^bjam].
|
||||
|
||||
Take note however that the preferred build tool for Boost.Python is bjam.
|
||||
There are so many ways to set up the build incorrectly. Experience shows
|
||||
that 90% of the "I can't build Boost.Python" problems come from people
|
||||
who had to use a different tool.
|
||||
]
|
||||
|
||||
We shall skip over the details. Our objective will be to simply create the
|
||||
@@ -994,7 +999,7 @@ respectively. In our [^foo] function the minimum number of arguments is 1
|
||||
and the maximum number of arguments is 4. The [^def(...)] function will
|
||||
automatically add all the foo variants for us:
|
||||
|
||||
.def("foo", foo, foo_overloads());
|
||||
def("foo", foo, foo_overloads());
|
||||
|
||||
[h2 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
|
||||
|
||||
@@ -1330,6 +1335,258 @@ create a new scope around a class:
|
||||
.value("blue", blue)
|
||||
;
|
||||
|
||||
[def Py_Initialize [@http://www.python.org/doc/current/api/initialization.html#l2h-652 Py_Initialize]]
|
||||
[def Py_Finalize [@http://www.python.org/doc/current/api/initialization.html#l2h-656 Py_Finalize]]
|
||||
[def PyRun_String [@http://www.python.org/doc/current/api/veryhigh.html#l2h-55 PyRun_String]]
|
||||
[def PyRun_File [@http://www.python.org/doc/current/api/veryhigh.html#l2h-56 PyRun_File]]
|
||||
[def Py_eval_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-58 Py_eval_input]]
|
||||
[def Py_file_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-59 Py_file_input]]
|
||||
[def Py_single_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-60 Py_single_input]]
|
||||
[def Py_XINCREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-65 Py_XINCREF]]
|
||||
[def Py_XDECREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-67 Py_XDECREF]]
|
||||
[def PyImport_AppendInittab [@http://www.python.org/doc/current/api/importing.html#l2h-137 PyImport_AppendInittab]]
|
||||
[def PyImport_AddModule [@http://www.python.org/doc/current/api/importing.html#l2h-125 PyImport_AddModule]]
|
||||
[def PyModule_New [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-591 PyModule_New]]
|
||||
[def PyModule_GetDict [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-594 PyModule_GetDict]]
|
||||
|
||||
[page:0 Embedding]
|
||||
|
||||
By now you should know how to use Boost.Python to call your C++ code from
|
||||
Python. However, sometimes you may need to do the reverse: call Python code
|
||||
from the C++-side. This requires you to ['embed] the Python interpreter
|
||||
into your C++ program.
|
||||
|
||||
Currently, Boost.Python does not directly support everything you'll need
|
||||
when embedding. Therefore you'll need to use the
|
||||
[@http://www.python.org/doc/current/api/api.html Python/C API] to fill in
|
||||
the gaps. However, Boost.Python already makes embedding a lot easier and,
|
||||
in a future version, it may become unnecessary to touch the Python/C API at
|
||||
all. So stay tuned... :-)
|
||||
|
||||
[h2 Building embedded programs]
|
||||
|
||||
To be able to use embedding in your programs, they have to be linked to
|
||||
both Boost.Python's and Python's static link library.
|
||||
|
||||
Boost.Python's static link library comes in two variants. Both are located
|
||||
in Boost's [^/libs/python/build/bin-stage] subdirectory. On Windows, the
|
||||
variants are called [^boost_python.lib] (for release builds) and
|
||||
[^boost_python_debug.lib] (for debugging). If you can't find the libraries,
|
||||
you probably haven't built Boost.Python yet. See [@../../building.html
|
||||
Building and Testing] on how to do this.
|
||||
|
||||
Python's static link library can be found in the [^/libs] subdirectory of
|
||||
your Python directory. On Windows it is called pythonXY.lib where X.Y is
|
||||
your major Python version number.
|
||||
|
||||
Additionally, Python's [^/include] subdirectory has to be added to your
|
||||
include path.
|
||||
|
||||
In a Jamfile, all the above boils down to:
|
||||
|
||||
[pre
|
||||
projectroot c:\projects\embedded_program ; # location of the program
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include python.jam ;
|
||||
|
||||
exe embedded_program # name of the executable
|
||||
: #sources
|
||||
embedded_program.cpp
|
||||
: # requirements
|
||||
<find-library>boost_python <library-path>c:\boost\libs\python
|
||||
$(PYTHON_PROPERTIES)
|
||||
<library-path>$(PYTHON_LIB_PATH)
|
||||
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
|
||||
]
|
||||
|
||||
[h2 Getting started]
|
||||
|
||||
Being able to build is nice, but there is nothing to build yet. Embedding
|
||||
the Python interpreter into one of your C++ programs requires these 4
|
||||
steps:
|
||||
|
||||
# '''#include''' [^<boost/python.hpp>][br][br]
|
||||
|
||||
# Call Py_Initialize() to start the interpreter and create the [^__main__] module.[br][br]
|
||||
|
||||
# Call other Python C API routines to use the interpreter.[br][br]
|
||||
|
||||
# Call Py_Finalize() to stop the interpreter and release its resources.
|
||||
|
||||
(Of course, there can be other C++ code between all of these steps.)
|
||||
|
||||
[:['[*Now that we can embed the interpreter in our programs, lets see how to put it to use...]]]
|
||||
|
||||
[page:1 Using the interpreter]
|
||||
|
||||
As you probably already know, objects in Python are reference-counted.
|
||||
Naturally, the [^PyObject]s of the Python/C API are also reference-counted.
|
||||
There is a difference however. While the reference-counting is fully
|
||||
automatic in Python, the Python/C API requires you to do it
|
||||
[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
|
||||
messy and especially hard to get right in the presence of C++ exceptions.
|
||||
Fortunately Boost.Python provides the [@../../v2/handle.html handle] class
|
||||
template to automate the process.
|
||||
|
||||
[h2 Reference-counting handles]
|
||||
|
||||
There are two ways in which a function in the Python/C API can return a
|
||||
[^PyObject*]: as a ['borrowed reference] or as a ['new reference]. Which of
|
||||
these a function uses, is listed in that function's documentation. The two
|
||||
require slightely different approaches to reference-counting but both can
|
||||
be 'handled' by Boost.Python.
|
||||
|
||||
For a function returning a ['borrowed reference] we'll have to tell the
|
||||
[^handle] that the [^PyObject*] is borrowed with the aptly named
|
||||
[@../../v2/handle.html#borrowed-spec borrowed] function. Two functions
|
||||
returning borrowed references are PyImport_AddModule and PyModule_GetDict.
|
||||
The former returns a reference to an already imported module, the latter
|
||||
retrieves a module's namespace dictionary. Let's use them to retrieve the
|
||||
namespace of the [^__main__] module:
|
||||
|
||||
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
|
||||
handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
|
||||
|
||||
Because the Python/C API doesn't know anything about [^handle]s, we used
|
||||
the [@../../v2/handle.html#handle-spec-observers get] member function to
|
||||
retrieve the [^PyObject*] from which the [^handle] was constructed.
|
||||
|
||||
For a function returning a ['new reference] we can just create a [^handle]
|
||||
out of the raw [^PyObject*] without wrapping it in a call to borrowed. One
|
||||
such function that returns a new reference is PyRun_String which we'll
|
||||
discuss in the next section.
|
||||
|
||||
[blurb __detail__ [*Handle is a class ['template], so why haven't we been using any template parameters?][br]
|
||||
[br]
|
||||
[^handle] has a single template parameter specifying the type of the managed object. This type is [^PyObject] 99% of the time, so the parameter was defaulted to [^PyObject] for convenience. Therefore we can use the shorthand [^handle<>] instead of the longer, but equivalent, [^handle<PyObject>].
|
||||
]
|
||||
|
||||
[h2 Running Python code]
|
||||
|
||||
To run Python code from C++ there is a family of functions in the API
|
||||
starting with the PyRun prefix. You can find the full list of these
|
||||
functions [@http://www.python.org/doc/current/api/veryhigh.html here]. They
|
||||
all work similarly so we will look at only one of them, namely:
|
||||
|
||||
PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
|
||||
|
||||
PyRun_String takes the code to execute as a null-terminated (C-style)
|
||||
string in its [^str] parameter. The function returns a new reference to a
|
||||
Python object. Which object is returned depends on the [^start] paramater.
|
||||
|
||||
The [^start] parameter is the start symbol from the Python grammar to use
|
||||
for interpreting the code. The possible values are:
|
||||
|
||||
[table Start symbols
|
||||
|
||||
[Py_eval_input] [for interpreting isolated expressions]
|
||||
[Py_file_input] [for interpreting sequences of statements]
|
||||
[Py_single_input] [for interpreting a single statement]
|
||||
]
|
||||
|
||||
When using Py_eval_input, the input string must contain a single expression
|
||||
and its result is returned. When using Py_file_input, the string can
|
||||
contain an abitrary number of statements and None is returned.
|
||||
Py_single_input works in the same way as Py_file_input but only accepts a
|
||||
single statement.
|
||||
|
||||
Lastly, the [^globals] and [^locals] parameters are Python dictionaries
|
||||
containing the globals and locals of the context in which to run the code.
|
||||
For most intents and purposes you can use the namespace dictionary of the
|
||||
[^__main__] module for both parameters.
|
||||
|
||||
We have already seen how to get the [^__main__] module's namespace so let's
|
||||
run some Python code in it:
|
||||
|
||||
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
|
||||
handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
|
||||
handle<>( PyRun_String("hello = file('hello.txt', 'w')\n"
|
||||
"hello.write('Hello world!')\n"
|
||||
"hello.close()", Py_file_input,
|
||||
main_namespace.get(), main_namespace.get()) );
|
||||
|
||||
This should create a file called 'hello.txt' in the current directory
|
||||
containing a phrase that is well-known in programming circles.
|
||||
|
||||
__note__ [*Note] that we wrap the return value of PyRun_String in a
|
||||
(nameless) [^handle] even though we are not interested in it. If we didn't
|
||||
do this, the the returned object would be kept alive unnecessarily. Unless
|
||||
you want to be a Dr. Frankenstein, always wrap [^PyObject*]s in [^handle]s.
|
||||
|
||||
[h2 Beyond handles]
|
||||
|
||||
It's nice that [^handle] manages the reference counting details for us, but
|
||||
other than that it doesn't do much. Often we'd like to have a more useful
|
||||
class to manipulate Python objects. But we have already seen such a class
|
||||
in the [@object_interface.html previous section]: the aptly named [^object]
|
||||
class and it's derivatives. What we haven't seen, is that they can be
|
||||
constructed from a [^handle]. The following examples should illustrate this
|
||||
fact:
|
||||
|
||||
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
|
||||
dict main_namespace(handle<>(borrowed( PyModule_GetDict(main_module.get()) )));
|
||||
handle<>( PyRun_String("result = 5 ** 2", Py_file_input,
|
||||
main_namespace.ptr(), main_namespace.ptr()) );
|
||||
int five_squared = extract<int>( main_namespace["result"] );
|
||||
|
||||
Here we create a dictionary object for the [^__main__] module's namespace.
|
||||
Then we assign 5 squared to the result variable and read this variable from
|
||||
the dictionary. Another way to achieve the same result is to let
|
||||
PyRun_String return the result directly with Py_eval_input:
|
||||
|
||||
object result(handle<>( PyRun_String("5 ** 2", Py_eval_input,
|
||||
main_namespace.ptr(), main_namespace.ptr()) ));
|
||||
int five_squared = extract<int>(result);
|
||||
|
||||
__note__ [*Note] that [^object]'s member function to return the wrapped
|
||||
[^PyObject*] is called [^ptr] instead of [^get]. This makes sense if you
|
||||
take into account the different functions that [^object] and [^handle]
|
||||
perform.
|
||||
|
||||
[h2 Exception handling]
|
||||
|
||||
If an exception occurs in the execution of some Python code, the PyRun_String function returns a null pointer. Constructing a [^handle] out of this null pointer throws [@../../v2/errors.html#error_already_set-spec error_already_set], so basically, the Python exception is automatically translated into a C++ exception when using [^handle]:
|
||||
|
||||
try
|
||||
{
|
||||
object result(handle<>( PyRun_String("5/0", Py_eval_input,
|
||||
main_namespace.ptr(), main_namespace.ptr()) ));
|
||||
// execution will never get here:
|
||||
int five_divided_by_zero = extract<int>(result);
|
||||
}
|
||||
catch(error_already_set)
|
||||
{
|
||||
// handle the exception in some way
|
||||
}
|
||||
|
||||
The [^error_already_set] exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the [@http://www.python.org/doc/api/exceptionHandling.html exception handling functions] of the Python/C API in your catch-statement. This can be as simple as calling [@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to print the exception's traceback to the console, or comparing the type of the exception with those of the [@http://www.python.org/doc/api/standardExceptions.html standard exceptions]:
|
||||
|
||||
catch(error_already_set)
|
||||
{
|
||||
if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
|
||||
{
|
||||
// handle ZeroDivisionError specially
|
||||
}
|
||||
else
|
||||
{
|
||||
// print all other errors to stderr
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
|
||||
(To retrieve even more information from the exception you can use some of the other exception handling functions listed [@http://www.python.org/doc/api/exceptionHandling.html here].)
|
||||
|
||||
If you'd rather not have [^handle] throw a C++ exception when it is constructed, you can use the [@../../v2/handle.html#allow_null-spec allow_null] function in the same way you'd use borrowed:
|
||||
|
||||
handle<> result(allow_null( PyRun_String("5/0", Py_eval_input,
|
||||
main_namespace.ptr(), main_namespace.ptr()) ));
|
||||
if (!result)
|
||||
// Python exception occurred
|
||||
else
|
||||
// everything went okay, it's safe to use the result
|
||||
|
||||
[page Iterators]
|
||||
|
||||
In C++, and STL in particular, we see iterators everywhere. Python also has
|
||||
@@ -1424,3 +1681,321 @@ Users may provide custom translation. Here's an example:
|
||||
PodBayDoorException>(translator);
|
||||
...
|
||||
|
||||
[page General Techniques]
|
||||
|
||||
Here are presented some useful techniques that you can use while wrapping code with Boost.Python.
|
||||
|
||||
[page:1 Creating Packages]
|
||||
|
||||
A Python package is a collection of modules that provide to the user a certain
|
||||
functionality. If you're not familiar on how to create packages, a good
|
||||
introduction to them is provided in the
|
||||
[@http://www.python.org/doc/current/tut/node8.html Python Tutorial].
|
||||
|
||||
But we are wrapping C++ code, using Boost.Python. How can we provide a nice
|
||||
package interface to our users? To better explain some concepts, let's work
|
||||
with an example.
|
||||
|
||||
We have a C++ library that works with sounds: reading and writing various
|
||||
formats, applying filters to the sound data, etc. It is named (conveniently)
|
||||
[^sounds]. Our library already has a neat C++ namespace hierarchy, like so:
|
||||
|
||||
sounds::core
|
||||
sounds::io
|
||||
sounds::filters
|
||||
|
||||
We would like to present this same hierarchy to the Python user, allowing him
|
||||
to write code like this:
|
||||
|
||||
import sounds.filters
|
||||
sounds.filters.echo(...) # echo is a C++ function
|
||||
|
||||
The first step is to write the wrapping code. We have to export each module
|
||||
separately with Boost.Python, like this:
|
||||
|
||||
/* file core.cpp */
|
||||
BOOST_PYTHON_MODULE(core)
|
||||
{
|
||||
/* export everything in the sounds::core namespace */
|
||||
...
|
||||
}
|
||||
|
||||
/* file io.cpp */
|
||||
BOOST_PYTHON_MODULE(io)
|
||||
{
|
||||
/* export everything in the sounds::io namespace */
|
||||
...
|
||||
}
|
||||
|
||||
/* file filters.cpp */
|
||||
BOOST_PYTHON_MODULE(filters)
|
||||
{
|
||||
/* export everything in the sounds::filters namespace */
|
||||
...
|
||||
}
|
||||
|
||||
Compiling these files will generate the following Python extensions:
|
||||
[^core.pyd], [^io.pyd] and [^filters.pyd].
|
||||
|
||||
[blurb __note__ The extension [^.pyd] is used for python extension modules, which
|
||||
are just shared libraries. Using the default for your system, like [^.so] for
|
||||
Unix and [^.dll] for Windows, works just as well.]
|
||||
|
||||
Now, we create this directory structure for our Python package:
|
||||
|
||||
[pre
|
||||
sounds/
|
||||
__init__.py
|
||||
core.pyd
|
||||
filters.pyd
|
||||
io.pyd
|
||||
]
|
||||
|
||||
The file [^__init__.py] is what tells Python that the directory [^sounds/] is
|
||||
actually a Python package. It can be a empty file, but can also perform some
|
||||
magic, that will be shown later.
|
||||
|
||||
Now our package is ready. All the user has to do is put [^sounds] into his
|
||||
[@http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000 PYTHONPATH] and fire up the interpreter:
|
||||
|
||||
>>> import sounds.io
|
||||
>>> import sounds.filters
|
||||
>>> sound = sounds.io.open('file.mp3')
|
||||
>>> new_sound = sounds.filters.echo(sound, 1.0)
|
||||
|
||||
Nice heh?
|
||||
|
||||
This is the simplest way to create hierarchies of packages, but it is not very
|
||||
flexible. What if we want to add a ['pure] Python function to the filters
|
||||
package, for instance, one that applies 3 filters in a sound object at once?
|
||||
Sure, you can do this in C++ and export it, but why not do so in Python? You
|
||||
don't have to recompile the extension modules, plus it will be easier to write
|
||||
it.
|
||||
|
||||
If we want this flexibility, we will have to complicate our package hierarchy a
|
||||
little. First, we will have to change the name of the extension modules:
|
||||
|
||||
/* file core.cpp */
|
||||
BOOST_PYTHON_MODULE(_core)
|
||||
{
|
||||
...
|
||||
/* export everything in the sounds::core namespace */
|
||||
}
|
||||
|
||||
Note that we added an underscore to the module name. The filename will have to
|
||||
be changed to [^_core.pyd] as well, and we do the same to the other extension modules.
|
||||
Now, we change our package hierarchy like so:
|
||||
|
||||
[pre
|
||||
sounds/
|
||||
__init__.py
|
||||
core/
|
||||
__init__.py
|
||||
_core.pyd
|
||||
filters/
|
||||
__init__.py
|
||||
_filters.pyd
|
||||
io/
|
||||
__init__.py
|
||||
_io.pyd
|
||||
]
|
||||
|
||||
Note that we created a directory for each extension module, and added a
|
||||
__init__.py to each one. But if we leave it that way, the user will have to
|
||||
access the functions in the core module with this syntax:
|
||||
|
||||
>>> import sounds.core._core
|
||||
>>> sounds.core._core.foo(...)
|
||||
|
||||
which is not what we want. But here enters the [^__init__.py] magic: everything
|
||||
that is brought to the [^__init__.py] namespace can be accessed directly by the
|
||||
user. So, all we have to do is bring the entire namespace from [^_core.pyd]
|
||||
to [^core/__init__.py]. So add this line of code to [^sounds/core/__init__.py]:
|
||||
|
||||
from _core import *
|
||||
|
||||
We do the same for the other packages. Now the user accesses the functions and
|
||||
classes in the extension modules like before:
|
||||
|
||||
>>> import sounds.filters
|
||||
>>> sounds.filters.echo(...)
|
||||
|
||||
with the additional benefit that we can easily add pure Python functions to
|
||||
any module, in a way that the user can't tell the difference between a C++
|
||||
function and a Python function. Let's add a ['pure] Python function,
|
||||
[^echo_noise], to the [^filters] package. This function applies both the
|
||||
[^echo] and [^noise] filters in sequence in the given [^sound] object. We
|
||||
create a file named [^sounds/filters/echo_noise.py] and code our function:
|
||||
|
||||
import _filters
|
||||
def echo_noise(sound):
|
||||
s = _filters.echo(sound)
|
||||
s = _filters.noise(sound)
|
||||
return s
|
||||
|
||||
Next, we add this line to [^sounds/filters/__init__.py]:
|
||||
|
||||
from echo_noise import echo_noise
|
||||
|
||||
And that's it. The user now accesses this function like any other function
|
||||
from the [^filters] package:
|
||||
|
||||
>>> import sounds.filters
|
||||
>>> sounds.filters.echo_noise(...)
|
||||
|
||||
[page:1 Extending Wrapped Objects in Python]
|
||||
|
||||
Thanks to Python's flexibility, you can easily add new methods to a class,
|
||||
even after it was already created:
|
||||
|
||||
>>> class C(object): pass
|
||||
>>>
|
||||
>>> # a regular function
|
||||
>>> def C_str(self): return 'A C instance!'
|
||||
>>>
|
||||
>>> # now we turn it in a member function
|
||||
>>> C.__str__ = C_str
|
||||
>>>
|
||||
>>> c = C()
|
||||
>>> print c
|
||||
A C instance!
|
||||
>>> C_str(c)
|
||||
A C instance!
|
||||
|
||||
Yes, Python rox. :-)
|
||||
|
||||
We can do the same with classes that were wrapped with Boost.Python. Suppose
|
||||
we have a class [^point] in C++:
|
||||
|
||||
class point {...};
|
||||
|
||||
BOOST_PYTHON_MODULE(_geom)
|
||||
{
|
||||
class_<point>("point")...;
|
||||
}
|
||||
|
||||
If we are using the technique from the previous session, [@creating_packages.html
|
||||
Creating Packages], we can code directly into [^geom/__init__.py]:
|
||||
|
||||
from _geom import *
|
||||
|
||||
# a regular function
|
||||
def point_str(self):
|
||||
return str((self.x, self.y))
|
||||
|
||||
# now we turn it into a member function
|
||||
point.__str__ = point_str
|
||||
|
||||
[*All] point instances created from C++ will also have this member function!
|
||||
This technique has several advantages:
|
||||
|
||||
* Cut down compile times to zero for these additional functions
|
||||
* Reduce the memory footprint to virtually zero
|
||||
* Minimize the need to recompile
|
||||
* Rapid prototyping (you can move the code to C++ if required without changing the interface)
|
||||
|
||||
You can even add a little syntactic sugar with the use of metaclasses. Let's
|
||||
create a special metaclass that "injects" methods in other classes.
|
||||
|
||||
# The one Boost.Python uses for all wrapped classes.
|
||||
# You can use here any class exported by Boost instead of "point"
|
||||
BoostPythonMetaclass = point.__class__
|
||||
|
||||
class injector(object):
|
||||
class __metaclass__(BoostPythonMetaclass):
|
||||
def __init__(self, name, bases, dict):
|
||||
for b in bases:
|
||||
if type(b) not in (self, type):
|
||||
for k,v in dict.items():
|
||||
setattr(b,k,v)
|
||||
return type.__init__(self, name, bases, dict)
|
||||
|
||||
# inject some methods in the point foo
|
||||
class more_point(injector, point):
|
||||
def __repr__(self):
|
||||
return 'Point(x=%s, y=%s)' % (self.x, self.y)
|
||||
def foo(self):
|
||||
print 'foo!'
|
||||
|
||||
Now let's see how it got:
|
||||
|
||||
>>> print point()
|
||||
Point(x=10, y=10)
|
||||
>>> point().foo()
|
||||
foo!
|
||||
|
||||
Another useful idea is to replace constructors with factory functions:
|
||||
|
||||
_point = point
|
||||
|
||||
def point(x=0, y=0):
|
||||
return _point(x, y)
|
||||
|
||||
In this simple case there is not much gained, but for constructurs with
|
||||
many overloads and/or arguments this is often a great simplification, again
|
||||
with virtually zero memory footprint and zero compile-time overhead for
|
||||
the keyword support.
|
||||
|
||||
[page:1 Reducing Compiling Time]
|
||||
|
||||
If you have ever exported a lot of classes, you know that it takes quite a good
|
||||
time to compile the Boost.Python wrappers. Plus the memory consumption can
|
||||
easily become too high. If this is causing you problems, you can split the
|
||||
class_ definitions in multiple files:
|
||||
|
||||
/* file point.cpp */
|
||||
#include <point.h>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
void export_point()
|
||||
{
|
||||
class_<point>("point")...;
|
||||
}
|
||||
|
||||
/* file triangle.cpp */
|
||||
#include <triangle.h>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
void export_triangle()
|
||||
{
|
||||
class_<triangle>("triangle")...;
|
||||
}
|
||||
|
||||
Now you create a file [^main.cpp], which contains the [^BOOST_PYTHON_MODULE]
|
||||
macro, and call the various export functions inside it.
|
||||
|
||||
void export_point();
|
||||
void export_triangle();
|
||||
|
||||
BOOST_PYTHON_MODULE(_geom)
|
||||
{
|
||||
export_point();
|
||||
export_triangle();
|
||||
}
|
||||
|
||||
Compiling and linking together all this files produces the same result as the
|
||||
usual approach:
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <point.h>
|
||||
#include <triangle.h>
|
||||
|
||||
BOOST_PYTHON_MODULE(_geom)
|
||||
{
|
||||
class_<point>("point")...;
|
||||
class_<triangle>("triangle")...;
|
||||
}
|
||||
|
||||
but the memory is kept under control.
|
||||
|
||||
This method is recommended too if you are developing the C++ library and
|
||||
exporting it to Python at the same time: changes in a class will only demand
|
||||
the compilation of a single cpp, instead of the entire wrapper code.
|
||||
|
||||
[blurb __note__ If you're exporting your classes with [@../../../pyste/index.html Pyste],
|
||||
take a look at the [^--multiple] option, that generates the wrappers in
|
||||
various files as demonstrated here.]
|
||||
|
||||
[blurb __note__ This method is useful too if you are getting the error message
|
||||
['"fatal error C1204:Compiler limit:internal structure overflow"] when compiling
|
||||
a large source file, as explained in the [@../../v2/faq.html#c1204 FAQ].]
|
||||
|
||||
@@ -145,13 +145,15 @@ previous section</a>: the aptly named <tt>object</tt>
|
||||
class and it's derivatives. What we haven't seen, is that they can be
|
||||
constructed from a <tt>handle</tt>. The following examples should illustrate this
|
||||
fact:</p>
|
||||
<code><pre>
|
||||
<code>
|
||||
<pre>
|
||||
<span class=identifier>handle</span><span class=special><> </span><span class=identifier>main_module</span><span class=special>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyImport_AddModule</span><span class=special>(</span><span class=string>"__main__"</span><span class=special>) ));
|
||||
</span><span class=identifier>main_namespace </span><span class=identifier>dict</span><span class=special>(</span><span class=identifier>handle</span><span class=special><>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyModule_GetDict</span><span class=special>(</span><span class=identifier>main_module</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) )));
|
||||
</span><span class=identifier>dict </span><span class=identifier>main_namespace</span><span class=special>(</span><span class=identifier>handle</span><span class=special><>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyModule_GetDict</span><span class=special>(</span><span class=identifier>main_module</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) )));
|
||||
</span><span class=identifier>handle</span><span class=special><>( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>"result = 5 ** 2"</span><span class=special>, </span><span class=identifier>Py_file_input</span><span class=special>,
|
||||
</span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>()) );
|
||||
</span><span class=keyword>int </span><span class=identifier>five_squared </span><span class=special>= </span><span class=identifier>extract</span><span class=special><</span><span class=keyword>int</span><span class=special>>( </span><span class=identifier>main_namespace</span><span class=special>[</span><span class=string>"result"</span><span class=special>] );
|
||||
</span></pre></code>
|
||||
</span></pre>
|
||||
</code>
|
||||
<p>
|
||||
Here we create a dictionary object for the <tt>__main__</tt> module's namespace.
|
||||
Then we assign 5 squared to the result variable and read this variable from
|
||||
|
||||
134
doc/v2/args.html
134
doc/v2/args.html
@@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
@@ -35,7 +35,31 @@
|
||||
|
||||
<dt><a href="#keyword-expression"><i>keyword-expressions</i></a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#arg-spec">class <code>arg</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#arg-synopsis">class <code>arg</code>
|
||||
synopsis</a></dt>
|
||||
|
||||
<dt><a href="#arg-ctor">class <code>arg</code>
|
||||
constructor</a></dt>
|
||||
|
||||
<dt><a href="#arg-operator">class <code>arg</code> template
|
||||
<code>operator =</code></a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#keyword-expression-operators"><i>Keyword-expression</i>
|
||||
operator <code>,</code></a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions (deprecated)</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
@@ -57,27 +81,95 @@
|
||||
|
||||
<p>A <b>keyword-expression</b> results in an object which holds a
|
||||
sequence of <a href="definitions.html#ntbs">ntbs</a>es, and whose type
|
||||
encodes the number of keywords specified.</p>
|
||||
encodes the number of keywords specified. The <b>keyword-expression</b>
|
||||
may contain default values for some or all of the keywords it holds</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="args-spec"></a><code>args(</code>...<code>)</code></h3>
|
||||
<h3><a name="arg-spec"></a><code>class arg;</code></h3>
|
||||
|
||||
<p>The objects of class arg are keyword-expressions holding one keyword (
|
||||
size one )</p>
|
||||
|
||||
<h4><a name="arg-synopsis"></a>Class <code>arg</code> synopsis</h4>
|
||||
<pre>
|
||||
<i>unspecified1</i> args(char const*);
|
||||
<i>unspecified2</i> args(char const*, char const*);
|
||||
.
|
||||
.
|
||||
.
|
||||
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
|
||||
namespace boost { namespace python
|
||||
{
|
||||
struct arg
|
||||
{
|
||||
template <class T>
|
||||
arg &perator = (T const &value);
|
||||
explicit arg (char const *name){elements[0].name = name;}
|
||||
};
|
||||
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="arg-ctor"></a>Class <code>arg</code> constructor</h4>
|
||||
<pre>
|
||||
arg(char const* name);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> Every argument must be a <a href=
|
||||
<dt><b>Requires:</b> The argument must be a <a href=
|
||||
"definitions.html#ntbs">ntbs</a>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> an object representing a <a href=
|
||||
"#keyword-expression"><i>keyword-expression</i></a> encapsulating the
|
||||
arguments passed.</dt>
|
||||
<dt><b>Effects:</b> Constructs an <code>arg</code> object holding a
|
||||
keyword with name <code>name</code>.</dt>
|
||||
</dl>
|
||||
|
||||
<h4><a name="arg-operator"></a>Class <code>arg</code> operator =</h4>
|
||||
<pre>
|
||||
template <class T> arg &operator = (T const &value);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> The argument must convertible to python.</dt>
|
||||
|
||||
<dt><b>Effects:</b> Assigns default value for the keyword.</dt>
|
||||
|
||||
<dt><b>Returns:</b> Reference to <code>this</code>.</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="keyword-expression-operators"><i>Keyword-expression</i>
|
||||
operator <code>,</code></a></h2>
|
||||
<pre>
|
||||
<i>keyword-expression</i> operator , (<i>keyword-expression</i>, const arg &kw) const
|
||||
<i>keyword-expression</i> operator , (<i>keyword-expression</i>, const char *name) const;
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> The argument <code>name</code> must be a <a href=
|
||||
"definitions.html#ntbs">ntbs</a>.</dt>
|
||||
|
||||
<dt><b>Effects:</b> Extends the <i>keyword-expression</i> argument with
|
||||
one more keyword.</dt>
|
||||
|
||||
<dt><b>Returns:</b> The extended <i>keyword-expression</i>.</dt>
|
||||
</dl>
|
||||
|
||||
<h2><font color="#7F7F7F"><a name="functions"></a>Functions
|
||||
(deprecated)</font></h2>
|
||||
|
||||
<h3><a name="args-spec"></a><code><font color=
|
||||
"#7F7F7F">args</font>(</code>...<code>)</code></h3>
|
||||
<pre>
|
||||
<font color="#7F7F7F"> <i>unspecified1</i> args(char const*);
|
||||
<i>unspecified2</i> args(char const*, char const*);
|
||||
.
|
||||
.
|
||||
.
|
||||
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
|
||||
</font>
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><font color="#7F7F7F"><b>Requires:</b> Every argument must be a <a
|
||||
href="definitions.html#ntbs">ntbs</a>.</font></dt>
|
||||
|
||||
<dt><font color="#7F7F7F"><b>Returns:</b> an object representing a <a
|
||||
href="#keyword-expression"><i>keyword-expression</i></a> encapsulating
|
||||
the arguments passed.</font></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
@@ -85,19 +177,21 @@
|
||||
#include <boost/python/def.hpp>
|
||||
using namespace boost::python;
|
||||
|
||||
int f(int x, int y, int z);
|
||||
int f(double x, double y, double z=0.0, double w=1.0);
|
||||
|
||||
BOOST_PYTHON_MODULE(xxx)
|
||||
{
|
||||
def("f", f, args("x", "y", "z"));
|
||||
def("f", f
|
||||
, ( arg("x"), "y", arg("z")=0.0, arg("w")=1.0 )
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Revised 05 November, 2001</p>
|
||||
<p>Revised 01 August, 2003</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003. All
|
||||
Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <class T
|
||||
<font color="#007F00"> , class Bases = bases<>
|
||||
<font color="#007F00"> , class Bases = bases<>
|
||||
, class HeldType = T
|
||||
, class NonCopyable = <i>unspecified</i>
|
||||
>
|
||||
@@ -261,12 +261,23 @@ namespace boost { namespace python
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D T::*pm);
|
||||
|
||||
// exposing static data members
|
||||
template <class D>
|
||||
class_& def_readonly(char const* name, D const& d);
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D& d);
|
||||
|
||||
// property creation
|
||||
template <class Get>
|
||||
void add_property(char const* name, Get const& fget);
|
||||
template <class Get, class Set>
|
||||
void add_property(char const* name, Get const& fget, Set const& fset);
|
||||
|
||||
template <class Get>
|
||||
void add_static_property(char const* name, Get const& fget);
|
||||
template <class Get, class Set>
|
||||
void add_static_property(char const* name, Get const& fget, Set const& fset);
|
||||
|
||||
// pickle support
|
||||
template <typename PickleSuite>
|
||||
self& def_pickle(PickleSuite const&);
|
||||
@@ -579,8 +590,40 @@ void add_property(char const* name, Get const& fget, Set const& fset);
|
||||
</dl>
|
||||
<br>
|
||||
<pre>
|
||||
template <class Get>
|
||||
void add_static_property(char const* name, Get const& fget);
|
||||
template <class Get, class Set>
|
||||
void add_static_property(char const* name, Get const& fget, Set const& fset);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>name</code> is an <a href=
|
||||
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
|
||||
"http://www.python.org/doc/current/ref/identifiers.html">identifier
|
||||
naming rules</a>.</dt>
|
||||
|
||||
<dt><b>Effects:</b> Creates a Boost.Python.StaticProperty object,
|
||||
passing <code><a href=
|
||||
"object.html#object-spec-ctors">object</a>(fget)</code> (and <code><a
|
||||
href="object.html#object-spec-ctors">object</a>(fset)</code> in the
|
||||
second form) to its constructor, then adds that property to the Python
|
||||
class under construction with the given attribute <code>name</code>.
|
||||
StaticProperty is a special subclass of Python's <a href=
|
||||
"http://www.python.org/2.2.2/descrintro.html#property"><code>property</code></a>
|
||||
class which can be called without an initial <code>self</code>
|
||||
argument.</dt>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
|
||||
<dt><b>Rationale:</b> Allows users to easily expose functions that can
|
||||
be invoked from Python with static attribute access syntax.</dt>
|
||||
</dl>
|
||||
<br>
|
||||
<pre>
|
||||
template <class D>
|
||||
class_& def_readonly(char const* name, D T::*pm);
|
||||
template <class D>
|
||||
class_& def_readonly(char const* name, D const& d);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
@@ -596,17 +639,26 @@ class_& def_readonly(char const* name, D T::*pm);
|
||||
this->add_property(name, <a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>(pm));
|
||||
</pre>
|
||||
and
|
||||
<pre>
|
||||
this->add_static_property(name, <a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>(pm));
|
||||
</pre>
|
||||
respectively.<br>
|
||||
<br>
|
||||
</dd>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
|
||||
<dt><b>Rationale:</b> Allows users to easily expose a class' data
|
||||
member such that it can be inspected from Python with a natural
|
||||
syntax.</dt>
|
||||
member or free variable such that it can be inspected from Python with
|
||||
a natural syntax.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D T::*pm);
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D& d);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
@@ -618,13 +670,21 @@ this->add_property(name, <a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
|
||||
"data_members.html#make_setter-spec">make_setter</a>(pm));
|
||||
</pre>
|
||||
and
|
||||
<pre>
|
||||
this->add_static_property(name, <a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
|
||||
"data_members.html#make_setter-spec">make_setter</a>(pm));
|
||||
</pre>
|
||||
respectively.<br>
|
||||
<br>
|
||||
</dd>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
|
||||
<dt><b>Rationale:</b> Allows users to easily expose a class' data
|
||||
member such that it can be inspected and set from Python with a natural
|
||||
syntax.</dt>
|
||||
<dt><b>Rationale:</b> Allows users to easily expose a class' data or
|
||||
free variable member such that it can be inspected and set from Python
|
||||
with a natural syntax.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <typename PickleSuite>
|
||||
@@ -714,8 +774,7 @@ class_<Derived, bases<Base> >("Derived");
|
||||
</pre>
|
||||
Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
5 August, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
|
||||
2267
doc/v2/containers.html
Executable file
2267
doc/v2/containers.html
Executable file
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
@@ -92,6 +92,39 @@ template <class C, class D, class Policies>
|
||||
callable object.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <class D>
|
||||
<a href="object.html#object-spec">object</a> make_getter(D const& d);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_getter(D const& d, Policies const& policies);
|
||||
|
||||
template <class D>
|
||||
<a href="object.html#object-spec">object</a> make_getter(D const* p);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_getter(D const* p, Policies const& policies);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
|
||||
"CallPolicies.html">CallPolicies</a>.</dt>
|
||||
|
||||
<dt><b>Effects:</b> Creates a Python callable object which accepts no
|
||||
arguments and returns <code>d</code> or <code>*p</code>, converted
|
||||
<code>to_python</code> on demand. If <code>policies</code> is supplied,
|
||||
it will be applied to the function as described <a href=
|
||||
"CallPolicies.html">here</a>. Otherwise, the library attempts to
|
||||
determine whether <code>D</code> is a user-defined class type, and if
|
||||
so uses <code><a href=
|
||||
"reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a></code></dt>
|
||||
|
||||
<dt>for <code>Policies</code>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> An instance of <a href=
|
||||
"object.html#object-spec">object</a> which holds the new Python
|
||||
callable object.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
<a name="make_setter-spec">template <class C, class D></a>
|
||||
<a href="object.html#object-spec">object</a> make_setter(D C::*pm);
|
||||
|
||||
@@ -116,6 +149,34 @@ template <class C, class D, class Policies>
|
||||
"object.html#object-spec">object</a> which holds the new Python
|
||||
callable object.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <class D>
|
||||
<a href="object.html#object-spec">object</a> make_setter(D& d);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_setter(D& d, Policies const& policies);
|
||||
|
||||
template <class D>
|
||||
<a href="object.html#object-spec">object</a> make_setter(D* p);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_setter(D* p, Policies const& policies);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
|
||||
"CallPolicies.html">CallPolicies</a>.</dt>
|
||||
|
||||
<dt><b>Effects:</b> Creates a Python callable object which accepts one
|
||||
argument, which is converted from Python to <code>D const&</code>
|
||||
and written into <code>d</code> or <code>*p</code>, respectively. If
|
||||
<code>policies</code> is supplied, it will be applied to the function
|
||||
as described <a href="CallPolicies.html">here</a>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> An instance of <a href=
|
||||
"object.html#object-spec">object</a> which holds the new Python
|
||||
callable object.</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
@@ -155,8 +216,7 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)
|
||||
|
||||
<p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
5 August, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
|
||||
135
doc/v2/def_visitor.html
Normal file
135
doc/v2/def_visitor.html
Normal file
@@ -0,0 +1,135 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<meta name="generator" content="Microsoft FrontPage 5.0">
|
||||
<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/def_visitor.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"><a href="../index.html"><font size="7">Boost.Python</font></a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/def_visitor.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="#def_visitor-spec">Class <code>def_visitor</code></a>
|
||||
<dd> <a href="#def_visitor-synopsis">Class <code>def_visitor</code>
|
||||
synopsis</a></dd>
|
||||
<dd> <a href="#def_visitor-requirements">Class <code>def_visitor</code>
|
||||
requirements</a></dd>
|
||||
</dl>
|
||||
<dt><a href="#examples">Example</a>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
|
||||
<p><code><boost/python/def_visitor.hpp></code> provides a generic visitation
|
||||
interface through which the <a href="class.html">class_</a> <b>def</b> member
|
||||
functionality can be extended non-intrusively to avoid cluttering the <a href="class.html">class_</a>
|
||||
interface. It declares the <code>def_visitor<T> </code>class template,
|
||||
which is parameterized on the derived type <tt>DerivedVisitor</tt>, which provides
|
||||
the actual <b>def</b> functionality through its <b>visit</b> member functions.
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="def_visitor-spec"></a>Class template <code>def_visitor<DerivedVisitor></code></h3>
|
||||
|
||||
|
||||
<p>The class def_visitor is a base class paramaterized by its derived class. The
|
||||
def_visitor class is a protocol class. Its derived class, DerivedVisitor, is
|
||||
expected to have a member function visit. The def_visitor class is never instantiated
|
||||
directly. Instead, an instance of its subclass, DerivedVisitor, is passed
|
||||
on as an argument to the <a href="class.html">class_</a> def member function.
|
||||
<h4>
|
||||
<a name="def_visitor-synopsis" id="def_visitor-synopsis"></a>Class <code>def_visitor </code>synopsis</h4>
|
||||
<pre>namespace boost { namespace python {
|
||||
|
||||
template <class DerivedVisitor>
|
||||
class def_visitor {};
|
||||
}</pre>
|
||||
<h3><a name="def_visitor-requirements"></a><code>def_visitor </code>requirements</h3>
|
||||
|
||||
|
||||
<p>The <span class="pre">client supplied class </span><span class="pre"></span><tt class="literal"><span class="pre">DerivedVisitor</span></tt>
|
||||
template parameter is expected to:
|
||||
<ul>
|
||||
<li>be privately derived from def_visitor</li>
|
||||
<li>grant friend access to class def_visitor_access</li>
|
||||
<li>define either or both visit member functions listed in the table below:</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<table border class="table">
|
||||
<tr>
|
||||
<td width="181" nowrap><b>Expression</b></td>
|
||||
<td width="85"><b>Return Type</b></td>
|
||||
<td width="330"><b>Requirements</b></td>
|
||||
<td width="259"><b>Effects</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap>visitor.visit(cls)</td>
|
||||
<td>void</td>
|
||||
<td>cls is an instance of a <a href="class.html">class_</a> being wrapped
|
||||
to Python. visitor is a def_visitor derived class.</td>
|
||||
<td>A call to cls.def(visitor) forwards to this member function.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap>visitor.visit(cls, name, options)</td>
|
||||
<td>void</td>
|
||||
<td>cls is a class_ instance, name is a C string. visitor is a def_visitor
|
||||
derived class. options is a context specific optional argument.</td>
|
||||
<td>A call to cls.def(name, visitor) or cls.def(name, visitor, options) forwards
|
||||
to this member function. </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
|
||||
<pre>class X {/*...*/};<br>
|
||||
class my_def_visitor : boost::python::def_visitor<my_def_visitor>
|
||||
{
|
||||
friend class def_visitor_access;
|
||||
|
||||
template <class classT>
|
||||
void visit(classT& c) const
|
||||
{
|
||||
c
|
||||
.def("foo", &my_def_visitor::foo)
|
||||
.def("bar", &my_def_visitor::bar)
|
||||
;
|
||||
}
|
||||
|
||||
static void foo(X& self);
|
||||
static void bar(X& self);
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(my_ext)
|
||||
{
|
||||
class_<X>("X")
|
||||
.def(my_def_visitor())
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->27 August, 2003<!--webbot bot="Timestamp" endspan i-checksum="34484" -->
|
||||
</p>
|
||||
|
||||
|
||||
<p><i>© Copyright Joel de Guzman 2003. All Rights Reserved.</i>
|
||||
@@ -57,6 +57,11 @@
|
||||
|
||||
<dt><a href="#ownership">How can I wrap a function which needs to take
|
||||
ownership of a raw pointer?</a></dt>
|
||||
|
||||
<dt><a href="#slow_compilation">Compilation takes too much time and eats too much memory!
|
||||
What can I do to make it faster?</a></dt>
|
||||
|
||||
<dt><a href="#packages">How do I create sub-packages using Boost.Python?</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
@@ -543,6 +548,20 @@ void b_insert(B& b, std::auto_ptr<A> a)
|
||||
"manage_new_object.html#manage_new_object-spec">manage_new_object</a></code>
|
||||
will also be held by <code>auto_ptr</code>, so this transfer-of-ownership
|
||||
will also work correctly.
|
||||
|
||||
<h2><a name="slow_compilation">Compilation takes too much time and eats too
|
||||
much memory! What can I do to make it faster?</a></h2>
|
||||
<p>
|
||||
Please refer to the <a href="../tutorial/doc/reducing_compiling_time.html">Techniques</a>
|
||||
section in the tutorial.
|
||||
</p>
|
||||
|
||||
<h2><a name="packages">How do I create sub-packages using Boost.Python?</a></h2>
|
||||
<p>
|
||||
In the <a href="../tutorial/doc/creating_packages.html">Techniques</a>
|
||||
section of the tutorial this topic is explored.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
Automatic redirection failed, please go to <a href=
|
||||
Loading index page; if nothing happens, please go to <a href=
|
||||
"../index.html">../index.html</a>.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
636
doc/v2/indexing.html
Normal file
636
doc/v2/indexing.html
Normal file
@@ -0,0 +1,636 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st February 2003), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>
|
||||
Indexing Support
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%"
|
||||
summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3>
|
||||
<a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border=
|
||||
"0"></a>
|
||||
</h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">
|
||||
<a href="../index.html">Boost.Python</a>
|
||||
</h1>
|
||||
|
||||
<h2> Headers <boost/python/indexing/indexing_suite.hpp><br>
|
||||
<boost/python/indexing/vector_indexing_suite.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>
|
||||
Contents
|
||||
</h2>
|
||||
<dl class="page-index">
|
||||
<dt>
|
||||
<a href="#introduction">Introduction</a>
|
||||
</dt>
|
||||
<dt>
|
||||
<a href="#interface">Interface</a>
|
||||
</dt>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt>
|
||||
<a href="#indexing_suite">indexing_suite</a>
|
||||
</dt>
|
||||
<dt>
|
||||
<a href="#indexing_suite_subclasses">indexing_suite
|
||||
sub-classes</a>
|
||||
</dt>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt>
|
||||
<a href="#vector_indexing_suite">vector_indexing_suite</a>
|
||||
</dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<a href="#indexing_suite_class">indexing_suite class</a>
|
||||
</dt>
|
||||
<dt>
|
||||
<a href="#vector_indexing_suite_class">vector_indexing_suite
|
||||
class</a>
|
||||
</dt>
|
||||
</dl>
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="introduction" id="introduction"></a>Introduction
|
||||
</h2>
|
||||
<p>
|
||||
Indexing is a Boost Python facility for easy exportation of indexable
|
||||
C++ containers to Python. Indexable containers are containers that
|
||||
allow random access through the operator[] (e.g. std::vector).
|
||||
</p>
|
||||
<p>
|
||||
While Boost Python has all the facilities needed to expose indexable
|
||||
C++ containers such as the ubiquitous std::vector to Python, the
|
||||
procedure is not as straightforward as we'd like it to be. Python
|
||||
containers do not map easily to C++ containers. Emulating Python
|
||||
containers in C++ (see Python Reference Manual, <a href=
|
||||
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
|
||||
container types</a>) using Boost Python is non trivial. There are a lot
|
||||
of issues to consider before we can map a C++ container to Python.
|
||||
These involve implementing wrapper functions for the methods
|
||||
<strong>__len__</strong>, <strong>__getitem__</strong>,
|
||||
<strong>__setitem__</strong>, <strong>__delitem__,</strong>
|
||||
<strong>__iter__</strong> and <strong>__contains</strong>.
|
||||
</p>
|
||||
<p>
|
||||
The goals:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<div>
|
||||
Make indexable C++ containers behave exactly as one would expect a
|
||||
Python container to behave.
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
Provide default reference semantics for container element indexing
|
||||
(<tt>__getitem__</tt>) such that <tt>c[i]</tt> can be mutable.
|
||||
Require:
|
||||
<div>
|
||||
<pre>
|
||||
val = c[i]
|
||||
c[i].m()
|
||||
val == c[i]
|
||||
</pre>
|
||||
</div>where <tt>m</tt> is a non-const (mutating) member function
|
||||
(method).
|
||||
</li>
|
||||
<li>
|
||||
Return safe references from <tt>__getitem__</tt> such that subsequent
|
||||
adds and deletes to and from the container will not result in
|
||||
dangling references (will not crash Python).
|
||||
</li>
|
||||
<li>
|
||||
Support slice indexes.
|
||||
</li>
|
||||
<li>
|
||||
Accept Python container arguments (e.g. lists, tuples) wherever
|
||||
appropriate.
|
||||
</li>
|
||||
<li>
|
||||
Allow for extensibility through re-definable policy classes.
|
||||
</li>
|
||||
<li>
|
||||
Provide predefined support for the most common STL and STL like
|
||||
indexable containers.
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<h2> <a name="interface"></a>The Boost.Python Indexing Interface</h2>
|
||||
<h3> <a name="indexing_suite"></a>indexing_suite [ Header <boost/python/indexing/indexing_suite.hpp>
|
||||
]</h3>
|
||||
<p>
|
||||
The <tt>indexing_suite</tt> class is the base protocol class for the
|
||||
management of C++ containers intended to be integrated to Python. The
|
||||
objective is make a C++ container look and feel and behave exactly as
|
||||
we'd expect a Python container. The class automatically wraps these
|
||||
special Python methods (taken from the Python reference: <a href=
|
||||
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
|
||||
container types</a>):
|
||||
</p>
|
||||
<dl>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-126"><tt class=
|
||||
"method">__len__</tt></a></b>(<var>self</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement the built-in function <tt class=
|
||||
"function">len()</tt><a name="l2h-134"> </a> Should return
|
||||
the length of the object, an integer <code>>=</code> 0. Also,
|
||||
an object that doesn't define a <tt class=
|
||||
"method">__nonzero__()</tt> method and whose <tt class=
|
||||
"method">__len__()</tt> method returns zero is considered to be
|
||||
false in a Boolean context. <a name="l2h-128"> </a>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-129"><tt class=
|
||||
"method">__getitem__</tt></a></b>(<var>self, key</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement evaluation of
|
||||
<code><var>self</var>[<var>key</var>]</code>. For sequence types,
|
||||
the accepted keys should be integers and slice
|
||||
objects.<a name="l2h-135"> </a> Note that the special
|
||||
interpretation of negative indexes (if the class wishes to
|
||||
emulate a sequence type) is up to the <tt class=
|
||||
"method">__getitem__()</tt> method. If <var>key</var> is of
|
||||
an inappropriate type, <tt class="exception">TypeError</tt>
|
||||
may be raised; if of a value outside the set of indexes for
|
||||
the sequence (after any special interpretation of negative
|
||||
values), <tt class="exception">IndexError</tt> should be
|
||||
raised. <span class="note"><b class="label">Note:</b>
|
||||
<tt class="keyword">for</tt> loops expect that an <tt class=
|
||||
"exception">IndexError</tt> will be raised for illegal
|
||||
indexes to allow proper detection of the end of the
|
||||
sequence.</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-130"><tt class=
|
||||
"method">__setitem__</tt></a></b>(<var>self, key, value</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement assignment to
|
||||
<code><var>self</var>[<var>key</var>]</code>. Same note as for
|
||||
<tt class="method">__getitem__()</tt>. This should only be
|
||||
implemented for mappings if the objects support changes to the
|
||||
values for keys, or if new keys can be added, or for sequences if
|
||||
elements can be replaced. The same exceptions should be raised
|
||||
for improper <var>key</var> values as for the <tt class=
|
||||
"method">__getitem__()</tt> method.
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-131"><tt class=
|
||||
"method">__delitem__</tt></a></b>(<var>self, key</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement deletion of
|
||||
<code><var>self</var>[<var>key</var>]</code>. Same note as for
|
||||
<tt class="method">__getitem__()</tt>. This should only be
|
||||
implemented for mappings if the objects support removal of keys,
|
||||
or for sequences if elements can be removed from the sequence.
|
||||
The same exceptions should be raised for improper <var>key</var>
|
||||
values as for the <tt class="method">__getitem__()</tt> method.
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-132"><tt class=
|
||||
"method">__iter__</tt></a></b>(<var>self</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
This method is called when an iterator is required for a
|
||||
container. This method should return a new iterator object that
|
||||
can iterate over all the objects in the container. For mappings,
|
||||
it should iterate over the keys of the container, and should also
|
||||
be made available as the method <tt class=
|
||||
"method">iterkeys()</tt>.
|
||||
<p>
|
||||
Iterator objects also need to implement this method; they are
|
||||
required to return themselves. For more information on iterator
|
||||
objects, see ``<a class="ulink" href=
|
||||
"http://www.python.org/doc/current/lib/typeiter.html">Iterator
|
||||
Types</a>'' in the <em class="citetitle"><a href=
|
||||
"http://www.python.org/doc/current/lib/lib.html" title=
|
||||
"Python Library Reference">Python Library Reference</a></em>.
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-133"><tt class=
|
||||
"method">__contains__</tt></a></b>(<var>self, item</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement membership test operators. Should return true
|
||||
if <var>item</var> is in <var>self</var>, false otherwise. For
|
||||
mapping objects, this should consider the keys of the mapping
|
||||
rather than the values or the key-item pairs.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3> <a name="indexing_suite_subclasses"></a>indexing_suite sub-classes</h3>
|
||||
<p>
|
||||
The <tt>indexing_suite</tt> is not meant to be used as is. A couple of
|
||||
policy functions must be supplied by subclasses of
|
||||
<tt>indexing_suite</tt>. However, a set of <tt>indexing_suite</tt>
|
||||
subclasses for the standard indexable STL containers will be provided,
|
||||
In most cases, we can simply use the available predefined suites. In
|
||||
some cases, we can refine the predefined suites to suit our needs.
|
||||
</p>
|
||||
|
||||
<h3> <a name="vector_indexing_suite"></a>vector_indexing_suite [ Header <boost/python/indexing/vector_indexing_suite.hpp>
|
||||
] </h3>
|
||||
<p>
|
||||
The <tt>vector_indexing_suite</tt> class is a predefined
|
||||
<tt>indexing_suite</tt> derived class designed to wrap
|
||||
<tt>std::vector</tt> (and <tt>std::vector</tt> like [i.e. a class with
|
||||
std::vector interface]) classes (currently, this is the only predefined
|
||||
suite available). It provides all the policies required by the
|
||||
<tt>indexing_suite</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Example usage:
|
||||
</p>
|
||||
<pre>
|
||||
class X {...};
|
||||
...
|
||||
|
||||
class_<std::vector<X> >("XVec")
|
||||
.def(vector_indexing_suite<std::vector<X> >())
|
||||
;
|
||||
</pre>
|
||||
<p>
|
||||
<tt>XVec</tt> is now a full-fledged Python container (see the
|
||||
<a href="../../test/vector_indexing_suite.cpp">example in full</a>,
|
||||
along with its <a href="../../test/vector_indexing_suite.py">python
|
||||
test</a>).
|
||||
</p>
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="indexing_suite_class"></a>indexing_suite class
|
||||
</h2>
|
||||
<h3>
|
||||
Class template<br>
|
||||
<tt>indexing_suite<<br>
|
||||
class <font color="#007F00">Container</font><br>
|
||||
, class <font color="#007F00">DerivedPolicies<br></font></tt> <tt>,
|
||||
bool <font color="#007F00">NoProxy</font><br>
|
||||
, bool <font color="#007F00">NoProxy</font>,<br>
|
||||
, class <font color="#007F00">Element</font><br>
|
||||
, class <font color="#007F00">Key</font><br>
|
||||
, class <font color="#007F00">Index</font></tt>
|
||||
</h3>
|
||||
<table width="100%" border="1">
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Template Parameter</strong><br>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Requirements</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Semantics</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Default</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Container</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A class type
|
||||
</td>
|
||||
<td>
|
||||
The container type to be wrapped to Python.
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>DerivedPolicies</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A subclass of indexing_suite
|
||||
</td>
|
||||
<td>
|
||||
Derived classes provide the policy hooks. See <a href=
|
||||
"#DerivedPolicies">DerivedPolicies</a> below.
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>NoProxy</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A boolean
|
||||
</td>
|
||||
<td>
|
||||
By default indexed elements have Python reference semantics and are
|
||||
returned by proxy. This can be disabled by supplying
|
||||
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
|
||||
</td>
|
||||
<td>
|
||||
false
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Element</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
The container's element type.
|
||||
</td>
|
||||
<td>
|
||||
<tt>Container::value_type</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Key</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
The container's key type.
|
||||
</td>
|
||||
<td>
|
||||
<tt>Container::value_type</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Index</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
The container's index type.
|
||||
</td>
|
||||
<td>
|
||||
<tt>Container::size_type</tt>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<pre>
|
||||
template <<br> class Container
|
||||
, class DerivedPolicies
|
||||
, bool NoProxy = false
|
||||
, class Element = typename Container::value_type
|
||||
, class Key = typename Container::value_type
|
||||
, class Index = typename Container::size_type
|
||||
><br> class indexing_suite
|
||||
: unspecified
|
||||
{
|
||||
public:
|
||||
|
||||
indexing_suite(); // default constructor
|
||||
}
|
||||
</pre>
|
||||
<h2>
|
||||
<tt><a name="DerivedPolicies"></a>DerivedPolicies</tt>
|
||||
</h2>
|
||||
<dl>
|
||||
<dd>
|
||||
Derived classes provide the hooks needed by
|
||||
the<tt>indexing_suite:</tt>
|
||||
</dd>
|
||||
</dl>
|
||||
<pre>
|
||||
static element_type&
|
||||
get_item(Container& container, index_type i);
|
||||
|
||||
static object
|
||||
get_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static void
|
||||
set_item(Container& container, index_type i, element_type const& v);
|
||||
|
||||
static void
|
||||
set_slice(
|
||||
Container& container, index_type from,
|
||||
index_type to, element_type const& v
|
||||
);
|
||||
|
||||
template <class Iter>
|
||||
static void<br> set_slice(Container& container, index_type from,
|
||||
index_type to, Iter first, Iter last
|
||||
);
|
||||
|
||||
static void
|
||||
delete_item(Container& container, index_type i);
|
||||
|
||||
static void
|
||||
delete_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static size_t
|
||||
size(Container& container);
|
||||
|
||||
template <class T>
|
||||
static bool
|
||||
contains(Container& container, T const& val);
|
||||
|
||||
static index_type
|
||||
convert_index(Container& container, PyObject* i);
|
||||
|
||||
static index_type
|
||||
adjust_index(index_type current, index_type from,
|
||||
index_type to, size_type len
|
||||
);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>
|
||||
Most of these policies are self explanatory. <tt>However,
|
||||
<strong>convert_index</strong></tt> and
|
||||
<tt><strong>adjust_index</strong></tt> deserve some explanation.
|
||||
</p>
|
||||
<p>
|
||||
<strong><tt>convert_index</tt></strong> converts a Python index into
|
||||
a C++ index that the container can handle. For instance, negative
|
||||
indexes in Python, by convention, start counting from the right(e.g.
|
||||
<tt>C[-1]</tt> indexes the rightmost element in <tt>C</tt>).
|
||||
<strong><tt>convert_index</tt></strong> should handle the necessary
|
||||
conversion for the C++ container (e.g. convert <tt>-1</tt> to
|
||||
<tt>C.size()-1</tt>). <tt><strong>convert_index</strong></tt> should
|
||||
also be able to convert the type of the index (A dynamic Python type)
|
||||
to the actual type that the C++ container expects.
|
||||
</p>
|
||||
<p>
|
||||
When a container expands or contracts, held indexes to its elements
|
||||
must be adjusted to follow the movement of data. For instance, if we
|
||||
erase 3 elements, starting from index 0 from a 5 element vector, what
|
||||
used to be at index 4 will now be at index 1:
|
||||
</p>
|
||||
<pre>
|
||||
[a][b][c][d][e] ---> [d][e]
|
||||
^ ^
|
||||
4 1
|
||||
</pre>
|
||||
<p>
|
||||
<strong><tt>adjust_index</tt></strong> takes care of the adjustment.
|
||||
Given a current index, the function should return the adjusted index
|
||||
when data in the container at index <tt>from</tt>..<tt>to</tt> is
|
||||
replaced by <tt>len</tt> elements.
|
||||
</p>
|
||||
</blockquote>
|
||||
<div>
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="vector_indexing_suite_class"></a>vector_indexing_suite class
|
||||
</h2>
|
||||
<h3>
|
||||
Class template <tt><br>
|
||||
vector_indexing_suite<<br>
|
||||
class <font color="#007F00">Container</font><br>
|
||||
, bool <font color="#007F00">NoProxy</font><br>
|
||||
, class <font color="#007F00">DerivedPolicies</font>></tt>
|
||||
</h3>
|
||||
<table width="100%" border="1">
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Template Parameter</strong><br>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Requirements</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Semantics</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Default</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Container</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A class type
|
||||
</td>
|
||||
<td>
|
||||
The container type to be wrapped to Python.
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>NoProxy</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A boolean
|
||||
</td>
|
||||
<td>
|
||||
By default indexed elements have Python reference semantics and
|
||||
are returned by proxy. This can be disabled by supplying
|
||||
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
|
||||
</td>
|
||||
<td>
|
||||
false
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>DerivedPolicies</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A subclass of indexing_suite
|
||||
</td>
|
||||
<td>
|
||||
The <tt>vector_indexing_suite</tt> may still be derived to
|
||||
further tweak any of the predefined policies. Static polymorphism
|
||||
through CRTP (James Coplien. "Curiously Recurring Template
|
||||
Pattern". C++ Report, Feb. 1995) enables the base
|
||||
<tt>indexing_suite</tt> class to call policy function of the most
|
||||
derived class
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<pre>
|
||||
template <<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite<br> : public indexing_suite<Container, DerivedPolicies, NoProxy><br> {<br> public:<br><br> typedef typename Container::value_type element_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> static element_type&<br> get_item(Container& container, index_type i);
|
||||
|
||||
static object
|
||||
get_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static void<br> set_item(Container& container, index_type i, element_type const& v);
|
||||
|
||||
static void
|
||||
set_slice(Container& container, index_type from,
|
||||
index_type to, element_type const& v);
|
||||
|
||||
template <class Iter><br> static void<br> set_slice(Container& container, index_type from,<br> index_type to, Iter first, Iter last);
|
||||
|
||||
static void
|
||||
delete_item(Container& container, index_type i);
|
||||
|
||||
static void
|
||||
delete_slice(Container& container, index_type from, index_type to);<br>
|
||||
static size_t
|
||||
size(Container& container);
|
||||
|
||||
static bool
|
||||
contains(Container& container, key_type const& key);
|
||||
|
||||
static index_type
|
||||
convert_index(Container& container, PyObject* i);
|
||||
|
||||
static index_type
|
||||
adjust_index(index_type current, index_type from,
|
||||
index_type to, size_type len);
|
||||
};
|
||||
</pre>
|
||||
<hr>
|
||||
© Copyright Joel de Guzman 2003. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -66,9 +66,13 @@ template <class F, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_function(F f, Policies const& policies)
|
||||
|
||||
template <class F, class Policies, class Keywords>
|
||||
template <class F, class Policies, class KeywordsOrSignature>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_function(F f, Policies const& policies, Keywords const& keywords)
|
||||
"object.html#object-spec">object</a> make_function(F f, Policies const& policies, KeywordsOrSignature const& ks)
|
||||
|
||||
template <class F, class Policies, class Keywords, class Signature>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_function(F f, Policies const& policies, Keywords const& kw, Signature const& sig)
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
@@ -82,19 +86,41 @@ template <class F, class Policies, class Keywords>
|
||||
|
||||
<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
|
||||
<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>. <ul>
|
||||
<li> If <code>policies</code> are supplied, it
|
||||
will be applied to the function as described <a href=
|
||||
"CallPolicies.html">here</a>. If <code>keywords</code> are
|
||||
"CallPolicies.html">here</a>.
|
||||
<li>If <code>keywords</code> are
|
||||
supplied, the keywords will be applied in order to the final
|
||||
arguments of the resulting function.</dt>
|
||||
arguments of the resulting function.
|
||||
<li>If <code>Signature</code>
|
||||
is supplied, it should be an instance of an <a
|
||||
href="../../mpl/doc/ref/Sequence.html">MPL front-extensible
|
||||
sequence</a> representing the function's return type followed by
|
||||
its argument types. Pass a <code>Signature</code> when wrapping
|
||||
function object types whose signatures can't be deduced, or when
|
||||
you wish to override the types which will be passed to the
|
||||
wrapped function.
|
||||
</ul></dt>
|
||||
|
||||
<dt><b>Returns:</b> An instance of <a href=
|
||||
"object.html#object-spec">object</a> which holds the new Python
|
||||
callable object.</dt>
|
||||
|
||||
<dt><b>Caveats:</b> An argument of pointer type may
|
||||
be <code>0</code> if <code>None</code> is passed from Python.
|
||||
An argument type which is a constant reference may refer to a
|
||||
temporary which was created from the Python object for just the
|
||||
duration of the call to the wrapped function, for example
|
||||
a <code>std::vector</code> conjured up by the conversion process
|
||||
from a Python list. Use a non-<code>const</code> reference
|
||||
argument when a persistent lvalue is required.
|
||||
</dl>
|
||||
|
||||
<pre>
|
||||
<a name=
|
||||
"make_constructor-spec"></a>template <class T, class ArgList, class Generator>
|
||||
|
||||
@@ -196,6 +196,8 @@ namespace boost { namespace python { namespace self_ns {
|
||||
"#operator_-spec">operator_</a><<i>unspecified</i>> operator+(self_t);
|
||||
<a href=
|
||||
"#operator_-spec">operator_</a><<i>unspecified</i>> operator~(self_t);
|
||||
<a href=
|
||||
"#operator_-spec">operator_</a><<i>unspecified</i>> operator!(self_t);
|
||||
|
||||
// value operations
|
||||
<a href=
|
||||
@@ -349,123 +351,123 @@ namespace boost { namespace python { namespace self_ns {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self == r</td>
|
||||
<td><code>self == r</code></td>
|
||||
|
||||
<td>__eq__</td>
|
||||
<td><code>__eq__</code></td>
|
||||
|
||||
<td>x == y</td>
|
||||
<td><code>x == y</code></td>
|
||||
|
||||
<td>x == y, y == x</td>
|
||||
<td><code>x == y, y == x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l == self</td>
|
||||
<td><code>l == self</code></td>
|
||||
|
||||
<td>__eq__</td>
|
||||
<td><code>__eq__</code></td>
|
||||
|
||||
<td>y == x</td>
|
||||
<td><code>y == x</code></td>
|
||||
|
||||
<td>y == x, x == y</td>
|
||||
<td><code>y == x, x == y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self != r</td>
|
||||
<td><code>self != r</code></td>
|
||||
|
||||
<td>__ne__</td>
|
||||
<td><code>__ne__</code></td>
|
||||
|
||||
<td>x != y</td>
|
||||
<td><code>x != y</code></td>
|
||||
|
||||
<td>x != y, y != x</td>
|
||||
<td><code>x != y, y != x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l != self</td>
|
||||
<td><code>l != self</code></td>
|
||||
|
||||
<td>__ne__</td>
|
||||
<td><code>__ne__</code></td>
|
||||
|
||||
<td>y != x</td>
|
||||
<td><code>y != x</code></td>
|
||||
|
||||
<td>y != x, x != y</td>
|
||||
<td><code>y != x, x != y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self < r</td>
|
||||
<td><code>self < r</code></td>
|
||||
|
||||
<td>__lt__</td>
|
||||
<td><code>__lt__</code></td>
|
||||
|
||||
<td>x < y</td>
|
||||
<td><code>x < y</code></td>
|
||||
|
||||
<td>x < y, y > x</td>
|
||||
<td><code>x < y, y > x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l < self</td>
|
||||
<td><code>l < self</code></td>
|
||||
|
||||
<td>__gt__</td>
|
||||
<td><code>__gt__</code></td>
|
||||
|
||||
<td>y < x</td>
|
||||
<td><code>y < x</code></td>
|
||||
|
||||
<td>y > x, x < y</td>
|
||||
<td><code>y > x, x < y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self > r</td>
|
||||
<td><code>self > r</code></td>
|
||||
|
||||
<td>__gt__</td>
|
||||
<td><code>__gt__</code></td>
|
||||
|
||||
<td>x > y</td>
|
||||
<td><code>x > y</code></td>
|
||||
|
||||
<td>x > y, y < x</td>
|
||||
<td><code>x > y, y < x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l > self</td>
|
||||
<td><code>l > self</code></td>
|
||||
|
||||
<td>__lt__</td>
|
||||
<td><code>__lt__</code></td>
|
||||
|
||||
<td>y > x</td>
|
||||
<td><code>y > x</code></td>
|
||||
|
||||
<td>y < x, x > y</td>
|
||||
<td><code>y < x, x > y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self <= r</td>
|
||||
<td><code>self <= r</code></td>
|
||||
|
||||
<td>__le__</td>
|
||||
<td><code>__le__</code></td>
|
||||
|
||||
<td>x <= y</td>
|
||||
<td><code>x <= y</code></td>
|
||||
|
||||
<td>x <= y, y >= x</td>
|
||||
<td><code>x <= y, y >= x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l <= self</td>
|
||||
<td><code>l <= self</code></td>
|
||||
|
||||
<td>__ge__</td>
|
||||
<td><code>__ge__</code></td>
|
||||
|
||||
<td>y <= x</td>
|
||||
<td><code>y <= x</code></td>
|
||||
|
||||
<td>y >= x, x <= y</td>
|
||||
<td><code>y >= x, x <= y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self >= r</td>
|
||||
<td><code>self >= r</code></td>
|
||||
|
||||
<td>__ge__</td>
|
||||
<td><code>__ge__</code></td>
|
||||
|
||||
<td>x >= y</td>
|
||||
<td><code>x >= y</code></td>
|
||||
|
||||
<td>x >= y, y <= x</td>
|
||||
<td><code>x >= y, y <= x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l >= self</td>
|
||||
<td><code>l >= self</code></td>
|
||||
|
||||
<td>__le__</td>
|
||||
<td><code>__le__</code></td>
|
||||
|
||||
<td>y >= x</td>
|
||||
<td><code>y >= x</code></td>
|
||||
|
||||
<td>y <= x, x >= y</td>
|
||||
<td><code>y <= x, x >= y</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -487,183 +489,183 @@ namespace boost { namespace python { namespace self_ns {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self + r</td>
|
||||
<td><code>self + r</code></td>
|
||||
|
||||
<td>__add__</td>
|
||||
<td><code>__add__</code></td>
|
||||
|
||||
<td>x + y</td>
|
||||
<td><code>x + y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l + self</td>
|
||||
<td><code>l + self</code></td>
|
||||
|
||||
<td>__radd__</td>
|
||||
<td><code>__radd__</code></td>
|
||||
|
||||
<td>y + x</td>
|
||||
<td><code>y + x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self - r</td>
|
||||
<td><code>self - r</code></td>
|
||||
|
||||
<td>__sub__</td>
|
||||
<td><code>__sub__</code></td>
|
||||
|
||||
<td>x - y</td>
|
||||
<td><code>x - y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l - self</td>
|
||||
<td><code>l - self</code></td>
|
||||
|
||||
<td>__rsub__</td>
|
||||
<td><code>__rsub__</code></td>
|
||||
|
||||
<td>y - x</td>
|
||||
<td><code>y - x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self * r</td>
|
||||
<td><code>self * r</code></td>
|
||||
|
||||
<td>__mul__</td>
|
||||
<td><code>__mul__</code></td>
|
||||
|
||||
<td>x * y</td>
|
||||
<td><code>x * y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l * self</td>
|
||||
<td><code>l * self</code></td>
|
||||
|
||||
<td>__rmul__</td>
|
||||
<td><code>__rmul__</code></td>
|
||||
|
||||
<td>y * x</td>
|
||||
<td><code>y * x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self / r</td>
|
||||
<td><code>self / r</code></td>
|
||||
|
||||
<td>__div__</td>
|
||||
<td><code>__div__</code></td>
|
||||
|
||||
<td>x / y</td>
|
||||
<td><code>x / y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l / self</td>
|
||||
<td><code>l / self</code></td>
|
||||
|
||||
<td>__rdiv__</td>
|
||||
<td><code>__rdiv__</code></td>
|
||||
|
||||
<td>y / x</td>
|
||||
<td><code>y / x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self % r</td>
|
||||
<td><code>self % r</code></td>
|
||||
|
||||
<td>__mod__</td>
|
||||
<td><code>__mod__</code></td>
|
||||
|
||||
<td>x % y</td>
|
||||
<td><code>x % y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l % self</td>
|
||||
<td><code>l % self</code></td>
|
||||
|
||||
<td>__rmod__</td>
|
||||
<td><code>__rmod__</code></td>
|
||||
|
||||
<td>y % x</td>
|
||||
<td><code>y % x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self >> r</td>
|
||||
<td><code>self >> r</code></td>
|
||||
|
||||
<td>__rshift__</td>
|
||||
<td><code>__rshift__</code></td>
|
||||
|
||||
<td>x >> y</td>
|
||||
<td><code>x >> y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l >> self</td>
|
||||
<td><code>l >> self</code></td>
|
||||
|
||||
<td>__rrshift__</td>
|
||||
<td><code>__rrshift__</code></td>
|
||||
|
||||
<td>y >> x</td>
|
||||
<td><code>y >> x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self << r</td>
|
||||
<td><code>self << r</code></td>
|
||||
|
||||
<td>__lshift__</td>
|
||||
<td><code>__lshift__</code></td>
|
||||
|
||||
<td>x << y</td>
|
||||
<td><code>x << y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l << self</td>
|
||||
<td><code>l << self</code></td>
|
||||
|
||||
<td>__rlshift__</td>
|
||||
<td><code>__rlshift__</code></td>
|
||||
|
||||
<td>y << x</td>
|
||||
<td><code>y << x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self & r</td>
|
||||
<td><code>self & r</code></td>
|
||||
|
||||
<td>__and__</td>
|
||||
<td><code>__and__</code></td>
|
||||
|
||||
<td>x & y</td>
|
||||
<td><code>x & y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l & self</td>
|
||||
<td><code>l & self</code></td>
|
||||
|
||||
<td>__rand__</td>
|
||||
<td><code>__rand__</code></td>
|
||||
|
||||
<td>y & x</td>
|
||||
<td><code>y & x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self ^ r</td>
|
||||
<td><code>self ^ r</code></td>
|
||||
|
||||
<td>__xor__</td>
|
||||
<td><code>__xor__</code></td>
|
||||
|
||||
<td>x ^ y</td>
|
||||
<td><code>x ^ y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l ^ self</td>
|
||||
<td><code>l ^ self</code></td>
|
||||
|
||||
<td>__rxor__</td>
|
||||
<td><code>__rxor__</code></td>
|
||||
|
||||
<td>y ^ x</td>
|
||||
<td><code>y ^ x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>self | r</td>
|
||||
<td><code>self | r</code></td>
|
||||
|
||||
<td>__or__</td>
|
||||
<td><code>__or__</code></td>
|
||||
|
||||
<td>x | y</td>
|
||||
<td><code>x | y</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>l | self</td>
|
||||
<td><code>l | self</code></td>
|
||||
|
||||
<td>__ror__</td>
|
||||
<td><code>__ror__</code></td>
|
||||
|
||||
<td>y | x</td>
|
||||
<td><code>y | x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>pow(self, r)</td>
|
||||
<td><code>pow(self, r)</code></td>
|
||||
|
||||
<td>__pow__</td>
|
||||
<td><code>__pow__</code></td>
|
||||
|
||||
<td>pow(x, y)</td>
|
||||
<td><code>pow(x, y)</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>pow(l, self)</td>
|
||||
<td><code>pow(l, self)</code></td>
|
||||
|
||||
<td>__rpow__</td>
|
||||
<td><code>__rpow__</code></td>
|
||||
|
||||
<td>pow(y, x)</td>
|
||||
<td><code>pow(y, x)</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4><a name="self_t-spec-unary-ops"></a>Class <code>self_t</code> unary
|
||||
<h4><a name="self_t-spec-value-unary-ops"></a>Class <code>self_t</code> unary
|
||||
operations</h4>
|
||||
|
||||
<table border="1" summary="self_t unary operations">
|
||||
@@ -676,27 +678,35 @@ namespace boost { namespace python { namespace self_ns {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>-self</td>
|
||||
<td><code>-self</code></td>
|
||||
|
||||
<td>__neg__</td>
|
||||
<td><code>__neg__</code></td>
|
||||
|
||||
<td>-x</td>
|
||||
<td><code>-x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>+self</td>
|
||||
<td><code>+self</code></td>
|
||||
|
||||
<td>__pos__</td>
|
||||
<td><code>__pos__</code></td>
|
||||
|
||||
<td>+x</td>
|
||||
<td><code>+x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>~self</td>
|
||||
<td><code>~self</code></td>
|
||||
|
||||
<td>__invert__</td>
|
||||
<td><code>__invert__</code></td>
|
||||
|
||||
<td>~x</td>
|
||||
<td><code>~x</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>not self</code><br><i>or</i><br><code>!self</code></td>
|
||||
|
||||
<td><code>__nonzero__</code></td>
|
||||
|
||||
<td><code>!!x</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -713,44 +723,44 @@ namespace boost { namespace python { namespace self_ns {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>int_(self)</td>
|
||||
<td><code>int_(self)</code></td>
|
||||
|
||||
<td>__int__</td>
|
||||
<td><code>__int__</code></td>
|
||||
|
||||
<td>long(x)</td>
|
||||
<td><code>long(x)</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>long_</td>
|
||||
<td><code>long_</code></td>
|
||||
|
||||
<td>__long__</td>
|
||||
<td><code>__long__</code></td>
|
||||
|
||||
<td>PyLong_FromLong(x)</td>
|
||||
<td><code>PyLong_FromLong(x)</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>float_</td>
|
||||
<td><code>float_</code></td>
|
||||
|
||||
<td>__float__</td>
|
||||
<td><code>__float__</code></td>
|
||||
|
||||
<td>double(x)</td>
|
||||
<td><code>double(x)</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>complex_</td>
|
||||
<td><code>complex_</code></td>
|
||||
|
||||
<td>__complex__</td>
|
||||
<td><code>__complex__</code></td>
|
||||
|
||||
<td>std::complex<double>(x)</td>
|
||||
<td><code>std::complex<double>(x)</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>str</td>
|
||||
<td><code>str</code></td>
|
||||
|
||||
<td>__str__</td>
|
||||
<td><code>__str__</code></td>
|
||||
|
||||
<td><a href=
|
||||
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a><std::string>(x)</td>
|
||||
<td><code><a href=
|
||||
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a><std::string>(x)</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -876,7 +886,7 @@ BOOST_PYTHON_MODULE(demo)
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
3 October, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
|
||||
@@ -194,9 +194,10 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 1, 3)
|
||||
|
||||
BOOST_PYTHON_MODULE(args_ext)
|
||||
{
|
||||
def("f", f, args("x", "y", "z")
|
||||
, "This is f's docstring"
|
||||
);
|
||||
def("f", f,
|
||||
f_overloads(
|
||||
args("x", "y", "z"), "This is f's docstring"
|
||||
));
|
||||
|
||||
|
||||
class_<Y>("Y")
|
||||
@@ -204,16 +205,17 @@ BOOST_PYTHON_MODULE(args_ext)
|
||||
|
||||
class_<X>("X", "This is X's docstring")
|
||||
.def("f1", &X::f,
|
||||
X_f_overloads(args("x", "y", "z"),
|
||||
"f's docstring"
|
||||
)[return_internal_reference<>()])
|
||||
X_f_overloads(
|
||||
args("x", "y", "z"), "f's docstring"
|
||||
)[return_internal_reference<>()]
|
||||
)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
15 December, 2002
|
||||
15 April, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
|
||||
BIN
doc/v2/overview.png
Executable file
BIN
doc/v2/overview.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
BIN
doc/v2/proxy.png
Executable file
BIN
doc/v2/proxy.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
doc/v2/proxy_detached.png
Executable file
BIN
doc/v2/proxy_detached.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
116
doc/v2/raw_function.html
Executable file
116
doc/v2/raw_function.html
Executable file
@@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/raw_function.hpp></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/raw_function.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>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#raw_function-spec">raw_function</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><a href="#raw_function-spec">raw_function</a>(...)</code>
|
||||
is used to convert a function taking a <a
|
||||
href="tuple.html#tuple-spec">tuple</a> and a <a
|
||||
href="dict.html#dict-spec">dict</a> into a Python callable object
|
||||
which accepts a variable number of arguments and arbitrary keyword
|
||||
arguments.
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<a name="raw_function-spec"></a>raw_function
|
||||
<pre>
|
||||
template <class F>
|
||||
object raw_function(F f, std::size_t min_args = 0);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>f(tuple(), dict())</code> is
|
||||
well-formed.</dt>
|
||||
|
||||
<dt><b>Returns:</b> a <a href=
|
||||
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">callable</a> object which requires at least <code>min_args</code> arguments. When called, the actual non-keyword arguments will be passed in a <a
|
||||
href="tuple.html#tuple-spec">tuple</a> as the first argument to <code>f</code>, and the keyword arguments will be passed in a <a
|
||||
href="dict.html#dict-spec">dict</a> as the second argument to <code>f</code>.
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
C++:
|
||||
<pre>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/raw_function.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
tuple raw(tuple args, dict kw)
|
||||
{
|
||||
return make_tuple(args, kw);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(raw_test)
|
||||
{
|
||||
def("raw", raw_function(raw));
|
||||
}
|
||||
</pre>
|
||||
|
||||
Python:
|
||||
<pre>
|
||||
>>> from raw_test import *
|
||||
|
||||
>>> raw(3, 4, foo = 'bar', baz = 42)
|
||||
((3, 4), {'foo': 'bar', 'baz': 42})
|
||||
</pre>
|
||||
<p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
7 March, 2003
|
||||
<!--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>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
p.c3 {font-style: italic}
|
||||
h2.c2 {text-align: center}
|
||||
h1.c1 {text-align: center}
|
||||
</style>
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -96,193 +96,158 @@
|
||||
|
||||
<h2><a name="high_level">High Level Components</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="class.html">class.hpp/class_fwd.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
|
||||
<dl>
|
||||
<dt><a href="class.html">class.hpp/class_fwd.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="class.html#classes">Classes</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="class.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="class.html#class_-spec">class_</a></dt>
|
||||
|
||||
<dt><a href="class.html#bases-spec">bases</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="def.html">def.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="def.html#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="def.html#def-spec">def</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="enum.html">enum.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="enum.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="enum.html#enum_-spec">enum_</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="errors.html">errors.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="errors.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"errors.html#error_already_set-spec">error_already_set</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="errors.html#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"errors.html#handle_exception-spec">handle_exception</a></dt>
|
||||
|
||||
<dt><a href=
|
||||
"errors.html#expect_non_null-spec">expect_non_null</a></dt>
|
||||
|
||||
<dt><a href=
|
||||
"errors.html#throw_error_already_set-spec">throw_error_already_set</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href=
|
||||
"exception_translator.html">exception_translator.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"exception_translator.html#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"exception_translator.html#register_exception_translator-spec">register_exception_translator</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="init.html">init.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="init.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="init.html#init-spec">init</a></dt>
|
||||
|
||||
<dt><a href="init.html#optional-spec">optional</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="iterator.html">iterator.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="iterator.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="iterator.html#iterator-spec">iterator</a></dt>
|
||||
|
||||
<dt><a href="iterator.html#iterators-spec">iterators</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="iterator.html#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="iterator.html#range-spec">range</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="module.html">module.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="module.html#macros">Macros</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"module.html#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="operators.html">operators.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="operators.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="operators.html#self_t-spec">self_t</a></dt>
|
||||
|
||||
<dt><a href="operators.html#other-spec">other</a></dt>
|
||||
|
||||
<dt><a href="operators.html#operator_-spec">operator_</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="operators.html#objects">Objects</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="operators.html#self-spec">self</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="scope.html">scope.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="scope.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="scope.html#scope-spec">scope</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="class.html#class_-spec">class_</a></dt>
|
||||
<dt><a href="class.html#bases-spec">bases</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="def.html">def.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="def.html#functions">Functions</a></dt>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="def.html#def-spec">def</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="def_visitor.html">def_visitor.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="def_visitor.html#classes">Classes</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="enum.html">enum.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="enum.html#classes">Classes</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="enum.html#enum_-spec">enum_</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="errors.html">errors.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="errors.html#classes">Classes</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"errors.html#error_already_set-spec">error_already_set</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="errors.html#functions">Functions</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"errors.html#handle_exception-spec">handle_exception</a></dt>
|
||||
<dt><a href=
|
||||
"errors.html#expect_non_null-spec">expect_non_null</a></dt>
|
||||
<dt><a href=
|
||||
"errors.html#throw_error_already_set-spec">throw_error_already_set</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href=
|
||||
"exception_translator.html">exception_translator.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"exception_translator.html#functions">Functions</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"exception_translator.html#register_exception_translator-spec">register_exception_translator</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="init.html">init.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="init.html#classes">Classes</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="init.html#init-spec">init</a></dt>
|
||||
<dt><a href="init.html#optional-spec">optional</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="iterator.html">iterator.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="iterator.html#classes">Classes</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="iterator.html#iterator-spec">iterator</a></dt>
|
||||
<dt><a href="iterator.html#iterators-spec">iterators</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="iterator.html#functions">Functions</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="iterator.html#range-spec">range</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="module.html">module.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="module.html#macros">Macros</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"module.html#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="operators.html">operators.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="operators.html#classes">Classes</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="operators.html#self_t-spec">self_t</a></dt>
|
||||
<dt><a href="operators.html#other-spec">other</a></dt>
|
||||
<dt><a href="operators.html#operator_-spec">operator_</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="operators.html#objects">Objects</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="operators.html#self-spec">self</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><a href="scope.html">scope.hpp</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="scope.html#classes">Classes</a></dt>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="scope.html#scope-spec">scope</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="object_wrappers">Object Wrappers</a></h2>
|
||||
|
||||
@@ -371,7 +336,7 @@
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="str.html">tuple.hpp</a></dt>
|
||||
<dt><a href="tuple.html">tuple.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
@@ -570,6 +535,24 @@
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="return_arg.html">return_arg.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="return_arg.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"return_arg.html#return_arg-spec">return_arg</a></dt>
|
||||
|
||||
<dt><a href=
|
||||
"return_arg.html#return_self-spec">return_self</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href=
|
||||
"return_internal_reference.html">return_internal_reference.hpp</a></dt>
|
||||
|
||||
@@ -750,21 +733,22 @@
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="return_opaque_pointer.html">return_opaque_pointer.hpp</a></dt>
|
||||
<dt><a href=
|
||||
"return_opaque_pointer.html">return_opaque_pointer.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="return_opaque_pointer.html#classes">Classes</a></dt>
|
||||
<dt><a href=
|
||||
"return_opaque_pointer.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="return_opaque_pointer.html#return_opaque_pointer-spec">
|
||||
return_opaque_pointer</a></dt>
|
||||
<dt><a href=
|
||||
"return_opaque_pointer.html#return_opaque_pointer-spec">return_opaque_pointer</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
@@ -822,24 +806,28 @@
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="opaque_pointer_converter.html">opaque_pointer_converter.hpp</a></dt>
|
||||
<dt><a href=
|
||||
"opaque_pointer_converter.html">opaque_pointer_converter.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="opaque_pointer_converter.html#classes">Classes</a></dt>
|
||||
<dt><a href=
|
||||
"opaque_pointer_converter.html#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="opaque_pointer_converter.html#opaque_pointer_converter-spec">
|
||||
opaque_pointer_converter</a></dt>
|
||||
<dt><a href=
|
||||
"opaque_pointer_converter.html#opaque_pointer_converter-spec">opaque_pointer_converter</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="opaque_pointer_converter.html#macros">Macros</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="opaque_pointer_converter.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
|
||||
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</a></dt>
|
||||
<dt><a href=
|
||||
"opaque_pointer_converter.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
|
||||
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
@@ -859,6 +847,23 @@
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href=
|
||||
"register_ptr_to_python.html">register_ptr_to_python.hpp</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"register_ptr_to_python.html#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"register_ptr_to_python.html#register_ptr_to_python-spec">register_ptr_to_python</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="utility">Utility and Infrastructure</a></h2>
|
||||
@@ -960,18 +965,17 @@
|
||||
|
||||
<h2><a name="topics">Topics</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="callbacks.html">Calling Python Functions and
|
||||
Methods</a></dt>
|
||||
|
||||
<dt><a href="pickle.html">Pickle Support</a></dt>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt><a href="callbacks.html">Calling Python Functions and Methods</a></dt>
|
||||
<dt><a href="pickle.html">Pickle Support</a><br>
|
||||
<a href="containers.html">Indexing Support</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
7 March, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
19 July, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p class="c3">© Copyright <a href=
|
||||
|
||||
160
doc/v2/register_ptr_to_python.html
Normal file
160
doc/v2/register_ptr_to_python.html
Normal file
@@ -0,0 +1,160 @@
|
||||
<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 - <register_ptr_to_python.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="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">Header <register_ptr_to_python.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="#register_ptr_to_python-spec">register_ptr_to_python</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
<p>
|
||||
<code><boost/python/register_ptr_to_python.hpp></code>
|
||||
supplies <code>register_ptr_to_python</code>, a function template
|
||||
which registers a conversion for smart pointers to Python. The
|
||||
resulting Python object holds a copy of the converted smart pointer,
|
||||
but behaves as though it were a wrapped copy of the pointee. If
|
||||
the pointee type has virtual functions and the class representing
|
||||
its dynamic (most-derived) type has been wrapped, the Python object
|
||||
will be an instance of the wrapper for the most-derived type. More than
|
||||
one smart pointer type for a pointee's class can be registered.
|
||||
</p>
|
||||
<p>
|
||||
Note that in order to convert a Python <code>X</code> object to a
|
||||
<code>smart_ptr<X>&</code> (non-const reference), the embedded C++
|
||||
object must be held by <code>smart_ptr<X></code>, and that when wrapped
|
||||
objects are created by calling the constructor from Python, how they are held
|
||||
is determined by the <code>HeldType</code> parameter to
|
||||
<code>class_<...></code> instances.
|
||||
</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
<a name="register_ptr_to_python-spec">template <class P>
|
||||
void register_ptr_to_python()
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>P</code> is the type of the smart pointer,
|
||||
for example <code>smart_ptr<X></code>.
|
||||
</dt>
|
||||
<dt><b>Effects:</b> Allows conversions to-python of <code>smart_ptr<X></code>
|
||||
instances.
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example(s)</h2>
|
||||
|
||||
<h3>C++ Wrapper Code</h3>
|
||||
|
||||
Here is an example of a module that contains a class <code>A</code> with
|
||||
virtual functions and some functions that work with
|
||||
<code>boost::shared_ptr<A></code>.
|
||||
|
||||
<pre>
|
||||
struct A
|
||||
{
|
||||
virtual int f() { return 0; }
|
||||
};
|
||||
|
||||
shared_ptr<A> New() { return shared_ptr<A>( new A() ); }
|
||||
|
||||
int Ok( const shared_ptr<A>& a ) { return a->f(); }
|
||||
|
||||
int Fail( shared_ptr<A>& a ) { return a->f(); }
|
||||
|
||||
struct A_Wrapper: A
|
||||
{
|
||||
A_Wrapper(PyObject* self_): self(self_) {}
|
||||
int f() { return call_method<int>(self, "f"); }
|
||||
int default_f() { return A::f(); }
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(register_ptr)
|
||||
{
|
||||
class_<A, A_Wrapper>("A")
|
||||
.def("f", &A::f, &A_Wrapper::default_f)
|
||||
;
|
||||
|
||||
def("New", &New);
|
||||
def("Ok", &Call);
|
||||
def("Fail", &Fail);
|
||||
|
||||
register_ptr_to_python< shared_ptr<A> >();
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python Code</h3>
|
||||
|
||||
<pre>
|
||||
>>> from register_ptr import *
|
||||
>>> a = A()
|
||||
>>> Ok(a) # ok, passed as shared_ptr<A>
|
||||
0
|
||||
>>> Fail(a) # passed as shared_ptr<A>&, and was created in Python!
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: bad argument type for built-in operation
|
||||
>>>
|
||||
>>> na = New() # now "na" is actually a shared_ptr<A>
|
||||
>>> Ok(a)
|
||||
0
|
||||
>>> Fail(a)
|
||||
0
|
||||
>>>
|
||||
</pre>
|
||||
|
||||
If <code>shared_ptr<A></code> is registered as follows:
|
||||
|
||||
<pre>
|
||||
class_<A, A_Wrapper, shared_ptr<A> >("A")
|
||||
.def("f", &A::f, &A_Wrapper::default_f)
|
||||
;
|
||||
</pre>
|
||||
|
||||
There will be an error when trying to convert <code>shared_ptr<A></code> to
|
||||
<code>shared_ptr<A_Wrapper></code>:
|
||||
|
||||
<pre>
|
||||
>>> a = New()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr<struct A>
|
||||
>>>
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
24 Jun, 2003
|
||||
<!--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>
|
||||
|
||||
|
||||
219
doc/v2/return_arg.html
Executable file
219
doc/v2/return_arg.html
Executable file
@@ -0,0 +1,219 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/return_arg.hpp></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/return_arg.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#return_arg-spec">Class Template
|
||||
<code>return_arg</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#return_arg-spec-synopsis">Class Template
|
||||
<code>return_arg</code> synopsis</a></dt>
|
||||
|
||||
<dt><a href="#return_arg-spec-statics">Class
|
||||
<code>return_arg</code> static functions</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#return_self-spec">Class Template
|
||||
<code>return_self</code></a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
<code>return_arg</code> and <code>return_self</code> instantiations are
|
||||
models of <a href="CallPolicies.html">CallPolicies</a> which return the
|
||||
specified argument parameter (usually <code>*this</code>) of a wrapped
|
||||
(member) function.
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="return_arg-spec"></a>Class template
|
||||
<code>return_arg</code></h3>
|
||||
|
||||
<table border="1" summary="return_arg template parameters">
|
||||
<caption>
|
||||
<b><code>return_arg</code> template parameters</b>
|
||||
</caption>
|
||||
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
|
||||
<th>Requirements</th>
|
||||
|
||||
<th>Description</th>
|
||||
|
||||
<th>Default</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>arg_pos</code></td>
|
||||
|
||||
<td>A positive compile-time constant of type
|
||||
<code>std::size_t</code>.</td>
|
||||
|
||||
<td>the position of the argument to be returned.</td>
|
||||
|
||||
<td>1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>Base</code></td>
|
||||
|
||||
<td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
|
||||
|
||||
<td>Used for policy composition. Any <code>result_converter</code> it
|
||||
supplies will be overridden by <code>return_arg</code>, but its
|
||||
<code>precall</code> and <code>postcall</code> policies are composed
|
||||
as described here <a href=
|
||||
"CallPolicies.html#composition">CallPolicies</a>.</td>
|
||||
|
||||
<td><code><a href=
|
||||
"default_call_policies.html#default_call_policies-spec">default_call_policies</a></code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4><a name="return_arg-spec-synopsis"></a>Class template
|
||||
<code>return_arg</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <size_t arg_pos=1, class Base = default_call_policies>
|
||||
struct return_arg : Base
|
||||
{
|
||||
static PyObject* postcall(PyObject*, PyObject* result);
|
||||
struct result_converter{ template <class T> struct apply; };
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="return_arg-spec-statics"></a>Class <code>return_arg</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> and <code>PyTuple_Size(args) != 0</code></dt>
|
||||
|
||||
<dt><b>Returns:</b> <code>PyTuple_GetItem(args,arg_pos-1)</code></dt>
|
||||
</dl>
|
||||
|
||||
<h3><a name="return_self-spec"></a>Class template
|
||||
<code>return_self</code></h3>
|
||||
|
||||
<h4>Class template <code>return_self</code> synopsis:</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <class Base = default_call_policies>
|
||||
struct return_self
|
||||
: return_arg<1,Base>
|
||||
{};
|
||||
}}
|
||||
</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/return_arg.hpp>
|
||||
|
||||
struct Widget
|
||||
{
|
||||
Widget() :sensitive_(true){}
|
||||
bool get_sensitive() const { return sensitive_; }
|
||||
void set_sensitive(bool s) { this->sensitive_ = s; }
|
||||
private:
|
||||
bool sensitive_;
|
||||
};
|
||||
|
||||
struct Label : Widget
|
||||
{
|
||||
Label() {}
|
||||
|
||||
std::string get_label() const { return label_; }
|
||||
void set_label(const std::string &l){ label_ = l; }
|
||||
|
||||
private:
|
||||
std::string label_;
|
||||
};
|
||||
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE(return_self_ext)
|
||||
{
|
||||
class_<widget>("Widget")
|
||||
.def("sensitive", &Widget::get_sensitive)
|
||||
.def("sensitive", &Widget::set_sensitive, return_self<>())
|
||||
;
|
||||
|
||||
class_<Label, bases<Widget> >("Label")
|
||||
.def("label", &Label::get_label)
|
||||
.def("label", &Label::set_label, return_self<>())
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
</pre>
|
||||
|
||||
<h3>Python code</h3>
|
||||
<pre>
|
||||
>>> from return_self_ext import *
|
||||
>>> l1 = Label().label("foo").sensitive(false)
|
||||
>>> l2 = Label().sensitive(false).label("foo")
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
19 July, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> and Nikolay
|
||||
Mladenov 2003. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -67,8 +67,10 @@
|
||||
<p>Exposes the <a href=
|
||||
"http://www.python.org/dev/doc/devel/lib/string-methods.html">string
|
||||
methods</a> of Python's built-in <code>str</code> type. The
|
||||
semantics of the constructors and member functions defined below
|
||||
can be fully understood by reading the <a href=
|
||||
semantics of the constructors and member functions defined below,
|
||||
except for the two-argument constructors which construct str
|
||||
objects from a range of characters, can be fully understood by
|
||||
reading the <a href=
|
||||
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
|
||||
definition. Since <code>str</code> is publicly derived from
|
||||
<code><a href="object.html#object-spec">object</a></code>, the
|
||||
@@ -85,7 +87,10 @@ namespace boost { namespace python
|
||||
public:
|
||||
str(); // new str
|
||||
|
||||
str(const char* s); // new str
|
||||
str(char const* s); // new str
|
||||
|
||||
str(char const* start, char const* finish); // new str
|
||||
str(char const* start, std::size_t length); // new str
|
||||
|
||||
template <class T>
|
||||
explicit str(T const& other);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Specify our location in the boost project hierarchy
|
||||
subproject libs/python/example ;
|
||||
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
|
||||
# and conditions of use.
|
||||
|
||||
# This is the top of our own project tree
|
||||
project-root ;
|
||||
|
||||
# Declares the following targets:
|
||||
#
|
||||
@@ -19,18 +22,17 @@ subproject libs/python/example ;
|
||||
#
|
||||
|
||||
# Include definitions needed for Python modules
|
||||
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include python.jam ;
|
||||
import python ;
|
||||
|
||||
# ----- getting_started1 -------
|
||||
|
||||
# Declare a Python extension called getting_started1
|
||||
extension getting_started1
|
||||
: # sources
|
||||
getting_started1.cpp
|
||||
: # sources
|
||||
getting_started1.cpp
|
||||
|
||||
# dependencies
|
||||
<dll>../build/boost_python
|
||||
# requirements and dependencies for Boost.Python extensions
|
||||
<template>@boost/libs/python/build/extension
|
||||
;
|
||||
|
||||
# Declare a test for the extension module
|
||||
@@ -49,8 +51,8 @@ extension getting_started2
|
||||
: # sources
|
||||
getting_started2.cpp
|
||||
|
||||
# dependencies
|
||||
<dll>../build/boost_python
|
||||
# requirements and dependencies for Boost.Python extensions
|
||||
<template>@boost/libs/python/build/extension
|
||||
;
|
||||
|
||||
# Declare a test for the extension module
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
use-project /boost/python : ../build ;
|
||||
|
||||
project
|
||||
: requirements <library>@/boost/python/boost_python
|
||||
: requirements <library>/boost/python//boost_python
|
||||
;
|
||||
|
||||
python-extension getting_started1 : getting_started1.cpp : <shared>true ;
|
||||
python-extension getting_started2 : getting_started2.cpp : <shared>true ;
|
||||
python-extension getting_started1 : getting_started1.cpp : <link>shared ;
|
||||
python-extension getting_started2 : getting_started2.cpp : <link>shared ;
|
||||
|
||||
exe embedding_test : embedding_test.cpp : <define>BOOST_PYTHON_DYNAMIC_LIB <shared>true ;
|
||||
|
||||
|
||||
7
example/Jamrules
Executable file
7
example/Jamrules
Executable file
@@ -0,0 +1,7 @@
|
||||
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
|
||||
# and conditions of use.
|
||||
|
||||
# Edit this path to point at the root directory of your Boost
|
||||
# installation. Absolute paths work, too.
|
||||
path-global BOOST_ROOT : ../../.. ;
|
||||
project boost : $(BOOST_ROOT) ;
|
||||
6
example/boost-build.jam
Executable file
6
example/boost-build.jam
Executable file
@@ -0,0 +1,6 @@
|
||||
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
|
||||
# and conditions of use.
|
||||
|
||||
# Edit this path to point at the tools/build subdirectory of your
|
||||
# Boost installation. Absolute paths work, too.
|
||||
boost-build ../../../tools/build ;
|
||||
18
example/test_getting_started1.py
Normal file
18
example/test_getting_started1.py
Normal file
@@ -0,0 +1,18 @@
|
||||
r'''>>> import getting_started1
|
||||
>>> print getting_started1.greet()
|
||||
hello, world
|
||||
>>> number = 11
|
||||
>>> print number, '*', number, '=', getting_started1.square(number)
|
||||
11 * 11 = 121
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started1
|
||||
return doctest.testmod(test_getting_started1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
31
example/test_getting_started2.py
Normal file
31
example/test_getting_started2.py
Normal file
@@ -0,0 +1,31 @@
|
||||
r'''>>> from getting_started2 import *
|
||||
>>> hi = hello('California')
|
||||
>>> hi.greet()
|
||||
'Hello from California'
|
||||
>>> invite(hi)
|
||||
'Hello from California! Please come soon!'
|
||||
>>> hi.invite()
|
||||
'Hello from California! Please come soon!'
|
||||
|
||||
>>> class wordy(hello):
|
||||
... def greet(self):
|
||||
... return hello.greet(self) + ', where the weather is fine'
|
||||
...
|
||||
>>> hi2 = wordy('Florida')
|
||||
>>> hi2.greet()
|
||||
'Hello from Florida, where the weather is fine'
|
||||
>>> invite(hi2)
|
||||
'Hello from Florida! Please come soon!'
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started2
|
||||
return doctest.testmod(test_getting_started2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
subproject libs/python/example/tutorial ;
|
||||
|
||||
# Include definitions needed for Python modules
|
||||
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include python.jam ;
|
||||
import python ;
|
||||
|
||||
extension hello # Declare a Python extension called hello
|
||||
: hello.cpp # source
|
||||
|
||||
@@ -1,67 +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.
|
||||
|
||||
// See http://www.boost.org/libs/python for documentation.
|
||||
|
||||
#ifndef PYTHON_DWA2002810_HPP
|
||||
# define PYTHON_DWA2002810_HPP
|
||||
|
||||
# include <boost/python/args.hpp>
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
# include <boost/python/back_reference.hpp>
|
||||
# include <boost/python/bases.hpp>
|
||||
# include <boost/python/borrowed.hpp>
|
||||
# include <boost/python/call.hpp>
|
||||
# include <boost/python/call_method.hpp>
|
||||
# include <boost/python/class.hpp>
|
||||
# include <boost/python/copy_const_reference.hpp>
|
||||
# include <boost/python/copy_non_const_reference.hpp>
|
||||
# include <boost/python/data_members.hpp>
|
||||
# include <boost/python/def.hpp>
|
||||
# include <boost/python/default_call_policies.hpp>
|
||||
# include <boost/python/dict.hpp>
|
||||
# include <boost/python/enum.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/exception_translator.hpp>
|
||||
# include <boost/python/extract.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/has_back_reference.hpp>
|
||||
# include <boost/python/implicit.hpp>
|
||||
# include <boost/python/init.hpp>
|
||||
# include <boost/python/instance_holder.hpp>
|
||||
# include <boost/python/iterator.hpp>
|
||||
# include <boost/python/list.hpp>
|
||||
# include <boost/python/long.hpp>
|
||||
# include <boost/python/lvalue_from_pytype.hpp>
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/manage_new_object.hpp>
|
||||
# include <boost/python/module.hpp>
|
||||
# include <boost/python/numeric.hpp>
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/object_protocol.hpp>
|
||||
# include <boost/python/object_protocol_core.hpp>
|
||||
# include <boost/python/operators.hpp>
|
||||
# include <boost/python/opaque_pointer_converter.hpp>
|
||||
# include <boost/python/other.hpp>
|
||||
# include <boost/python/overloads.hpp>
|
||||
# include <boost/python/pointee.hpp>
|
||||
# include <boost/python/ptr.hpp>
|
||||
# include <boost/python/reference_existing_object.hpp>
|
||||
# include <boost/python/return_internal_reference.hpp>
|
||||
# include <boost/python/return_opaque_pointer.hpp>
|
||||
# include <boost/python/return_value_policy.hpp>
|
||||
# include <boost/python/scope.hpp>
|
||||
# include <boost/python/self.hpp>
|
||||
# include <boost/python/slice_nil.hpp>
|
||||
# include <boost/python/str.hpp>
|
||||
# include <boost/python/to_python_converter.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
# include <boost/python/to_python_value.hpp>
|
||||
# include <boost/python/tuple.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/with_custodian_and_ward.hpp>
|
||||
|
||||
#endif // PYTHON_DWA2002810_HPP
|
||||
@@ -1,84 +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 ARG_FROM_PYTHON_DWA2002128_HPP
|
||||
# define ARG_FROM_PYTHON_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/converter/arg_from_python.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
struct arg_from_python
|
||||
: converter::select_arg_from_python<T>::type
|
||||
{
|
||||
typedef typename converter::select_arg_from_python<T>::type base;
|
||||
arg_from_python(PyObject*);
|
||||
};
|
||||
|
||||
// specialization for PyObject*
|
||||
template <>
|
||||
struct arg_from_python<PyObject*>
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
|
||||
arg_from_python(PyObject*) {}
|
||||
bool convertible() const { return true; }
|
||||
PyObject* operator()(PyObject* source) const { return source; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_from_python<PyObject* const&>
|
||||
{
|
||||
typedef PyObject* const& result_type;
|
||||
arg_from_python(PyObject*) {}
|
||||
bool convertible() const { return true; }
|
||||
PyObject*const& operator()(PyObject*const& source) const { return source; }
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
// Meta-iterators for use with caller<>
|
||||
//
|
||||
|
||||
// temporary hack
|
||||
template <class T> struct nullary : T
|
||||
{
|
||||
nullary(PyObject* x) : T(x), m_p(x) {}
|
||||
typename T::result_type operator()() { return this->T::operator()(m_p); }
|
||||
PyObject* m_p;
|
||||
};
|
||||
|
||||
// An MPL metafunction class which returns arg_from_python<ArgType>
|
||||
struct gen_arg_from_python
|
||||
{
|
||||
template <class ArgType> struct apply
|
||||
{
|
||||
typedef nullary<arg_from_python<ArgType> > type;
|
||||
};
|
||||
};
|
||||
|
||||
// An MPL iterator over an endless sequence of gen_arg_from_python
|
||||
struct args_from_python
|
||||
{
|
||||
typedef gen_arg_from_python type;
|
||||
typedef args_from_python next;
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
inline arg_from_python<T>::arg_from_python(PyObject* source)
|
||||
: base(source)
|
||||
{
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // ARG_FROM_PYTHON_DWA2002128_HPP
|
||||
@@ -1,112 +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 KEYWORDS_DWA2002323_HPP
|
||||
# define KEYWORDS_DWA2002323_HPP
|
||||
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
|
||||
# include <boost/type_traits/is_reference.hpp>
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
# include <boost/preprocessor/facilities/intercept.hpp>
|
||||
# include <boost/preprocessor/iteration/local.hpp>
|
||||
|
||||
# include <boost/python/detail/mpl_lambda.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
|
||||
# include <boost/type.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <std::size_t nkeywords>
|
||||
struct keywords
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
|
||||
|
||||
keyword_range range() const
|
||||
{
|
||||
return keyword_range(elements, elements + nkeywords);
|
||||
}
|
||||
|
||||
keyword elements[nkeywords];
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
struct is_keywords
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template<std::size_t nkeywords>
|
||||
struct is_keywords<keywords<nkeywords> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template <class T>
|
||||
struct is_reference_to_keywords
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
|
||||
typedef typename remove_reference<T>::type deref;
|
||||
typedef typename remove_cv<deref>::type key_t;
|
||||
BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
|
||||
|
||||
typedef mpl::bool_<value> type;
|
||||
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
|
||||
};
|
||||
# else
|
||||
typedef char (&yes_keywords_t)[1];
|
||||
typedef char (&no_keywords_t)[2];
|
||||
|
||||
no_keywords_t is_keywords_test(...);
|
||||
|
||||
template<std::size_t nkeywords>
|
||||
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords>&));
|
||||
|
||||
template<std::size_t nkeywords>
|
||||
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords> const&));
|
||||
|
||||
template<typename T>
|
||||
class is_reference_to_keywords
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_keywords_test( (void (*)(T))0 ))
|
||||
== sizeof(detail::yes_keywords_t)));
|
||||
|
||||
typedef mpl::bool_<value> type;
|
||||
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
|
||||
};
|
||||
# endif
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
|
||||
# define BOOST_PP_LOCAL_MACRO(n) \
|
||||
inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
|
||||
{ \
|
||||
detail::keywords<n> result; \
|
||||
BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
|
||||
return result; \
|
||||
}
|
||||
# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
|
||||
# endif // KEYWORDS_DWA2002323_HPP
|
||||
@@ -1,47 +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 ARGS_FWD_DWA2002927_HPP
|
||||
# define ARGS_FWD_DWA2002927_HPP
|
||||
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/config.hpp>
|
||||
# include <cstddef>
|
||||
# include <utility>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct keyword
|
||||
{
|
||||
char const* name;
|
||||
handle<> default_value;
|
||||
};
|
||||
|
||||
template <std::size_t nkeywords = 0> struct keywords;
|
||||
|
||||
typedef std::pair<keyword const*, keyword const*> keyword_range;
|
||||
|
||||
template <>
|
||||
struct keywords<0>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, size = 0);
|
||||
static keyword_range range() { return keyword_range(); }
|
||||
};
|
||||
|
||||
namespace error
|
||||
{
|
||||
template <int keywords, int function_args>
|
||||
struct more_keywords_than_function_arguments
|
||||
{
|
||||
typedef char too_many_keywords[keywords > function_args ? -1 : 1];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // ARGS_FWD_DWA2002927_HPP
|
||||
@@ -1,101 +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 BACK_REFERENCE_DWA2002510_HPP
|
||||
# define BACK_REFERENCE_DWA2002510_HPP
|
||||
|
||||
# include <boost/python/object_fwd.hpp>
|
||||
# include <boost/python/detail/dependent.hpp>
|
||||
# include <boost/python/detail/raw_pyobject.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
struct back_reference
|
||||
{
|
||||
private: // types
|
||||
typedef typename detail::dependent<object,T>::type source_t;
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
back_reference(PyObject*, T);
|
||||
source_t const& source() const;
|
||||
T get() const;
|
||||
private:
|
||||
source_t m_source;
|
||||
T m_value;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
class is_back_reference
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_back_reference<back_reference<T> >
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
# else // no partial specialization
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_back_reference_t)[1];
|
||||
typedef char (&no_back_reference_t)[2];
|
||||
|
||||
no_back_reference_t is_back_reference_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_back_reference_t is_back_reference_test(boost::type< back_reference<T> >);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class is_back_reference
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_back_reference_test(boost::type<T>()))
|
||||
== sizeof(detail::yes_back_reference_t)));
|
||||
};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
back_reference<T>::back_reference(PyObject* p, T x)
|
||||
: m_source(detail::borrowed_reference(p))
|
||||
, m_value(x)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename back_reference<T>::source_t const& back_reference<T>::source() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T back_reference<T>::get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BACK_REFERENCE_DWA2002510_HPP
|
||||
@@ -1,36 +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 BASE_TYPE_TRAITS_DWA2002614_HPP
|
||||
# define BASE_TYPE_TRAITS_DWA2002614_HPP
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct unspecialized {};
|
||||
}
|
||||
|
||||
// Derive from unspecialized so we can detect whether traits are
|
||||
// specialized
|
||||
template <class T> struct base_type_traits
|
||||
: detail::unspecialized
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct base_type_traits<PyObject>
|
||||
{
|
||||
typedef PyObject type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct base_type_traits<PyTypeObject>
|
||||
{
|
||||
typedef PyObject type;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BASE_TYPE_TRAITS_DWA2002614_HPP
|
||||
@@ -1,67 +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 BASES_DWA2002321_HPP
|
||||
# define BASES_DWA2002321_HPP
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/preprocessor/enum_params_with_a_default.hpp>
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# define BOOST_PYTHON_BASE_PARAMS BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, Base)
|
||||
|
||||
// A type list for specifying bases
|
||||
template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename Base, mpl::void_) >
|
||||
struct bases : detail::type_list< BOOST_PYTHON_BASE_PARAMS >::type
|
||||
{};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T> struct specifies_bases
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class Base) >
|
||||
struct specifies_bases< bases< BOOST_PYTHON_BASE_PARAMS > >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
# else
|
||||
template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class Base) >
|
||||
static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&);
|
||||
|
||||
static char (& is_bases_helper(...) )[256];
|
||||
|
||||
template <class T>
|
||||
struct specifies_bases
|
||||
{
|
||||
private:
|
||||
static typename add_reference<T>::type make();
|
||||
BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference<T>::value);
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
# endif
|
||||
template <class T, class Prev = bases<> >
|
||||
struct select_bases
|
||||
: mpl::if_<
|
||||
specifies_bases<T>
|
||||
, T
|
||||
, Prev
|
||||
>
|
||||
{
|
||||
};
|
||||
}
|
||||
# undef BOOST_PYTHON_BASE_PARAMS
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BASES_DWA2002321_HPP
|
||||
@@ -1,20 +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 BORROWED_DWA2002614_HPP
|
||||
# define BORROWED_DWA2002614_HPP
|
||||
# include <boost/python/detail/borrowed_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
inline python::detail::borrowed<T>* borrowed(T* p)
|
||||
{
|
||||
return (detail::borrowed<T>*)p;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BORROWED_DWA2002614_HPP
|
||||
@@ -1,66 +0,0 @@
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
// 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 CALL_DWA2002411_HPP
|
||||
# define CALL_DWA2002411_HPP
|
||||
|
||||
# include <boost/type.hpp>
|
||||
|
||||
# include <boost/python/converter/arg_to_python.hpp>
|
||||
# include <boost/python/converter/return_from_python.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/python/detail/void_return.hpp>
|
||||
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
# include <boost/preprocessor/debug/line.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \
|
||||
, converter::arg_to_python<A##n>(a##n).get()
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/call.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
# endif // CALL_DWA2002411_HPP
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# line BOOST_PP_LINE(__LINE__, call.hpp)
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
|
||||
template <
|
||||
class R
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)
|
||||
>
|
||||
typename detail::returnable<R>::type
|
||||
call(PyObject* callable
|
||||
BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)
|
||||
, boost::type<R>* = 0
|
||||
)
|
||||
{
|
||||
converter::return_from_python<R> converter;
|
||||
return converter(
|
||||
PyEval_CallFunction(
|
||||
callable
|
||||
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
|
||||
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
|
||||
));
|
||||
}
|
||||
|
||||
# undef N
|
||||
|
||||
#endif
|
||||
@@ -1,66 +0,0 @@
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
// 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 CALL_METHOD_DWA2002411_HPP
|
||||
# define CALL_METHOD_DWA2002411_HPP
|
||||
|
||||
# include <boost/type.hpp>
|
||||
|
||||
# include <boost/python/converter/arg_to_python.hpp>
|
||||
# include <boost/python/converter/return_from_python.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/python/detail/void_return.hpp>
|
||||
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
# include <boost/preprocessor/debug/line.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \
|
||||
, converter::arg_to_python<A##n>(a##n).get()
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/call_method.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
# endif // CALL_METHOD_DWA2002411_HPP
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
|
||||
template <
|
||||
class R
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)
|
||||
>
|
||||
typename detail::returnable<R>::type
|
||||
call_method(PyObject* self, char const* name
|
||||
BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)
|
||||
, boost::type<R>* = 0
|
||||
)
|
||||
{
|
||||
converter::return_from_python<R> converter;
|
||||
return converter(
|
||||
PyEval_CallMethod(
|
||||
self
|
||||
, const_cast<char*>(name)
|
||||
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
|
||||
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
|
||||
));
|
||||
}
|
||||
|
||||
# undef N
|
||||
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
@@ -1,106 +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 CAST_DWA200269_HPP
|
||||
# define CAST_DWA200269_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/python/base_type_traits.hpp>
|
||||
# include <boost/python/detail/convertible.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Source, class Target> inline Target* upcast_impl(Source*, Target*);
|
||||
|
||||
template <class Source, class Target>
|
||||
inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class Source, class Target>
|
||||
inline Target* upcast(Source* p, no_convertible, no_convertible, Target*)
|
||||
{
|
||||
typedef typename base_type_traits<Source>::type base;
|
||||
|
||||
return detail::upcast_impl((base*)p, (Target*)0);
|
||||
}
|
||||
|
||||
template <bool is_same = true>
|
||||
struct upcaster
|
||||
{
|
||||
template <class T>
|
||||
static inline T* execute(T* x, T*) { return x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct upcaster<false>
|
||||
{
|
||||
template <class Source, class Target>
|
||||
static inline Target* execute(Source* x, Target*)
|
||||
{
|
||||
return detail::upcast(
|
||||
x, detail::convertible<Target*>::check(x)
|
||||
, detail::convertible<Source*>::check((Target*)0)
|
||||
, (Target*)0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target* downcast(Source* p, yes_convertible)
|
||||
{
|
||||
return static_cast<Target*>(p);
|
||||
}
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target* downcast(Source* p, no_convertible, boost::type<Target>* = 0)
|
||||
{
|
||||
typedef typename base_type_traits<Source>::type base;
|
||||
return (Target*)detail::downcast<base>(p, convertible<Source*>::check((base*)0));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void assert_castable(boost::type<T>* = 0)
|
||||
{
|
||||
typedef char must_be_a_complete_type[sizeof(T)];
|
||||
}
|
||||
|
||||
template <class Source, class Target>
|
||||
inline Target* upcast_impl(Source* x, Target*)
|
||||
{
|
||||
typedef typename add_cv<Source>::type src_t;
|
||||
typedef typename add_cv<Target>::type target_t;
|
||||
static bool const same = is_same<src_t,target_t>::value;
|
||||
|
||||
return detail::upcaster<same>::execute(x, (Target*)0);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target* upcast(Source* x, Target* = 0)
|
||||
{
|
||||
detail::assert_castable<Source>();
|
||||
detail::assert_castable<Target>();
|
||||
return detail::upcast_impl(x, (Target*)0);
|
||||
|
||||
}
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target* downcast(Source* x, Target* = 0)
|
||||
{
|
||||
detail::assert_castable<Source>();
|
||||
detail::assert_castable<Target>();
|
||||
return detail::downcast<Target>(x, detail::convertible<Source*>::check((Target*)0));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CAST_DWA200269_HPP
|
||||
@@ -1,548 +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 CLASS_DWA200216_HPP
|
||||
# define CLASS_DWA200216_HPP
|
||||
|
||||
# include <boost/python/class_fwd.hpp>
|
||||
# include <boost/python/object/class.hpp>
|
||||
|
||||
# include <boost/python/bases.hpp>
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/data_members.hpp>
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
# include <boost/python/init.hpp>
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_member_function_pointer.hpp>
|
||||
# include <boost/type_traits/is_polymorphic.hpp>
|
||||
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
|
||||
# include <boost/python/object/select_holder.hpp>
|
||||
# include <boost/python/object/class_wrapper.hpp>
|
||||
# include <boost/python/object/make_instance.hpp>
|
||||
# include <boost/python/object/pickle_support.hpp>
|
||||
# include <boost/python/object/add_to_namespace.hpp>
|
||||
# include <boost/python/object/class_converters.hpp>
|
||||
|
||||
# include <boost/python/detail/string_literal.hpp>
|
||||
# include <boost/python/detail/overloads_fwd.hpp>
|
||||
# include <boost/python/detail/operator_id.hpp>
|
||||
# include <boost/python/detail/member_function_cast.hpp>
|
||||
# include <boost/python/detail/def_helper.hpp>
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
enum no_init_t { no_init };
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// This function object is used with mpl::for_each to write the id
|
||||
// of the type a pointer to which is passed as its 2nd compile-time
|
||||
// argument. into the iterator pointed to by its runtime argument
|
||||
struct write_type_id
|
||||
{
|
||||
write_type_id(type_info**p) : p(p) {}
|
||||
|
||||
// Here's the runtime behavior
|
||||
template <class T>
|
||||
void operator()(T*) const
|
||||
{
|
||||
*(*p)++ = type_id<T>();
|
||||
}
|
||||
|
||||
type_info** p;
|
||||
};
|
||||
|
||||
template <class T, class Prev = detail::not_specified>
|
||||
struct select_held_type;
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
struct has_noncopyable;
|
||||
|
||||
template <detail::operator_id, class L, class R>
|
||||
struct operator_;
|
||||
|
||||
// Register to_python converters for a class T. The first argument
|
||||
// will be mpl::true_ unless noncopyable was specified as a
|
||||
// class_<...> template parameter. The 2nd argument is a pointer to
|
||||
// the type of holder that must be created. The 3rd argument is a
|
||||
// reference to the Python type object to be created.
|
||||
template <class T, class SelectHolder>
|
||||
inline void register_class_to_python(mpl::true_ copyable, SelectHolder selector, T* = 0)
|
||||
{
|
||||
typedef typename SelectHolder::type holder;
|
||||
force_instantiate(objects::class_cref_wrapper<T, objects::make_instance<T,holder> >());
|
||||
SelectHolder::register_();
|
||||
}
|
||||
|
||||
template <class T, class SelectHolder>
|
||||
inline void register_class_to_python(mpl::false_ copyable, SelectHolder selector, T* = 0)
|
||||
{
|
||||
SelectHolder::register_();
|
||||
}
|
||||
|
||||
namespace error
|
||||
{
|
||||
//
|
||||
// A meta-assertion mechanism which prints nice error messages and
|
||||
// backtraces on lots of compilers. Usage:
|
||||
//
|
||||
// assertion<C>::failed
|
||||
//
|
||||
// where C is an MPL metafunction class
|
||||
//
|
||||
|
||||
template <class C> struct assertion_failed { };
|
||||
template <class C> struct assertion_ok { typedef C failed; };
|
||||
|
||||
template <class C>
|
||||
struct assertion
|
||||
: mpl::if_<C, assertion_ok<C>, assertion_failed<C> >::type
|
||||
{};
|
||||
|
||||
//
|
||||
// Checks for validity of arguments used to define virtual
|
||||
// functions with default implementations.
|
||||
//
|
||||
|
||||
template <class Default>
|
||||
void not_a_derived_class_member(Default) {}
|
||||
|
||||
template <class T, class Fn>
|
||||
struct virtual_function_default
|
||||
{
|
||||
template <class Default>
|
||||
static void
|
||||
must_be_derived_class_member(Default const&)
|
||||
{
|
||||
typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
typedef typename assertion<is_polymorphic<T> >::failed test1;
|
||||
# endif
|
||||
typedef typename assertion<is_member_function_pointer<Fn> >::failed test2;
|
||||
not_a_derived_class_member<Default>(Fn());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// This is the primary mechanism through which users will expose
|
||||
// C++ classes to Python.
|
||||
template <
|
||||
class T // class being wrapped
|
||||
, class X1 // = detail::not_specified
|
||||
, class X2 // = detail::not_specified
|
||||
, class X3 // = detail::not_specified
|
||||
>
|
||||
class class_ : public objects::class_base
|
||||
{
|
||||
public: // types
|
||||
typedef objects::class_base base;
|
||||
typedef T wrapped_type;
|
||||
|
||||
typedef class_<T,X1,X2,X3> self;
|
||||
BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable<X1,X2,X3>::value));
|
||||
|
||||
typedef typename detail::select_held_type<
|
||||
X1, typename detail::select_held_type<
|
||||
X2, typename detail::select_held_type<
|
||||
X3
|
||||
>::type>::type>::type held_type;
|
||||
|
||||
typedef objects::select_holder<T,held_type> holder_selector;
|
||||
|
||||
private: // types
|
||||
|
||||
typedef typename detail::select_bases<X1
|
||||
, typename detail::select_bases<X2
|
||||
, typename boost::python::detail::select_bases<X3>::type
|
||||
>::type
|
||||
>::type bases;
|
||||
|
||||
|
||||
// A helper class which will contain an array of id objects to be
|
||||
// passed to the base class constructor
|
||||
struct id_vector
|
||||
{
|
||||
id_vector()
|
||||
{
|
||||
// Stick the derived class id into the first element of the array
|
||||
ids[0] = type_id<T>();
|
||||
|
||||
// Write the rest of the elements into succeeding positions.
|
||||
type_info* p = ids + 1;
|
||||
mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer<mpl::_>*)0);
|
||||
}
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, size = mpl::size<bases>::value + 1);
|
||||
type_info ids[size];
|
||||
};
|
||||
friend struct id_vector;
|
||||
|
||||
public: // constructors
|
||||
|
||||
// Construct with the class name, with or without docstring, and default __init__() function
|
||||
class_(char const* name, char const* doc = 0);
|
||||
|
||||
// Construct with class name, no docstring, and an uncallable __init__ function
|
||||
class_(char const* name, no_init_t);
|
||||
|
||||
// Construct with class name, docstring, and an uncallable __init__ function
|
||||
class_(char const* name, char const* doc, no_init_t);
|
||||
|
||||
// Construct with class name and init<> function
|
||||
template <class DerivedT>
|
||||
inline class_(char const* name, init_base<DerivedT> const& i)
|
||||
: base(name, id_vector::size, id_vector().ids)
|
||||
{
|
||||
this->register_();
|
||||
define_init(*this, i.derived());
|
||||
this->set_instance_size(holder_selector::additional_size());
|
||||
}
|
||||
|
||||
// Construct with class name, docstring and init<> function
|
||||
template <class DerivedT>
|
||||
inline class_(char const* name, char const* doc, init_base<DerivedT> const& i)
|
||||
: base(name, id_vector::size, id_vector().ids, doc)
|
||||
{
|
||||
this->register_();
|
||||
define_init(*this, i.derived());
|
||||
this->set_instance_size(holder_selector::additional_size());
|
||||
}
|
||||
|
||||
public: // member functions
|
||||
|
||||
// Define additional constructors
|
||||
template <class DerivedT>
|
||||
self& def(init_base<DerivedT> const& i)
|
||||
{
|
||||
define_init(*this, i.derived());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Wrap a member function or a non-member function which can take
|
||||
// a T, T cv&, or T cv* as its first parameter, or a callable
|
||||
// python object.
|
||||
template <class F>
|
||||
self& def(char const* name, F f)
|
||||
{
|
||||
this->def_impl(name, f, detail::def_helper<char const*>(0), &f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
self& def(char const* name, A1 a1, A2 const& a2)
|
||||
{
|
||||
this->def_maybe_overloads(name, a1, a2, &a2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Fn, class A1, class A2>
|
||||
self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2)
|
||||
{
|
||||
// The arguments are definitely:
|
||||
// def(name, function, policy, doc_string)
|
||||
// def(name, function, doc_string, policy)
|
||||
|
||||
this->def_impl(
|
||||
name, fn
|
||||
, detail::def_helper<A1,A2>(a1,a2)
|
||||
, &fn);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Fn, class A1, class A2, class A3>
|
||||
self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3)
|
||||
{
|
||||
this->def_impl(
|
||||
name, fn
|
||||
, detail::def_helper<A1,A2,A3>(a1,a2,a3)
|
||||
, &fn);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <detail::operator_id id, class L, class R>
|
||||
self& def(detail::operator_<id,L,R> const& op)
|
||||
{
|
||||
typedef detail::operator_<id,L,R> op_t;
|
||||
return this->def(op.name(), &op_t::template apply<T>::execute);
|
||||
}
|
||||
|
||||
//
|
||||
// Data member access
|
||||
//
|
||||
template <class D, class B>
|
||||
self& def_readonly(char const* name, D B::*pm_)
|
||||
{
|
||||
D T::*pm = pm_;
|
||||
this->add_property(name, make_getter(pm));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class B>
|
||||
self& def_readwrite(char const* name, D B::*pm_)
|
||||
{
|
||||
D T::*pm = pm_;
|
||||
return this->add_property(name, make_getter(pm), make_setter(pm));
|
||||
}
|
||||
|
||||
// Property creation
|
||||
template <class Get>
|
||||
self& add_property(char const* name, Get fget)
|
||||
{
|
||||
base::add_property(
|
||||
name
|
||||
, object(
|
||||
detail::member_function_cast<T,Get>::stage1(fget).stage2((T*)0).stage3(fget)
|
||||
)
|
||||
);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Get, class Set>
|
||||
self& add_property(char const* name, Get fget, Set fset)
|
||||
{
|
||||
base::add_property(
|
||||
name
|
||||
, object(
|
||||
detail::member_function_cast<T,Get>::stage1(fget).stage2((T*)0).stage3(fget)
|
||||
)
|
||||
, object(
|
||||
detail::member_function_cast<T,Set>::stage1(fset).stage2((T*)0).stage3(fset)
|
||||
)
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
self& setattr(char const* name, U const& x)
|
||||
{
|
||||
this->base::setattr(name, object(x));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Pickle support
|
||||
template <typename PickleSuiteType>
|
||||
self& def_pickle(PickleSuiteType const& x)
|
||||
{
|
||||
error_messages::must_be_derived_from_pickle_suite(x);
|
||||
detail::pickle_suite_finalize<PickleSuiteType>::register_(
|
||||
*this,
|
||||
&PickleSuiteType::getinitargs,
|
||||
&PickleSuiteType::getstate,
|
||||
&PickleSuiteType::setstate,
|
||||
PickleSuiteType::getstate_manages_dict());
|
||||
return *this;
|
||||
}
|
||||
|
||||
self& staticmethod(char const* name)
|
||||
{
|
||||
this->make_method_static(name);
|
||||
return *this;
|
||||
}
|
||||
private: // helper functions
|
||||
|
||||
inline void register_() const;
|
||||
|
||||
//
|
||||
// These two overloads discriminate between def() as applied to
|
||||
// things which are already wrapped into callable python::object
|
||||
// instances and everything else.
|
||||
//
|
||||
template <class F, class A1>
|
||||
inline void def_impl(
|
||||
char const* name
|
||||
, F f
|
||||
, detail::def_helper<A1> const& helper
|
||||
, object const*)
|
||||
{
|
||||
// It's too late to specify anything other than docstrings, if
|
||||
// the callable object is already wrapped.
|
||||
BOOST_STATIC_ASSERT(
|
||||
(is_same<char const*,A1>::value
|
||||
|| detail::is_string_literal<A1>::value));
|
||||
|
||||
objects::add_to_namespace(*this, name, f, helper.doc());
|
||||
}
|
||||
|
||||
template <class Fn, class Helper>
|
||||
inline void def_impl(
|
||||
char const* name
|
||||
, Fn fn
|
||||
, Helper const& helper
|
||||
, ...)
|
||||
{
|
||||
objects::add_to_namespace(
|
||||
*this, name,
|
||||
make_function(
|
||||
// This bit of nastiness casts F to a member function of T if possible.
|
||||
detail::member_function_cast<T,Fn>::stage1(fn).stage2((T*)0).stage3(fn)
|
||||
, helper.policies(), helper.keywords())
|
||||
, helper.doc());
|
||||
|
||||
this->def_default(name, fn, helper, mpl::bool_<Helper::has_default_implementation>());
|
||||
}
|
||||
|
||||
//
|
||||
// These two overloads handle the definition of default
|
||||
// implementation overloads for virtual functions. The second one
|
||||
// handles the case where no default implementation was specified.
|
||||
//
|
||||
template <class Fn, class Helper>
|
||||
inline void def_default(
|
||||
char const* name
|
||||
, Fn fn
|
||||
, Helper const& helper
|
||||
, mpl::bool_<true>)
|
||||
{
|
||||
detail::error::virtual_function_default<T,Fn>::must_be_derived_class_member(
|
||||
helper.default_implementation());
|
||||
|
||||
objects::add_to_namespace(
|
||||
*this, name,
|
||||
make_function(
|
||||
helper.default_implementation(), helper.policies(), helper.keywords())
|
||||
);
|
||||
}
|
||||
|
||||
template <class Fn, class Helper>
|
||||
inline void def_default(char const*, Fn, Helper const&, mpl::bool_<false>)
|
||||
{ }
|
||||
|
||||
//
|
||||
// These two overloads discriminate between def() as applied to
|
||||
// regular functions and def() as applied to the result of
|
||||
// BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
|
||||
// discriminate.
|
||||
//
|
||||
template <class OverloadsT, class SigT>
|
||||
void def_maybe_overloads(
|
||||
char const* name
|
||||
, SigT sig
|
||||
, OverloadsT const& overloads
|
||||
, detail::overloads_base const*)
|
||||
|
||||
{
|
||||
// convert sig to a type_list (see detail::get_signature in signature.hpp)
|
||||
// before calling detail::define_with_defaults.
|
||||
detail::define_with_defaults(
|
||||
name, overloads, *this, detail::get_signature(sig));
|
||||
}
|
||||
|
||||
template <class Fn, class A1>
|
||||
void def_maybe_overloads(
|
||||
char const* name
|
||||
, Fn fn
|
||||
, A1 const& a1
|
||||
, ...)
|
||||
{
|
||||
this->def_impl(
|
||||
name, fn
|
||||
, detail::def_helper<A1>(a1)
|
||||
, &fn);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
// register converters
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline void class_<T,X1,X2,X3>::register_() const
|
||||
{
|
||||
objects::register_class_from_python<T,bases>();
|
||||
|
||||
detail::register_class_to_python<T>(
|
||||
mpl::bool_<is_copyable>()
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
, holder_selector::execute((held_type*)0)
|
||||
# elif BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
, holder_selector::type()
|
||||
# else
|
||||
, typename holder_selector::type()
|
||||
# endif
|
||||
);
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc)
|
||||
: base(name, id_vector::size, id_vector().ids, doc)
|
||||
{
|
||||
this->register_();
|
||||
this->set_instance_size(holder_selector::additional_size());
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
holder_selector::execute((held_type*)0).assert_default_constructible();
|
||||
# else
|
||||
holder_selector::type::assert_default_constructible();
|
||||
# endif
|
||||
this->def(init<>());
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_(char const* name, no_init_t)
|
||||
: base(name, id_vector::size, id_vector().ids)
|
||||
{
|
||||
this->register_();
|
||||
this->def_no_init();
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
|
||||
: base(name, id_vector::size, id_vector().ids, doc)
|
||||
{
|
||||
this->register_();
|
||||
this->def_no_init();
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T1, class T2, class T3>
|
||||
struct has_noncopyable
|
||||
: mpl::or_<
|
||||
is_same<T1,noncopyable>
|
||||
, is_same<T2,noncopyable>
|
||||
, is_same<T3,noncopyable>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <class T, class Prev>
|
||||
struct select_held_type
|
||||
: mpl::if_<
|
||||
mpl::or_<
|
||||
specifies_bases<T>
|
||||
, is_same<T,noncopyable>
|
||||
>
|
||||
, Prev
|
||||
, T
|
||||
>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_DWA200216_HPP
|
||||
@@ -1,23 +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 CLASS_FWD_DWA200222_HPP
|
||||
# define CLASS_FWD_DWA200222_HPP
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <
|
||||
class T // class being wrapped
|
||||
// arbitrarily-ordered optional arguments. Full qualification needed for MSVC6
|
||||
, class X1 = ::boost::python::detail::not_specified
|
||||
, class X2 = ::boost::python::detail::not_specified
|
||||
, class X3 = ::boost::python::detail::not_specified
|
||||
>
|
||||
class class_;
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_FWD_DWA200222_HPP
|
||||
@@ -1,341 +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 ARG_FROM_PYTHON_DWA2002127_HPP
|
||||
# define ARG_FROM_PYTHON_DWA2002127_HPP
|
||||
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/python/converter/registered_pointee.hpp>
|
||||
# include <boost/python/detail/void_ptr.hpp>
|
||||
# include <boost/python/back_reference.hpp>
|
||||
# include <boost/python/detail/referent_storage.hpp>
|
||||
# include <boost/python/converter/obj_mgr_arg_from_python.hpp>
|
||||
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <class T> struct arg_from_python;
|
||||
}}
|
||||
|
||||
// This header defines Python->C++ function argument converters,
|
||||
// parametrized on the argument type.
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
//
|
||||
// lvalue converters
|
||||
//
|
||||
// These require that an lvalue of the type U is stored somewhere in
|
||||
// the Python object being converted.
|
||||
|
||||
// Used when T == U*const&
|
||||
template <class T>
|
||||
struct pointer_cref_arg_from_python
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
pointer_cref_arg_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
bool convertible() const;
|
||||
|
||||
private: // storage for a U*
|
||||
// needed because not all compilers will let us declare U* as the
|
||||
// return type of operator() -- we return U*const& instead
|
||||
typename python::detail::referent_storage<T>::type m_result;
|
||||
};
|
||||
|
||||
// Base class for pointer and reference converters
|
||||
struct arg_lvalue_from_python_base
|
||||
{
|
||||
public: // member functions
|
||||
arg_lvalue_from_python_base(void* result);
|
||||
bool convertible() const;
|
||||
|
||||
protected: // member functions
|
||||
void*const& result() const;
|
||||
|
||||
private: // data members
|
||||
void* m_result;
|
||||
};
|
||||
|
||||
// Used when T == U*
|
||||
template <class T>
|
||||
struct pointer_arg_from_python : arg_lvalue_from_python_base
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
pointer_arg_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
// Used when T == U& and (T != V const& or T == W volatile&)
|
||||
template <class T>
|
||||
struct reference_arg_from_python : arg_lvalue_from_python_base
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
reference_arg_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
// ===================
|
||||
|
||||
//
|
||||
// rvalue converters
|
||||
//
|
||||
// These require only that an object of type T can be created from
|
||||
// the given Python object, but not that the T object exist
|
||||
// somewhere in storage.
|
||||
//
|
||||
|
||||
// Used when T is a plain value (non-pointer, non-reference) type or
|
||||
// a (non-volatile) const reference to a plain value type.
|
||||
template <class T>
|
||||
struct arg_rvalue_from_python
|
||||
{
|
||||
typedef typename boost::add_reference<
|
||||
T
|
||||
// We can't add_const here, or it would be impossible to pass
|
||||
// auto_ptr<U> args from Python to C++
|
||||
>::type result_type;
|
||||
|
||||
arg_rvalue_from_python(PyObject*);
|
||||
bool convertible() const;
|
||||
|
||||
# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
|
||||
typename arg_rvalue_from_python<T>::
|
||||
# endif
|
||||
result_type operator()(PyObject*);
|
||||
|
||||
private:
|
||||
rvalue_from_python_data<result_type> m_data;
|
||||
};
|
||||
|
||||
|
||||
// ==================
|
||||
|
||||
// Converts to a (PyObject*,T) bundle, for when you need a reference
|
||||
// back to the Python object
|
||||
template <class T>
|
||||
struct back_reference_arg_from_python
|
||||
: boost::python::arg_from_python<typename T::type>
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
back_reference_arg_from_python(PyObject*);
|
||||
T operator()(PyObject*);
|
||||
private:
|
||||
typedef boost::python::arg_from_python<typename T::type> base;
|
||||
};
|
||||
|
||||
|
||||
// ==================
|
||||
|
||||
// This metafunction selects the appropriate arg_from_python converter
|
||||
// type for an argument of type T.
|
||||
template <class T>
|
||||
struct select_arg_from_python
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, obj_mgr = is_object_manager<T>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, obj_mgr_ref = is_reference_to_object_manager<T>::value);
|
||||
|
||||
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);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, back_ref =
|
||||
boost::python::is_back_reference<T>::value);
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
obj_mgr
|
||||
, object_manager_value_arg_from_python<T>
|
||||
, typename mpl::if_c<
|
||||
obj_mgr_ref
|
||||
, object_manager_ref_arg_from_python<T>
|
||||
, typename mpl::if_c<
|
||||
ptr
|
||||
, pointer_arg_from_python<T>
|
||||
, typename mpl::if_c<
|
||||
ptr_cref
|
||||
, pointer_cref_arg_from_python<T>
|
||||
, typename mpl::if_c<
|
||||
ref
|
||||
, reference_arg_from_python<T>
|
||||
, typename mpl::if_c<
|
||||
back_ref
|
||||
, back_reference_arg_from_python<T>
|
||||
, arg_rvalue_from_python<T>
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// ==================
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
// arg_lvalue_from_python_base
|
||||
//
|
||||
inline arg_lvalue_from_python_base::arg_lvalue_from_python_base(void* result)
|
||||
: m_result(result)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool arg_lvalue_from_python_base::convertible() const
|
||||
{
|
||||
return m_result != 0;
|
||||
}
|
||||
|
||||
inline void*const& arg_lvalue_from_python_base::result() const
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
// pointer_cref_arg_from_python
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
// null_ptr_reference -- a function returning a reference to a null
|
||||
// pointer of type U. Needed so that extractors for T*const& can
|
||||
// convert Python's None.
|
||||
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 pointer_cref_arg_from_python<T>::pointer_cref_arg_from_python(PyObject* p)
|
||||
{
|
||||
// T == U*const&: store a U* in the m_result storage. Nonzero
|
||||
// indicates success. If find returns nonzero, it's a pointer to
|
||||
// a U object.
|
||||
python::detail::write_void_ptr_reference(
|
||||
m_result.bytes
|
||||
, p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters)
|
||||
, (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool pointer_cref_arg_from_python<T>::convertible() const
|
||||
{
|
||||
return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0;
|
||||
}
|
||||
template <class T>
|
||||
inline T pointer_cref_arg_from_python<T>::operator()(PyObject* p) const
|
||||
{
|
||||
return (p == Py_None) // None ==> 0
|
||||
? detail::null_ptr_reference((T(*)())0)
|
||||
// Otherwise, return a U*const& to the m_result storage.
|
||||
: python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
|
||||
}
|
||||
|
||||
// pointer_arg_from_python
|
||||
//
|
||||
template <class T>
|
||||
inline pointer_arg_from_python<T>::pointer_arg_from_python(PyObject* p)
|
||||
: arg_lvalue_from_python_base(
|
||||
p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T pointer_arg_from_python<T>::operator()(PyObject* p) const
|
||||
{
|
||||
return (p == Py_None) ? 0 : T(result());
|
||||
}
|
||||
|
||||
// reference_arg_from_python
|
||||
//
|
||||
template <class T>
|
||||
inline reference_arg_from_python<T>::reference_arg_from_python(PyObject* p)
|
||||
: arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered<T>::converters))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T reference_arg_from_python<T>::operator()(PyObject*) const
|
||||
{
|
||||
return python::detail::void_ptr_to_reference(result(), (T(*)())0);
|
||||
}
|
||||
|
||||
|
||||
// arg_rvalue_from_python
|
||||
//
|
||||
template <class T>
|
||||
inline arg_rvalue_from_python<T>::arg_rvalue_from_python(PyObject* obj)
|
||||
: m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool arg_rvalue_from_python<T>::convertible() const
|
||||
{
|
||||
return m_data.stage1.convertible != 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename arg_rvalue_from_python<T>::result_type
|
||||
arg_rvalue_from_python<T>::operator()(PyObject* p)
|
||||
{
|
||||
if (m_data.stage1.construct != 0)
|
||||
m_data.stage1.construct(p, &m_data.stage1);
|
||||
|
||||
return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
|
||||
}
|
||||
|
||||
// back_reference_arg_from_python
|
||||
//
|
||||
template <class T>
|
||||
back_reference_arg_from_python<T>::back_reference_arg_from_python(PyObject* x)
|
||||
: base(x)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
back_reference_arg_from_python<T>::operator()(PyObject* x)
|
||||
{
|
||||
return T(x, base::operator()(x));
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // ARG_FROM_PYTHON_DWA2002127_HPP
|
||||
@@ -1,262 +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 ARG_TO_PYTHON_DWA200265_HPP
|
||||
# define ARG_TO_PYTHON_DWA200265_HPP
|
||||
|
||||
# include <boost/python/ptr.hpp>
|
||||
# include <boost/python/tag.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/python/converter/registered_pointee.hpp>
|
||||
# include <boost/python/converter/arg_to_python_base.hpp>
|
||||
# include <boost/python/converter/shared_ptr_to_python.hpp>
|
||||
// Bring in specializations
|
||||
# include <boost/python/converter/builtin_converters.hpp>
|
||||
|
||||
# include <boost/python/object/function_handle.hpp>
|
||||
|
||||
# include <boost/python/base_type_traits.hpp>
|
||||
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/python/detail/convertible.hpp>
|
||||
# include <boost/python/detail/string_literal.hpp>
|
||||
# include <boost/python/detail/value_is_shared_ptr.hpp>
|
||||
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/function_traits.hpp>
|
||||
|
||||
|
||||
# include <boost/mpl/or.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T> struct is_object_manager;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct function_arg_to_python : handle<>
|
||||
{
|
||||
function_arg_to_python(T const& x);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct reference_arg_to_python : handle<>
|
||||
{
|
||||
reference_arg_to_python(T& x);
|
||||
private:
|
||||
static PyObject* get_object(T& x);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct shared_ptr_arg_to_python : handle<>
|
||||
{
|
||||
shared_ptr_arg_to_python(T const& x);
|
||||
private:
|
||||
static PyObject* get_object(T& x);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct value_arg_to_python : arg_to_python_base
|
||||
{
|
||||
// Throw an exception if the conversion can't succeed
|
||||
value_arg_to_python(T const&);
|
||||
};
|
||||
|
||||
template <class Ptr>
|
||||
struct pointer_deep_arg_to_python : arg_to_python_base
|
||||
{
|
||||
// Throw an exception if the conversion can't succeed
|
||||
pointer_deep_arg_to_python(Ptr);
|
||||
};
|
||||
|
||||
template <class Ptr>
|
||||
struct pointer_shallow_arg_to_python : handle<>
|
||||
{
|
||||
// Throw an exception if the conversion can't succeed
|
||||
pointer_shallow_arg_to_python(Ptr);
|
||||
private:
|
||||
static PyObject* get_object(Ptr p);
|
||||
};
|
||||
|
||||
// Convert types that manage a Python object to_python
|
||||
template <class T>
|
||||
struct object_manager_arg_to_python
|
||||
{
|
||||
object_manager_arg_to_python(T const& x) : m_src(x) {}
|
||||
|
||||
PyObject* get() const
|
||||
{
|
||||
return python::upcast<PyObject>(get_managed_object(m_src, tag));
|
||||
}
|
||||
|
||||
private:
|
||||
T const& m_src;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct select_arg_to_python
|
||||
{
|
||||
typedef typename unwrap_reference<T>::type unwrapped_referent;
|
||||
typedef typename unwrap_pointer<T>::type unwrapped_ptr;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
// Special handling for char const[N]; interpret them as char
|
||||
// const* for the sake of conversion
|
||||
python::detail::is_string_literal<T const>
|
||||
, arg_to_python<char const*>
|
||||
|
||||
, typename mpl::if_<
|
||||
python::detail::value_is_shared_ptr<T>
|
||||
, shared_ptr_arg_to_python<T>
|
||||
|
||||
, typename mpl::if_<
|
||||
mpl::or_<
|
||||
is_function<T>
|
||||
, python::detail::is_pointer_to_function<T>
|
||||
, is_member_function_pointer<T>
|
||||
>
|
||||
, function_arg_to_python<T>
|
||||
|
||||
, typename mpl::if_<
|
||||
is_object_manager<T>
|
||||
, object_manager_arg_to_python<T>
|
||||
|
||||
, typename mpl::if_<
|
||||
is_pointer<T>
|
||||
, pointer_deep_arg_to_python<T>
|
||||
|
||||
, typename mpl::if_<
|
||||
is_pointer_wrapper<T>
|
||||
, pointer_shallow_arg_to_python<unwrapped_ptr>
|
||||
|
||||
, typename mpl::if_<
|
||||
is_reference_wrapper<T>
|
||||
, reference_arg_to_python<unwrapped_referent>
|
||||
, value_arg_to_python<T>
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
|
||||
type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct arg_to_python
|
||||
: detail::select_arg_to_python<T>::type
|
||||
{
|
||||
typedef typename detail::select_arg_to_python<T>::type base;
|
||||
public: // member functions
|
||||
// Throw an exception if the conversion can't succeed
|
||||
arg_to_python(T const& x);
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
// reject_raw_object_ptr -- cause a compile-time error if the user
|
||||
// should pass a raw Python object pointer
|
||||
using python::detail::yes_convertible;
|
||||
using python::detail::no_convertible;
|
||||
using python::detail::unspecialized;
|
||||
|
||||
template <class T> struct cannot_convert_raw_PyObject;
|
||||
|
||||
template <class T, class Convertibility>
|
||||
struct reject_raw_object_helper
|
||||
{
|
||||
static void error(Convertibility)
|
||||
{
|
||||
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
|
||||
}
|
||||
static void error(...) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline void reject_raw_object_ptr(T*)
|
||||
{
|
||||
reject_raw_object_helper<T,yes_convertible>::error(
|
||||
python::detail::convertible<PyObject const volatile*>::check((T*)0));
|
||||
|
||||
typedef typename remove_cv<T>::type value_type;
|
||||
|
||||
reject_raw_object_helper<T,no_convertible>::error(
|
||||
python::detail::convertible<unspecialized*>::check(
|
||||
(base_type_traits<value_type>*)0
|
||||
));
|
||||
}
|
||||
// ---------
|
||||
|
||||
template <class T>
|
||||
inline function_arg_to_python<T>::function_arg_to_python(T const& x)
|
||||
: handle<>(python::objects::make_function_handle(x))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline value_arg_to_python<T>::value_arg_to_python(T const& x)
|
||||
: arg_to_python_base(&x, registered<T>::converters)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Ptr>
|
||||
inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
|
||||
: arg_to_python_base(x, registered_pointee<Ptr>::converters)
|
||||
{
|
||||
detail::reject_raw_object_ptr((Ptr)0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline PyObject* reference_arg_to_python<T>::get_object(T& x)
|
||||
{
|
||||
to_python_indirect<T&,python::detail::make_reference_holder> convert;
|
||||
return convert(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline reference_arg_to_python<T>::reference_arg_to_python(T& x)
|
||||
: handle<>(reference_arg_to_python<T>::get_object(x))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline shared_ptr_arg_to_python<T>::shared_ptr_arg_to_python(T const& x)
|
||||
: handle<>(shared_ptr_to_python(x))
|
||||
{
|
||||
}
|
||||
|
||||
template <class Ptr>
|
||||
inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x)
|
||||
: handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x))
|
||||
{
|
||||
detail::reject_raw_object_ptr((Ptr)0);
|
||||
}
|
||||
|
||||
template <class Ptr>
|
||||
inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)
|
||||
{
|
||||
to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
|
||||
return convert(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline arg_to_python<T>::arg_to_python(T const& x)
|
||||
: base(x)
|
||||
{}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // ARG_TO_PYTHON_DWA200265_HPP
|
||||
@@ -1,34 +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 ARG_TO_PYTHON_BASE_DWA200237_HPP
|
||||
# define ARG_TO_PYTHON_BASE_DWA200237_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct registration;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct BOOST_PYTHON_DECL arg_to_python_base
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179
|
||||
: handle<>
|
||||
# endif
|
||||
{
|
||||
arg_to_python_base(void const volatile* source, registration const&);
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102179
|
||||
PyObject* get() const { return m_ptr.get(); }
|
||||
PyObject* release() { return m_ptr.release(); }
|
||||
private:
|
||||
handle<> m_ptr;
|
||||
# endif
|
||||
};
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // ARG_TO_PYTHON_BASE_DWA200237_HPP
|
||||
@@ -1,50 +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 AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
|
||||
# define AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// Given a typesafe to_python conversion function, produces a
|
||||
// to_python_function_t which can be registered in the usual way.
|
||||
template <class T, class ToPython>
|
||||
struct as_to_python_function
|
||||
{
|
||||
// Assertion functions used to prevent wrapping of converters
|
||||
// which take non-const reference parameters. The T* argument in
|
||||
// the first overload ensures it isn't used in case T is a
|
||||
// reference.
|
||||
template <class U>
|
||||
static int convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0);
|
||||
template <class U>
|
||||
static int convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...);
|
||||
|
||||
static PyObject* convert(void const* x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
sizeof(
|
||||
convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L))
|
||||
== sizeof(int));
|
||||
|
||||
// Yes, the const_cast below opens a hole in const-correctness,
|
||||
// but it's needed to convert auto_ptr<U> to python.
|
||||
//
|
||||
// How big a hole is it? It allows ToPython::convert() to be
|
||||
// a function which modifies its argument. The upshot is that
|
||||
// client converters applied to const objects may invoke
|
||||
// undefined behavior. The damage, however, is limited by the
|
||||
// use of the assertion function. Thus, the only way this can
|
||||
// modify its argument is if T is an auto_ptr-like type. There
|
||||
// is still a const-correctness hole w.r.t. auto_ptr<U> const,
|
||||
// but c'est la vie.
|
||||
return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
|
||||
@@ -1,132 +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 BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# define BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <string>
|
||||
# include <complex>
|
||||
# include <boost/limits.hpp>
|
||||
|
||||
// Since all we can use to decide how to convert an object to_python
|
||||
// is its C++ type, there can be only one such converter for each
|
||||
// type. Therefore, for built-in conversions we can bypass registry
|
||||
// lookups using explicit specializations of arg_to_python and
|
||||
// result_to_python.
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace converter
|
||||
{
|
||||
template <class T> struct arg_to_python;
|
||||
BOOST_PYTHON_DECL PyObject* do_return_to_python(char);
|
||||
BOOST_PYTHON_DECL PyObject* do_return_to_python(char const*);
|
||||
BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject*);
|
||||
BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject*);
|
||||
}
|
||||
|
||||
// Provide specializations of to_python_value
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Since there's no registry lookup, always report the existence of
|
||||
// a converter.
|
||||
struct builtin_to_python
|
||||
{
|
||||
// This information helps make_getter() decide whether to try to
|
||||
// return an internal reference or not. I don't like it much,
|
||||
// but it will have to serve for now.
|
||||
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
|
||||
};
|
||||
}
|
||||
|
||||
// Use expr to create the PyObject corresponding to x
|
||||
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
template <> struct to_python_value<T&> \
|
||||
: detail::builtin_to_python \
|
||||
{ \
|
||||
inline PyObject* operator()(T const& x) const \
|
||||
{ \
|
||||
return (expr); \
|
||||
} \
|
||||
}; \
|
||||
template <> struct to_python_value<T const&> \
|
||||
: detail::builtin_to_python \
|
||||
{ \
|
||||
inline PyObject* operator()(T const& x) const \
|
||||
{ \
|
||||
return (expr); \
|
||||
} \
|
||||
};
|
||||
|
||||
# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
namespace converter \
|
||||
{ \
|
||||
template <> struct arg_to_python< T > \
|
||||
: handle<> \
|
||||
{ \
|
||||
arg_to_python(T const& x) \
|
||||
: python::handle<>(expr) {} \
|
||||
}; \
|
||||
}
|
||||
|
||||
// Specialize argument and return value converters for T using expr
|
||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \
|
||||
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
|
||||
|
||||
// Specialize converters for signed and unsigned T to Python Int
|
||||
# define BOOST_PYTHON_TO_INT(T) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
|
||||
unsigned T \
|
||||
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
|
||||
std::numeric_limits<long>::max()) \
|
||||
? PyLong_FromUnsignedLong(x) \
|
||||
: PyInt_FromLong(x))
|
||||
|
||||
// Bool is not signed.
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x))
|
||||
|
||||
// note: handles signed char and unsigned char, but not char (see below)
|
||||
BOOST_PYTHON_TO_INT(char)
|
||||
|
||||
BOOST_PYTHON_TO_INT(short)
|
||||
BOOST_PYTHON_TO_INT(int)
|
||||
BOOST_PYTHON_TO_INT(long)
|
||||
|
||||
// using Python's macro instead of Boost's - we don't seem to get the
|
||||
// config right all the time.
|
||||
# ifdef HAVE_LONG_LONG
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, PyLong_FromLongLong(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong(x))
|
||||
# endif
|
||||
|
||||
# undef BOOST_TO_PYTHON_INT
|
||||
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromStringAndSize(x.c_str(),x.size()))
|
||||
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_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
|
||||
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
|
||||
{
|
||||
|
||||
void initialize_builtin_converters();
|
||||
|
||||
}
|
||||
|
||||
}} // namespace boost::python::converter
|
||||
|
||||
#endif // BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
@@ -1,18 +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 CONSTRUCTOR_FUNCTION_DWA200278_HPP
|
||||
# define CONSTRUCTOR_FUNCTION_DWA200278_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// Declares the type of functions used to construct C++ objects for
|
||||
// rvalue from_python conversions.
|
||||
struct rvalue_from_python_stage1_data;
|
||||
typedef void (*constructor_function)(PyObject* source, rvalue_from_python_stage1_data*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CONSTRUCTOR_FUNCTION_DWA200278_HPP
|
||||
@@ -1,15 +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 CONVERTIBLE_FUNCTION_DWA200278_HPP
|
||||
# define CONVERTIBLE_FUNCTION_DWA200278_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
typedef void* (*convertible_function)(PyObject*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CONVERTIBLE_FUNCTION_DWA200278_HPP
|
||||
@@ -1,43 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef FIND_FROM_PYTHON_DWA2002223_HPP
|
||||
# define FIND_FROM_PYTHON_DWA2002223_HPP
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct registration;
|
||||
|
||||
|
||||
BOOST_PYTHON_DECL void* get_lvalue_from_python(
|
||||
PyObject* source, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python(
|
||||
PyObject* source, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
|
||||
PyObject* source, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
|
||||
PyObject* source, rvalue_from_python_stage1_data&, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL void* rvalue_result_from_python(
|
||||
PyObject*, rvalue_from_python_stage1_data&);
|
||||
|
||||
BOOST_PYTHON_DECL void* reference_result_from_python(PyObject*, registration const&);
|
||||
BOOST_PYTHON_DECL void* pointer_result_from_python(PyObject*, registration const&);
|
||||
|
||||
BOOST_PYTHON_DECL void void_result_from_python(PyObject*);
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject*, registration const&);
|
||||
BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject*, registration const&);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FIND_FROM_PYTHON_DWA2002223_HPP
|
||||
@@ -1,43 +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 IMPLICIT_DWA2002326_HPP
|
||||
# define IMPLICIT_DWA2002326_HPP
|
||||
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
# include <boost/python/converter/registrations.hpp>
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
|
||||
# include <boost/python/extract.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class Source, class Target>
|
||||
struct implicit
|
||||
{
|
||||
static void* convertible(PyObject* obj)
|
||||
{
|
||||
// Find a converter which can produce a Source instance from
|
||||
// obj. The user has told us that Source can be converted to
|
||||
// Target, and instantiating construct() below, ensures that
|
||||
// at compile-time.
|
||||
return implicit_rvalue_convertible_from_python(obj, registered<Source>::converters)
|
||||
? obj : 0;
|
||||
}
|
||||
|
||||
static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void* storage = ((rvalue_from_python_storage<Target>*)data)->storage.bytes;
|
||||
|
||||
new (storage) Target(extract<Source>(obj)());
|
||||
|
||||
// record successful construction
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // IMPLICIT_DWA2002326_HPP
|
||||
@@ -1,122 +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 OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/referent_storage.hpp>
|
||||
# include <boost/python/detail/destroy.hpp>
|
||||
# include <boost/python/detail/construct.hpp>
|
||||
# include <boost/python/converter/object_manager.hpp>
|
||||
# include <boost/python/detail/raw_pyobject.hpp>
|
||||
# include <boost/python/tag.hpp>
|
||||
|
||||
//
|
||||
// arg_from_python converters for Python type wrappers, to be used as
|
||||
// base classes for specializations.
|
||||
//
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T>
|
||||
struct object_manager_value_arg_from_python
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
object_manager_value_arg_from_python(PyObject*);
|
||||
bool convertible() const;
|
||||
T operator()(PyObject*) const;
|
||||
private:
|
||||
PyObject* m_source;
|
||||
};
|
||||
|
||||
// Used for converting reference-to-object-manager arguments from
|
||||
// python. The process used here is a little bit odd. Upon
|
||||
// construction, we build the object manager object in the m_result
|
||||
// object, *forcing* it to accept the source Python object by casting
|
||||
// its pointer to detail::borrowed_reference. This is supposed to
|
||||
// bypass any type checking of the source object. The convertible
|
||||
// check then extracts the owned object and checks it. If the check
|
||||
// fails, nothing else in the program ever gets to touch this strange
|
||||
// "forced" object.
|
||||
template <class Ref>
|
||||
struct object_manager_ref_arg_from_python
|
||||
{
|
||||
typedef Ref result_type;
|
||||
|
||||
object_manager_ref_arg_from_python(PyObject*);
|
||||
bool convertible() const;
|
||||
Ref operator()(PyObject*) const;
|
||||
~object_manager_ref_arg_from_python();
|
||||
private:
|
||||
typename python::detail::referent_storage<Ref>::type m_result;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
template <class T>
|
||||
inline object_manager_value_arg_from_python<T>::object_manager_value_arg_from_python(PyObject* x)
|
||||
: m_source(x)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool object_manager_value_arg_from_python<T>::convertible() const
|
||||
{
|
||||
return object_manager_traits<T>::check(m_source);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T object_manager_value_arg_from_python<T>::operator()(PyObject* x) const
|
||||
{
|
||||
return T(python::detail::borrowed_reference(x));
|
||||
}
|
||||
|
||||
template <class Ref>
|
||||
inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_python(PyObject* x)
|
||||
{
|
||||
# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
|
||||
// needed for warning suppression
|
||||
python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x);
|
||||
python::detail::construct_referent<Ref>(&m_result.bytes, x_);
|
||||
# else
|
||||
python::detail::construct_referent<Ref>(&m_result.bytes, (python::detail::borrowed_reference)x);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Ref>
|
||||
inline object_manager_ref_arg_from_python<Ref>::~object_manager_ref_arg_from_python()
|
||||
{
|
||||
python::detail::destroy_referent<Ref>(this->m_result.bytes);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
inline bool object_manager_ref_check(T const& x)
|
||||
{
|
||||
return object_manager_traits<T>::check(get_managed_object(x, tag));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Ref>
|
||||
inline bool object_manager_ref_arg_from_python<Ref>::convertible() const
|
||||
{
|
||||
return detail::object_manager_ref_check(
|
||||
python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0));
|
||||
}
|
||||
|
||||
template <class Ref>
|
||||
inline Ref object_manager_ref_arg_from_python<Ref>::operator()(PyObject*) const
|
||||
{
|
||||
return python::detail::void_ptr_to_reference(
|
||||
this->m_result.bytes, (Ref(*)())0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
@@ -1,231 +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 OBJECT_MANAGER_DWA2002614_HPP
|
||||
# define OBJECT_MANAGER_DWA2002614_HPP
|
||||
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/cast.hpp>
|
||||
# include <boost/python/converter/pyobject_traits.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
|
||||
// Facilities for dealing with types which always manage Python
|
||||
// objects. Some examples are object, list, str, et. al. Different
|
||||
// to_python/from_python conversion rules apply here because in
|
||||
// contrast to other types which are typically embedded inside a
|
||||
// Python object, these are wrapped around a Python object. For most
|
||||
// object managers T, a C++ non-const T reference argument does not
|
||||
// imply the existence of a T lvalue embedded in the corresponding
|
||||
// Python argument, since mutating member functions on T actually only
|
||||
// modify the held Python object.
|
||||
//
|
||||
// handle<T> is an object manager, though strictly speaking it should
|
||||
// not be. In other words, even though mutating member functions of
|
||||
// hanlde<T> actually modify the handle<T> and not the T object,
|
||||
// handle<T>& arguments of wrapped functions will bind to "rvalues"
|
||||
// wrapping the actual Python argument, just as with other object
|
||||
// manager classes. Making an exception for handle<T> is simply not
|
||||
// worth the trouble.
|
||||
//
|
||||
// borrowed<T> cv* is an object manager so that we can use the general
|
||||
// to_python mechanisms to convert raw Python object pointers to
|
||||
// python, without the usual semantic problems of using raw pointers.
|
||||
|
||||
|
||||
// Object Manager Concept requirements:
|
||||
//
|
||||
// T is an Object Manager
|
||||
// p is a PyObject*
|
||||
// x is a T
|
||||
//
|
||||
// * object_manager_traits<T>::is_specialized == true
|
||||
//
|
||||
// * T(detail::borrowed_reference(p))
|
||||
// Manages p without checking its type
|
||||
//
|
||||
// * get_managed_object(x, boost::python::tag)
|
||||
// Convertible to PyObject*
|
||||
//
|
||||
// Additional requirements if T can be converted from_python:
|
||||
//
|
||||
// * T(object_manager_traits<T>::adopt(p))
|
||||
// steals a reference to p, or throws a TypeError exception if
|
||||
// p doesn't have an appropriate type. May assume p is non-null
|
||||
//
|
||||
// * X::check(p)
|
||||
// convertible to bool. True iff T(X::construct(p)) will not
|
||||
// throw.
|
||||
|
||||
// Forward declarations
|
||||
//
|
||||
namespace boost { namespace python
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
class object;
|
||||
}
|
||||
}}
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
|
||||
// Specializations for handle<T>
|
||||
template <class T>
|
||||
struct handle_object_manager_traits
|
||||
: pyobject_traits<typename T::element_type>
|
||||
{
|
||||
private:
|
||||
typedef pyobject_traits<typename T::element_type> base;
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
|
||||
// Initialize with a null_ok pointer for efficiency, bypassing the
|
||||
// null check since the source is always non-null.
|
||||
static null_ok<typename T::element_type>* adopt(PyObject* p)
|
||||
{
|
||||
return python::allow_null(base::checked_downcast(p));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct default_object_manager_traits
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, is_specialized = python::detail::is_borrowed_ptr<T>::value
|
||||
);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct object_manager_traits
|
||||
: mpl::if_c<
|
||||
is_handle<T>::value
|
||||
, handle_object_manager_traits<T>
|
||||
, default_object_manager_traits<T>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// Traits for detecting whether a type is an object manager or a
|
||||
// (cv-qualified) reference to an object manager.
|
||||
//
|
||||
|
||||
template <class T>
|
||||
struct is_object_manager
|
||||
: mpl::bool_<object_manager_traits<T>::is_specialized>
|
||||
{
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager<T&>
|
||||
: is_object_manager<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager<T const&>
|
||||
: is_object_manager<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager<T volatile&>
|
||||
: is_object_manager<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager<T const volatile&>
|
||||
: is_object_manager<T>
|
||||
{
|
||||
};
|
||||
# else
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_reference_to_object_manager)[1];
|
||||
typedef char (&no_reference_to_object_manager)[2];
|
||||
|
||||
// A number of nastinesses go on here in order to work around MSVC6
|
||||
// bugs.
|
||||
template <class T>
|
||||
struct is_object_manager_help
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_object_manager<T>
|
||||
, yes_reference_to_object_manager
|
||||
, no_reference_to_object_manager
|
||||
>::type type;
|
||||
|
||||
// If we just use the type instead of the result of calling this
|
||||
// function, VC6 will ICE.
|
||||
static type call();
|
||||
};
|
||||
|
||||
// A set of overloads for each cv-qualification. The same argument
|
||||
// is passed twice: the first one is used to unwind the cv*, and the
|
||||
// second one is used to avoid relying on partial ordering for
|
||||
// overload resolution.
|
||||
template <class U>
|
||||
typename is_object_manager_help<U>
|
||||
is_object_manager_helper(U*, void*);
|
||||
|
||||
template <class U>
|
||||
typename is_object_manager_help<U>
|
||||
is_object_manager_helper(U const*, void const*);
|
||||
|
||||
template <class U>
|
||||
typename is_object_manager_help<U>
|
||||
is_object_manager_helper(U volatile*, void volatile*);
|
||||
|
||||
template <class U>
|
||||
typename is_object_manager_help<U>
|
||||
is_object_manager_helper(U const volatile*, void const volatile*);
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager_nonref
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager_ref
|
||||
{
|
||||
static T sample_object;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (sizeof(is_object_manager_helper(&sample_object, &sample_object).call())
|
||||
== sizeof(detail::yes_reference_to_object_manager)
|
||||
)
|
||||
);
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_object_manager
|
||||
: mpl::if_<
|
||||
is_reference<T>
|
||||
, detail::is_reference_to_object_manager_ref<T>
|
||||
, detail::is_reference_to_object_manager_nonref<T>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // OBJECT_MANAGER_DWA2002614_HPP
|
||||
@@ -1,69 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef POINTER_TYPE_ID_DWA2002222_HPP
|
||||
# define POINTER_TYPE_ID_DWA2002222_HPP
|
||||
|
||||
# include <boost/python/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 type_info execute(T*(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pointer_typeid_select<true>
|
||||
{
|
||||
template <class T>
|
||||
static inline type_info execute(T* const volatile&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline type_info execute(T*volatile&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline type_info execute(T*const&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline type_info execute(T*&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Usage: pointer_type_id<T>()
|
||||
//
|
||||
// Returns a type_info associated with the type pointed
|
||||
// to by T, which may be a pointer or a reference to a pointer.
|
||||
template <class T>
|
||||
type_info 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
|
||||
@@ -1,42 +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 PYOBJECT_TRAITS_DWA2002720_HPP
|
||||
# define PYOBJECT_TRAITS_DWA2002720_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/pyobject_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class> struct pyobject_traits;
|
||||
|
||||
template <>
|
||||
struct pyobject_traits<PyObject>
|
||||
{
|
||||
// All objects are convertible to PyObject
|
||||
static bool check(PyObject*) { return true; }
|
||||
static PyObject* checked_downcast(PyObject* x) { return x; }
|
||||
};
|
||||
|
||||
//
|
||||
// Specializations
|
||||
//
|
||||
|
||||
# define BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(T) \
|
||||
template <> struct pyobject_traits<Py##T##Object> \
|
||||
: pyobject_type<Py##T##Object, &Py##T##_Type> {}
|
||||
|
||||
// This is not an exhaustive list; should be expanded.
|
||||
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type);
|
||||
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List);
|
||||
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int);
|
||||
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long);
|
||||
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict);
|
||||
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // PYOBJECT_TRAITS_DWA2002720_HPP
|
||||
@@ -1,37 +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 PYOBJECT_TYPE_DWA2002720_HPP
|
||||
# define PYOBJECT_TYPE_DWA2002720_HPP
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/cast.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*);
|
||||
|
||||
// Used as a base class for specializations which need to provide
|
||||
// Python type checking capability.
|
||||
template <class Object, PyTypeObject* pytype>
|
||||
struct pyobject_type
|
||||
{
|
||||
static bool check(PyObject* x)
|
||||
{
|
||||
return ::PyObject_IsInstance(x, (PyObject*)pytype);
|
||||
}
|
||||
|
||||
static Object* checked_downcast(PyObject* x)
|
||||
{
|
||||
return python::downcast<Object>(
|
||||
(checked_downcast_impl)(x, pytype)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // PYOBJECT_TYPE_DWA2002720_HPP
|
||||
@@ -1,99 +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 PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
# define PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
//
|
||||
// arg_from_python converters for Python type wrappers, to be used as
|
||||
// base classes for specializations.
|
||||
//
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <PyTypeObject* python_type>
|
||||
struct pytype_arg_from_python
|
||||
{
|
||||
pytype_arg_from_python(PyObject*);
|
||||
bool convertible() const;
|
||||
private:
|
||||
PyObject* m_src;
|
||||
};
|
||||
|
||||
// rvalue converter base
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
struct pytype_wrapper_value_arg_from_python
|
||||
: pytype_arg_from_python<python_type>
|
||||
{
|
||||
typedef Wrapper result_type;
|
||||
|
||||
pytype_wrapper_value_arg_from_python(PyObject*);
|
||||
Wrapper operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
// Special case for Wrapper& - must store an lvalue internally. This
|
||||
// OK because the entire state of the object is actually in the Python
|
||||
// object.
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
struct pytype_wrapper_ref_arg_from_python
|
||||
: pytype_arg_from_python<python_type>
|
||||
{
|
||||
typedef Wrapper& result_type;
|
||||
|
||||
pytype_wrapper_ref_arg_from_python(PyObject*);
|
||||
Wrapper& operator()(PyObject*) const;
|
||||
private:
|
||||
mutable Wrapper m_result;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
template <PyTypeObject* python_type>
|
||||
inline pytype_arg_from_python<python_type>::pytype_arg_from_python(PyObject* x)
|
||||
: m_src(x)
|
||||
{
|
||||
}
|
||||
|
||||
template <PyTypeObject* python_type>
|
||||
inline bool pytype_arg_from_python<python_type>::convertible() const
|
||||
{
|
||||
return PyObject_IsInstance(m_src, (PyObject*)python_type);
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
pytype_wrapper_value_arg_from_python<Wrapper,python_type>::pytype_wrapper_value_arg_from_python(
|
||||
PyObject* p)
|
||||
: pytype_arg_from_python<python_type>(p)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
Wrapper pytype_wrapper_value_arg_from_python<Wrapper,python_type>::operator()(
|
||||
PyObject* x) const
|
||||
{
|
||||
return Wrapper(python::detail::borrowed_reference(x));
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
pytype_wrapper_ref_arg_from_python<Wrapper,python_type>::pytype_wrapper_ref_arg_from_python(
|
||||
PyObject* p)
|
||||
: pytype_arg_from_python<python_type>(p)
|
||||
, m_result(python::detail::borrowed_reference(p))
|
||||
{
|
||||
}
|
||||
|
||||
template <class Wrapper, PyTypeObject* python_type>
|
||||
Wrapper& pytype_wrapper_ref_arg_from_python<Wrapper,python_type>::operator()(
|
||||
PyObject* x) const
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
|
||||
@@ -1,43 +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 PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
|
||||
# define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
|
||||
|
||||
# include <boost/python/detail/raw_pyobject.hpp>
|
||||
# include <boost/python/cast.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/pyobject_type.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// Provide a forward declaration as a convenience for clients, who all
|
||||
// need it.
|
||||
template <class T> struct object_manager_traits;
|
||||
|
||||
// Derive specializations of object_manager_traits from this class
|
||||
// when T is an object manager for a particular Python type hierarchy.
|
||||
//
|
||||
template <PyTypeObject* pytype, class T>
|
||||
struct pytype_object_manager_traits
|
||||
: pyobject_type<T, pytype> // provides check()
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
static inline python::detail::new_reference adopt(PyObject*);
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <PyTypeObject* pytype, class T>
|
||||
inline python::detail::new_reference pytype_object_manager_traits<pytype,T>::adopt(PyObject* x)
|
||||
{
|
||||
return python::detail::new_reference(python::pytype_check(pytype, x));
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
|
||||
@@ -1,54 +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 REGISTERED_DWA2002710_HPP
|
||||
# define REGISTERED_DWA2002710_HPP
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/registrations.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct registration;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct registered_base
|
||||
{
|
||||
static registration const& converters;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct registered
|
||||
: detail::registered_base<
|
||||
typename add_reference<
|
||||
typename add_cv<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// collapses a few more types to the same static instance
|
||||
template <class T>
|
||||
struct registered<T&> : registered<T> {};
|
||||
# endif
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
registration const& registered_base<T>::converters
|
||||
= registry::lookup(type_id<T>());
|
||||
}
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // REGISTERED_DWA2002710_HPP
|
||||
@@ -1,63 +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 REGISTERED_POINTEE_DWA2002710_HPP
|
||||
# define REGISTERED_POINTEE_DWA2002710_HPP
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/python/converter/pointer_type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct registration;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct registered_pointee
|
||||
: registered<
|
||||
typename remove_pointer<
|
||||
typename remove_cv<
|
||||
typename remove_reference<T>::type
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
# else
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct registered_pointee_base
|
||||
{
|
||||
static registration const& converters;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct registered_pointee
|
||||
: detail::registered_pointee_base<
|
||||
typename add_reference<
|
||||
typename add_cv<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
registration const& registered_pointee_base<T>::converters
|
||||
= registry::lookup(pointer_type_id<T>());
|
||||
}
|
||||
|
||||
# endif
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // REGISTERED_POINTEE_DWA2002710_HPP
|
||||
@@ -1,85 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef REGISTRATIONS_DWA2002223_HPP
|
||||
# define REGISTRATIONS_DWA2002223_HPP
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
|
||||
# include <boost/python/converter/convertible_function.hpp>
|
||||
# include <boost/python/converter/constructor_function.hpp>
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct lvalue_from_python_chain
|
||||
{
|
||||
convertible_function convert;
|
||||
lvalue_from_python_chain* next;
|
||||
};
|
||||
|
||||
struct rvalue_from_python_chain
|
||||
{
|
||||
convertible_function convertible;
|
||||
constructor_function construct;
|
||||
rvalue_from_python_chain* next;
|
||||
};
|
||||
|
||||
struct BOOST_PYTHON_DECL registration
|
||||
{
|
||||
public: // member functions
|
||||
explicit registration(type_info);
|
||||
|
||||
// Convert the appropriately-typed data to Python
|
||||
PyObject* to_python(void const volatile*) const;
|
||||
|
||||
// Return the class object, or raise an appropriate Python
|
||||
// exception if no class has been registered.
|
||||
PyTypeObject* get_class_object() const;
|
||||
|
||||
public: // data members. So sue me.
|
||||
const python::type_info target_type;
|
||||
|
||||
// The chain of eligible from_python converters when an lvalue is required
|
||||
lvalue_from_python_chain* lvalue_chain;
|
||||
|
||||
// The chain of eligible from_python converters when an rvalue is acceptable
|
||||
rvalue_from_python_chain* rvalue_chain;
|
||||
|
||||
// The class object associated with this type
|
||||
PyTypeObject* m_class_object;
|
||||
|
||||
// The unique to_python converter for the associated C++ type.
|
||||
to_python_function_t m_to_python;
|
||||
|
||||
# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
private:
|
||||
void operator=(registration); // This is not defined, and just keeps MWCW happy.
|
||||
# endif
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline registration::registration(type_info target_type)
|
||||
: target_type(target_type)
|
||||
, lvalue_chain(0)
|
||||
, rvalue_chain(0)
|
||||
, m_class_object(0)
|
||||
, m_to_python(0)
|
||||
{}
|
||||
|
||||
inline bool operator<(registration const& lhs, registration const& rhs)
|
||||
{
|
||||
return lhs.target_type < rhs.target_type;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // REGISTRATIONS_DWA2002223_HPP
|
||||
@@ -1,52 +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 REGISTRY_DWA20011127_HPP
|
||||
# define REGISTRY_DWA20011127_HPP
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
# include <boost/python/converter/constructor_function.hpp>
|
||||
# include <boost/python/converter/convertible_function.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct registration;
|
||||
|
||||
// This namespace acts as a sort of singleton
|
||||
namespace registry
|
||||
{
|
||||
// Get the registration corresponding to the type, creating it if neccessary
|
||||
BOOST_PYTHON_DECL registration const& lookup(type_info);
|
||||
|
||||
// Return a pointer to the corresponding registration, if one exists
|
||||
BOOST_PYTHON_DECL registration const* query(type_info);
|
||||
|
||||
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info);
|
||||
|
||||
// Insert an lvalue from_python converter
|
||||
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info);
|
||||
|
||||
// Insert an rvalue from_python converter
|
||||
BOOST_PYTHON_DECL void insert(
|
||||
convertible_function
|
||||
, constructor_function
|
||||
, type_info
|
||||
);
|
||||
|
||||
// Insert an rvalue from_python converter at the tail of the
|
||||
// chain. Used for implicit conversions
|
||||
BOOST_PYTHON_DECL void push_back(
|
||||
convertible_function
|
||||
, constructor_function
|
||||
, type_info
|
||||
);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // REGISTRY_DWA20011127_HPP
|
||||
@@ -1,161 +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 RETURN_FROM_PYTHON_DWA200265_HPP
|
||||
# define RETURN_FROM_PYTHON_DWA200265_HPP
|
||||
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/python/converter/registered_pointee.hpp>
|
||||
# include <boost/python/detail/void_ptr.hpp>
|
||||
# include <boost/python/detail/void_return.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/type_traits/has_trivial_copy.hpp>
|
||||
# include <boost/mpl/and.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T> struct is_object_manager;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct return_pointer_from_python
|
||||
{
|
||||
typedef T result_type;
|
||||
T operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct return_reference_from_python
|
||||
{
|
||||
typedef T result_type;
|
||||
T operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct return_rvalue_from_python
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
return_rvalue_from_python();
|
||||
result_type operator()(PyObject*);
|
||||
private:
|
||||
rvalue_from_python_data<T> m_data;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct return_object_manager_from_python
|
||||
{
|
||||
typedef T result_type;
|
||||
result_type operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct select_return_from_python
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, obj_mgr = is_object_manager<T>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ptr = is_pointer<T>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ref = is_reference<T>::value);
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
obj_mgr
|
||||
, return_object_manager_from_python<T>
|
||||
, typename mpl::if_c<
|
||||
ptr
|
||||
, return_pointer_from_python<T>
|
||||
, typename mpl::if_c<
|
||||
ref
|
||||
, return_reference_from_python<T>
|
||||
, return_rvalue_from_python<T>
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct return_from_python
|
||||
: detail::select_return_from_python<T>::type
|
||||
{
|
||||
};
|
||||
|
||||
// Specialization as a convenience for call and call_method
|
||||
template <>
|
||||
struct return_from_python<void>
|
||||
{
|
||||
typedef python::detail::returnable<void>::type result_type;
|
||||
|
||||
result_type operator()(PyObject* x) const
|
||||
{
|
||||
(void_result_from_python)(x);
|
||||
# ifdef BOOST_NO_VOID_RETURNS
|
||||
return result_type();
|
||||
# endif
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Implementations
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
inline return_rvalue_from_python<T>::return_rvalue_from_python()
|
||||
: m_data(
|
||||
const_cast<registration*>(®istered<T>::converters)
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename return_rvalue_from_python<T>::result_type
|
||||
return_rvalue_from_python<T>::operator()(PyObject* obj)
|
||||
{
|
||||
// Take possession of the source object here. If the result is in
|
||||
// fact going to be a copy of an lvalue embedded in the object,
|
||||
// and we take possession inside rvalue_result_from_python, it
|
||||
// will be destroyed too early.
|
||||
handle<> holder(obj);
|
||||
|
||||
return *(T*)
|
||||
(rvalue_result_from_python)(obj, m_data.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T return_reference_from_python<T>::operator()(PyObject* obj) const
|
||||
{
|
||||
return python::detail::void_ptr_to_reference(
|
||||
(reference_result_from_python)(obj, registered<T>::converters)
|
||||
, (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
|
||||
{
|
||||
return T(
|
||||
(pointer_result_from_python)(obj, registered_pointee<T>::converters)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const
|
||||
{
|
||||
return T(
|
||||
object_manager_traits<T>::adopt(expect_non_null(obj))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // RETURN_FROM_PYTHON_DWA200265_HPP
|
||||
@@ -1,141 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/converter/constructor_function.hpp>
|
||||
# include <boost/python/detail/referent_storage.hpp>
|
||||
# include <boost/python/detail/destroy.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# include <boost/type_traits/add_cv.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
// Data management for potential rvalue conversions from Python to C++
|
||||
// types. When a client requests a conversion to T* or T&, we
|
||||
// generally require that an object of type T exists in the source
|
||||
// Python object, and the code here does not apply**. This implements
|
||||
// conversions which may create new temporaries of type T. The classic
|
||||
// example is a conversion which converts a Python tuple to a
|
||||
// std::vector. Since no std::vector lvalue exists in the Python
|
||||
// object -- it must be created "on-the-fly" by the converter, and
|
||||
// which must manage the lifetime of the created object.
|
||||
//
|
||||
// Note that the client is not precluded from using a registered
|
||||
// lvalue conversion to T in this case. In other words, we will
|
||||
// happily accept a Python object which /does/ contain a std::vector
|
||||
// lvalue, provided an appropriate converter is registered. So, while
|
||||
// this is an rvalue conversion from the client's point-of-view, the
|
||||
// converter registry may serve up lvalue or rvalue conversions for
|
||||
// the target type.
|
||||
//
|
||||
// ** C++ argument from_python conversions to T const& are an
|
||||
// exception to the rule for references: since in C++, const
|
||||
// references can bind to temporary rvalues, we allow rvalue
|
||||
// converters to be chosen when the target type is T const& for some
|
||||
// T.
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// Conversions begin by filling in and returning a copy of this
|
||||
// structure. The process looks up a converter in the rvalue converter
|
||||
// registry for the target type. It calls the convertible() function
|
||||
// of each registered converter, passing the source PyObject* as an
|
||||
// argument, until a non-null result is returned. This result goes in
|
||||
// the convertible field, and the converter's construct() function is
|
||||
// stored in the construct field.
|
||||
//
|
||||
// If no appropriate converter is found, conversion fails and the
|
||||
// convertible field is null. When used in argument conversion for
|
||||
// wrapped C++ functions, it causes overload resolution to reject the
|
||||
// current function but not to fail completely. If an exception is
|
||||
// thrown, overload resolution stops and the exception propagates back
|
||||
// through the caller.
|
||||
//
|
||||
// If an lvalue converter is matched, its convertible() function is
|
||||
// expected to return a pointer to the stored T object; its
|
||||
// construct() function will be NULL. The convertible() function of
|
||||
// rvalue converters may return any non-singular pointer; the actual
|
||||
// target object will only be available once the converter's
|
||||
// construct() function is called.
|
||||
struct rvalue_from_python_stage1_data
|
||||
{
|
||||
void* convertible;
|
||||
constructor_function construct;
|
||||
};
|
||||
|
||||
// Augments rvalue_from_python_stage1_data by adding storage for
|
||||
// constructing an object of remove_reference<T>::type. The
|
||||
// construct() function of rvalue converters (stored in m_construct
|
||||
// above) will cast the rvalue_from_python_stage1_data to an
|
||||
// appropriate instantiation of this template in order to access that
|
||||
// storage.
|
||||
template <class T>
|
||||
struct rvalue_from_python_storage
|
||||
{
|
||||
rvalue_from_python_stage1_data stage1;
|
||||
|
||||
// Storage for the result, in case an rvalue must be constructed
|
||||
typename python::detail::referent_storage<
|
||||
typename add_reference<T>::type
|
||||
>::type storage;
|
||||
};
|
||||
|
||||
// Augments rvalue_from_python_storage<T> with a destructor. If
|
||||
// stage1.convertible == storage.bytes, it indicates that an object of
|
||||
// remove_reference<T>::type has been constructed in storage and
|
||||
// should will be destroyed in ~rvalue_from_python_data(). It is
|
||||
// crucial that successful rvalue conversions establish this equality
|
||||
// and that unsuccessful ones do not.
|
||||
template <class T>
|
||||
struct rvalue_from_python_data : rvalue_from_python_storage<T>
|
||||
{
|
||||
# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \
|
||||
&& (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \
|
||||
&& (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \
|
||||
&& !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */
|
||||
// This must always be a POD struct with m_data its first member.
|
||||
BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0);
|
||||
# endif
|
||||
|
||||
// The usual constructor
|
||||
rvalue_from_python_data(rvalue_from_python_stage1_data const&);
|
||||
|
||||
// This constructor just sets m_convertible -- used by
|
||||
// implicitly_convertible<> to perform the final step of the
|
||||
// conversion, where the construct() function is already known.
|
||||
rvalue_from_python_data(void* convertible);
|
||||
|
||||
// Destroys any object constructed in the storage.
|
||||
~rvalue_from_python_data();
|
||||
private:
|
||||
typedef typename add_reference<typename add_cv<T>::type>::type ref_type;
|
||||
};
|
||||
|
||||
//
|
||||
// Implementataions
|
||||
//
|
||||
template <class T>
|
||||
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1)
|
||||
{
|
||||
this->stage1 = stage1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_from_python_data<T>::rvalue_from_python_data(void* convertible)
|
||||
{
|
||||
this->stage1.convertible = convertible;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_from_python_data<T>::~rvalue_from_python_data()
|
||||
{
|
||||
if (this->stage1.convertible == this->storage.bytes)
|
||||
python::detail::destroy_referent<ref_type>(this->storage.bytes);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
@@ -1,23 +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 SHARED_PTR_DELETER_DWA2002121_HPP
|
||||
# define SHARED_PTR_DELETER_DWA2002121_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL shared_ptr_deleter
|
||||
{
|
||||
shared_ptr_deleter(handle<> owner);
|
||||
~shared_ptr_deleter();
|
||||
|
||||
void operator()(void const*);
|
||||
|
||||
handle<> owner;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // SHARED_PTR_DELETER_DWA2002121_HPP
|
||||
@@ -1,53 +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 SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
|
||||
# define SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
|
||||
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T>
|
||||
struct shared_ptr_from_python
|
||||
{
|
||||
shared_ptr_from_python()
|
||||
{
|
||||
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >());
|
||||
}
|
||||
|
||||
static shared_ptr_from_python const registration;
|
||||
private:
|
||||
static void* convertible(PyObject* p)
|
||||
{
|
||||
return p == Py_None
|
||||
? p
|
||||
: converter::get_lvalue_from_python(p, registered<T>::converters)
|
||||
;
|
||||
}
|
||||
|
||||
static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void* const storage = ((converter::rvalue_from_python_storage<shared_ptr<T> >*)data)->storage.bytes;
|
||||
// Deal with the "None" case.
|
||||
if (data->convertible == source)
|
||||
new (storage) shared_ptr<T>();
|
||||
else
|
||||
new (storage) shared_ptr<T>(
|
||||
static_cast<T*>(data->convertible),
|
||||
shared_ptr_deleter(handle<>(borrowed(source)))
|
||||
);
|
||||
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
shared_ptr_from_python<T> const shared_ptr_from_python<T>::registration;
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright David Abrahams 2003. 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 SHARED_PTR_TO_PYTHON_DWA2003224_HPP
|
||||
# define SHARED_PTR_TO_PYTHON_DWA2003224_HPP
|
||||
|
||||
# include <boost/python/refcount.hpp>
|
||||
# include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T>
|
||||
PyObject* shared_ptr_to_python(shared_ptr<T> const& x)
|
||||
{
|
||||
if (shared_ptr_deleter* d = boost::get_deleter<shared_ptr_deleter>(x))
|
||||
return incref(d->owner.get());
|
||||
else
|
||||
return converter::registered<shared_ptr<T> const&>::converters.to_python(&x);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // SHARED_PTR_TO_PYTHON_DWA2003224_HPP
|
||||
@@ -1,20 +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 TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// The type of stored function pointers which actually do conversion
|
||||
// by-value. The void* points to the object to be converted, and
|
||||
// type-safety is preserved through runtime registration.
|
||||
typedef PyObject* (*to_python_function_t)(void const*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
@@ -1,42 +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 COPY_CONST_REFERENCE_DWA2002131_HPP
|
||||
# define COPY_CONST_REFERENCE_DWA2002131_HPP
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/python/to_python_value.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct copy_const_reference_expects_a_const_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
struct copy_const_reference
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::if_c<
|
||||
detail::is_reference_to_const<T>::value
|
||||
, to_python_value<T>
|
||||
, detail::copy_const_reference_expects_a_const_reference_return_type<T>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // COPY_CONST_REFERENCE_DWA2002131_HPP
|
||||
@@ -1,42 +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 COPY_NON_CONST_REFERENCE_DWA2002131_HPP
|
||||
# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/python/to_python_value.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct copy_non_const_reference_expects_a_non_const_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
struct copy_non_const_reference
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::if_c<
|
||||
boost::python::detail::is_reference_to_non_const<T>::value
|
||||
, to_python_value<T>
|
||||
, detail::copy_non_const_reference_expects_a_non_const_reference_return_type<T>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // COPY_NON_CONST_REFERENCE_DWA2002131_HPP
|
||||
@@ -1,144 +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 DATA_MEMBERS_DWA2002328_HPP
|
||||
# define DATA_MEMBERS_DWA2002328_HPP
|
||||
|
||||
# include <boost/python/return_value_policy.hpp>
|
||||
# include <boost/python/return_by_value.hpp>
|
||||
# include <boost/python/return_internal_reference.hpp>
|
||||
# include <boost/python/arg_from_python.hpp>
|
||||
|
||||
# include <boost/python/object/function_object.hpp>
|
||||
|
||||
# include <boost/python/converter/builtin_converters.hpp>
|
||||
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/add_const.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
|
||||
# include <boost/bind.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Data, class Class, class Policies>
|
||||
struct member
|
||||
{
|
||||
static PyObject* get(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies)
|
||||
{
|
||||
arg_from_python<Class*> c0(PyTuple_GET_ITEM(args_, 0));
|
||||
if (!c0.convertible()) return 0;
|
||||
|
||||
// find the result converter
|
||||
typedef typename Policies::result_converter result_converter;
|
||||
typedef typename boost::add_reference<Data>::type source;
|
||||
typename mpl::apply1<result_converter,source>::type cr;
|
||||
|
||||
if (!policies.precall(args_)) return 0;
|
||||
|
||||
PyObject* result = cr( (c0(PyTuple_GET_ITEM(args_, 0)))->*pm );
|
||||
|
||||
return policies.postcall(args_, result);
|
||||
}
|
||||
|
||||
static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies)
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
arg_from_python<Class&> c0(PyTuple_GET_ITEM(args_, 0));
|
||||
if (!c0.convertible()) return 0;
|
||||
|
||||
typedef typename add_const<Data>::type target1;
|
||||
typedef typename add_reference<target1>::type target;
|
||||
arg_from_python<target> c1(PyTuple_GET_ITEM(args_, 1));
|
||||
|
||||
if (!c1.convertible()) return 0;
|
||||
|
||||
if (!policies.precall(args_)) return 0;
|
||||
|
||||
(c0(PyTuple_GET_ITEM(args_, 0))).*pm = c1(PyTuple_GET_ITEM(args_, 1));
|
||||
|
||||
return policies.postcall(args_, detail::none());
|
||||
}
|
||||
};
|
||||
|
||||
// If it's a regular class type (not an object manager or other
|
||||
// type for which we have to_python specializations, use
|
||||
// return_internal_reference so that we can do things like
|
||||
// x.y.z = 1
|
||||
// and get the right result.
|
||||
template <class T>
|
||||
struct default_getter_policy
|
||||
{
|
||||
typedef typename add_reference<
|
||||
typename add_const<T>::type
|
||||
>::type t_cref;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, by_ref = to_python_value<t_cref>::uses_registry
|
||||
&& is_reference_to_class<t_cref>::value);
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
by_ref
|
||||
, return_internal_reference<>
|
||||
, return_value_policy<return_by_value>
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class C, class D>
|
||||
object make_getter(D C::*pm)
|
||||
{
|
||||
typedef typename detail::default_getter_policy<D>::type policy;
|
||||
|
||||
return objects::function_object(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,policy>::get, pm, _1, _2
|
||||
, policy())
|
||||
, 1);
|
||||
|
||||
}
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
object make_getter(D C::*pm, Policies const& policies)
|
||||
{
|
||||
return objects::function_object(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,Policies>::get, pm, _1, _2
|
||||
, policies)
|
||||
, 1);
|
||||
}
|
||||
|
||||
template <class C, class D>
|
||||
object make_setter(D C::*pm)
|
||||
{
|
||||
return objects::function_object(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,default_call_policies>::set, pm, _1, _2
|
||||
, default_call_policies())
|
||||
, 2);
|
||||
}
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
object make_setter(D C::*pm, Policies const& policies)
|
||||
{
|
||||
return objects::function_object(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,Policies>::set, pm, _1, _2
|
||||
, policies)
|
||||
, 2);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // DATA_MEMBERS_DWA2002328_HPP
|
||||
@@ -1,113 +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 DEF_DWA200292_HPP
|
||||
# define DEF_DWA200292_HPP
|
||||
|
||||
# include <boost/python/object_fwd.hpp>
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/detail/def_helper.hpp>
|
||||
# include <boost/python/detail/overloads_fwd.hpp>
|
||||
# include <boost/python/scope.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
# include <boost/python/detail/scope.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace error
|
||||
{
|
||||
// Compile-time error messages
|
||||
template <bool> struct multiple_functions_passed_to_def;
|
||||
template <> struct multiple_functions_passed_to_def<false> { typedef char type; };
|
||||
}
|
||||
|
||||
//
|
||||
// def_from_helper --
|
||||
//
|
||||
// Use a def_helper to define a regular wrapped function in the current scope.
|
||||
template <class F, class Helper>
|
||||
void def_from_helper(
|
||||
char const* name, F const& fn, Helper const& helper)
|
||||
{
|
||||
// Must not try to use default implementations except with method definitions.
|
||||
typedef typename error::multiple_functions_passed_to_def<
|
||||
Helper::has_default_implementation
|
||||
>::type assertion;
|
||||
|
||||
detail::scope_setattr_doc(
|
||||
name, boost::python::make_function(
|
||||
fn
|
||||
, helper.policies()
|
||||
, helper.keywords())
|
||||
, helper.doc()
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// These two overloads discriminate between def() as applied to
|
||||
// regular functions and def() as applied to the result of
|
||||
// BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
|
||||
// discriminate.
|
||||
//
|
||||
template <class Fn, class A1>
|
||||
void
|
||||
def_maybe_overloads(
|
||||
char const* name
|
||||
, Fn fn
|
||||
, A1 const& a1
|
||||
, ...)
|
||||
{
|
||||
detail::def_from_helper(name, fn, def_helper<A1>(a1));
|
||||
}
|
||||
|
||||
template <class StubsT, class SigT>
|
||||
void def_maybe_overloads(
|
||||
char const* name
|
||||
, SigT sig
|
||||
, StubsT const& stubs
|
||||
, detail::overloads_base const*)
|
||||
{
|
||||
scope current;
|
||||
|
||||
detail::define_with_defaults(
|
||||
name, stubs, current, detail::get_signature(sig));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
object make_function1(T fn, ...) { return make_function(fn); }
|
||||
|
||||
inline
|
||||
object make_function1(object const& x, object const*) { return x; }
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
void def(char const* name, Fn fn)
|
||||
{
|
||||
detail::scope_setattr_doc(name, detail::make_function1(fn, &fn), 0);
|
||||
}
|
||||
|
||||
template <class Arg1T, class Arg2T>
|
||||
void def(char const* name, Arg1T arg1, Arg2T const& arg2)
|
||||
{
|
||||
detail::def_maybe_overloads(name, arg1, arg2, &arg2);
|
||||
}
|
||||
|
||||
template <class F, class A1, class A2>
|
||||
void def(char const* name, F f, A1 const& a1, A2 const& a2)
|
||||
{
|
||||
detail::def_from_helper(name, f, detail::def_helper<A1,A2>(a1,a2));
|
||||
}
|
||||
|
||||
template <class F, class A1, class A2, class A3>
|
||||
void def(char const* name, F f, A1 const& a1, A2 const& a2, A3 const& a3)
|
||||
{
|
||||
detail::def_from_helper(name, f, detail::def_helper<A1,A2,A3>(a1,a2,a3));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // DEF_DWA200292_HPP
|
||||
@@ -1,78 +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 DEFAULT_CALL_POLICIES_DWA2002131_HPP
|
||||
# define DEFAULT_CALL_POLICIES_DWA2002131_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/python/to_python_value.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// for "readable" error messages
|
||||
template <class T> struct specify_a_return_value_policy_to_wrap_functions_returning
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
struct default_result_converter;
|
||||
|
||||
struct default_call_policies
|
||||
{
|
||||
// Nothing to do
|
||||
static bool precall(PyObject*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pass the result through
|
||||
static PyObject* postcall(PyObject*, PyObject* result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef default_result_converter result_converter;
|
||||
};
|
||||
|
||||
struct default_result_converter
|
||||
{
|
||||
template <class R>
|
||||
struct apply
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference<R>::value || is_pointer<R>::value);
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
is_illegal
|
||||
, detail::specify_a_return_value_policy_to_wrap_functions_returning<R>
|
||||
, boost::python::to_python_value<
|
||||
typename add_reference<typename add_const<R>::type>::type
|
||||
>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
// Exceptions for c strings an PyObject*s
|
||||
template <>
|
||||
struct default_result_converter::apply<char const*>
|
||||
{
|
||||
typedef boost::python::to_python_value<char const*const&> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct default_result_converter::apply<PyObject*>
|
||||
{
|
||||
typedef boost::python::to_python_value<PyObject*const&> type;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // DEFAULT_CALL_POLICIES_DWA2002131_HPP
|
||||
@@ -1,27 +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 AIX_INIT_MODULE_DWA2002529_HPP
|
||||
# define AIX_INIT_MODULE_DWA2002529_HPP
|
||||
# ifdef _AIX
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <cstdio>
|
||||
# ifdef __KCC
|
||||
# include <iostream> // this works around a problem in KCC 4.0f
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
extern "C"
|
||||
{
|
||||
typedef PyObject* (*so_load_function)(char*,char*,FILE*);
|
||||
}
|
||||
|
||||
void aix_init_module(so_load_function, char const* name, void (*init_module)());
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
# endif
|
||||
|
||||
#endif // AIX_INIT_MODULE_DWA2002529_HPP
|
||||
@@ -1,19 +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 BOOST_PYTHON_API_PLACE_HOLDER_HPP
|
||||
#define BOOST_PYTHON_API_PLACE_HOLDER_HPP
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
inline long len(object const& obj)
|
||||
{
|
||||
long result = PyObject_Length(obj.ptr());
|
||||
if (PyErr_Occurred()) throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP
|
||||
@@ -1,112 +0,0 @@
|
||||
#ifndef BORROWED_PTR_DWA20020601_HPP
|
||||
# define BORROWED_PTR_DWA20020601_HPP
|
||||
// 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.
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/tag.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template<class T> class borrowed
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
struct is_borrowed_ptr
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
# if !defined(__MWERKS__) || __MWERKS__ > 0x3000
|
||||
template<typename T>
|
||||
struct is_borrowed_ptr<borrowed<T>*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_borrowed_ptr<borrowed<T> const*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_borrowed_ptr<borrowed<T> volatile*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_borrowed_ptr<borrowed<T> const volatile*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
# else
|
||||
template<typename T>
|
||||
struct is_borrowed
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
template<typename T>
|
||||
struct is_borrowed<borrowed<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template<typename T>
|
||||
struct is_borrowed_ptr<T*>
|
||||
: is_borrowed<typename remove_cv<T>::type>
|
||||
{
|
||||
};
|
||||
# endif
|
||||
|
||||
# else // no partial specialization
|
||||
|
||||
typedef char (&yes_borrowed_ptr_t)[1];
|
||||
typedef char (&no_borrowed_ptr_t)[2];
|
||||
|
||||
no_borrowed_ptr_t is_borrowed_ptr_test(...);
|
||||
|
||||
template <class T>
|
||||
typename mpl::if_c<
|
||||
is_pointer<T>::value
|
||||
, T
|
||||
, int
|
||||
>::type
|
||||
is_borrowed_ptr_test1(boost::type<T>);
|
||||
|
||||
template<typename T>
|
||||
yes_borrowed_ptr_t is_borrowed_ptr_test(borrowed<T> const volatile*);
|
||||
|
||||
template<typename T>
|
||||
class is_borrowed_ptr
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_borrowed_ptr_test(is_borrowed_ptr_test1(boost::type<T>())))
|
||||
== sizeof(detail::yes_borrowed_ptr_t)));
|
||||
};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T* get_managed_object(detail::borrowed<T> const volatile* p, tag_t)
|
||||
{
|
||||
return (T*)p;
|
||||
}
|
||||
|
||||
}} // namespace boost::python::detail
|
||||
|
||||
#endif // #ifndef BORROWED_PTR_DWA20020601_HPP
|
||||
@@ -1,175 +0,0 @@
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
// 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 CALLER_DWA20021121_HPP
|
||||
# define CALLER_DWA20021121_HPP
|
||||
|
||||
# include <boost/compressed_pair.hpp>
|
||||
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/preprocessor/iteration/local.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
# include <boost/preprocessor/repetition/repeat.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/preprocessor/dec.hpp>
|
||||
# include <boost/preprocessor/if.hpp>
|
||||
|
||||
# include <boost/python/detail/invoke.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// This "result converter" is really just used as
|
||||
// a dispatch tag to invoke(...), selecting the appropriate
|
||||
// implementation
|
||||
typedef int void_result_to_python;
|
||||
|
||||
// A metafunction taking an iterator FunctionIter to a metafunction
|
||||
// class and an iterator ArgIter to an argument, which applies the
|
||||
// result of dereferencing FunctionIter to the result of dereferencing
|
||||
// ArgIter
|
||||
template <class FunctionIter, class ArgIter>
|
||||
struct apply_iter1
|
||||
: mpl::apply1<typename FunctionIter::type, typename ArgIter::type> {};
|
||||
|
||||
// Given a model of CallPolicies and a C++ result type, this
|
||||
// metafunction selects the appropriate converter to use for
|
||||
// converting the result to python.
|
||||
template <class Policies, class Result>
|
||||
struct select_result_converter
|
||||
: mpl::if_<
|
||||
is_same<Result,void>
|
||||
, void_result_to_python
|
||||
, typename mpl::apply1<typename Policies::result_converter,Result>::type*
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <unsigned> struct caller_arity;
|
||||
|
||||
# define BOOST_PYTHON_NEXT(init,name,n) \
|
||||
typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n;
|
||||
|
||||
# define BOOST_PYTHON_ARG_CONVERTER(n) \
|
||||
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
|
||||
BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \
|
||||
typedef typename apply_iter1<conv_iter##n,arg_iter##n>::type c_t##n; \
|
||||
c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \
|
||||
if (!c##n.convertible()) \
|
||||
return 0;
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
# undef BOOST_PYTHON_ARG_CONVERTER
|
||||
# undef BOOST_PYTHON_NEXT
|
||||
|
||||
// A metafunction returning the base class used for caller<class F,
|
||||
// class ConverterGenerators, class CallPolicies, class Sig>.
|
||||
template <class F, class ConverterGenerators, class CallPolicies, class Sig>
|
||||
struct caller_base_select
|
||||
{
|
||||
enum { arity = mpl::size<Sig>::value - 1 };
|
||||
typedef typename caller_arity<arity>::template impl<F,ConverterGenerators,CallPolicies,Sig> type;
|
||||
};
|
||||
|
||||
// A function object type which wraps C++ objects as Python callable
|
||||
// objects.
|
||||
//
|
||||
// Template Arguments:
|
||||
//
|
||||
// F -
|
||||
// the C++ `function object' that will be called. Might
|
||||
// actually be any data for which an appropriate invoke_tag() can
|
||||
// be generated. invoke(...) takes care of the actual invocation syntax.
|
||||
//
|
||||
// ConverterGenerators -
|
||||
// An MPL iterator type over a sequence of metafunction classes
|
||||
// that can be applied to element 1...N of Sig to produce
|
||||
// argument from_python converters for the arguments
|
||||
//
|
||||
// CallPolicies -
|
||||
// The precall, postcall, and what kind of resultconverter to
|
||||
// generate for mpl::front<Sig>::type
|
||||
//
|
||||
// Sig -
|
||||
// The `intended signature' of the function. An MPL sequence
|
||||
// beginning with a result type and continuing with a list of
|
||||
// argument types.
|
||||
template <class F, class ConverterGenerators, class CallPolicies, class Sig>
|
||||
struct caller
|
||||
: caller_base_select<F,ConverterGenerators,CallPolicies,Sig>::type
|
||||
{
|
||||
typedef typename caller_base_select<
|
||||
F,ConverterGenerators,CallPolicies,Sig
|
||||
>::type base;
|
||||
|
||||
typedef PyObject* result_type;
|
||||
|
||||
caller(F f, CallPolicies p) : base(f,p) {}
|
||||
};
|
||||
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
# endif // CALLER_DWA20021121_HPP
|
||||
|
||||
#else
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
|
||||
template <>
|
||||
struct caller_arity<N>
|
||||
{
|
||||
template <class F, class ConverterGenerators, class Policies, class Sig>
|
||||
struct impl
|
||||
{
|
||||
impl(F f, Policies p) : m_data(f,p) {}
|
||||
|
||||
PyObject* operator()(PyObject* args_, PyObject*) // eliminate
|
||||
// this
|
||||
// trailing
|
||||
// keyword dict
|
||||
{
|
||||
typedef typename mpl::begin<Sig>::type first;
|
||||
typedef typename first::type result_t;
|
||||
typedef typename select_result_converter<Policies, result_t>::type result_converter;
|
||||
# if N
|
||||
# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
|
||||
# define BOOST_PP_LOCAL_LIMITS (0, N-1)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
# endif
|
||||
// all converters have been checked. Now we can do the
|
||||
// precall part of the policy
|
||||
if (!m_data.second().precall(args_))
|
||||
return 0;
|
||||
|
||||
typedef typename detail::invoke_tag<F>::type tag;
|
||||
|
||||
PyObject* result = detail::invoke(
|
||||
tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c));
|
||||
|
||||
return m_data.second().postcall(args_, result);
|
||||
}
|
||||
private:
|
||||
compressed_pair<F,Policies> m_data;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
|
||||
|
||||
@@ -1,23 +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 CHAR_ARRAY_DWA2002129_HPP
|
||||
# define CHAR_ARRAY_DWA2002129_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// This little package is used to transmit the number of arguments
|
||||
// from the helper functions below to the sizeof() expression below.
|
||||
// Because we can never have an array of fewer than 1 element, we
|
||||
// add 1 to n and then subtract 1 from the result of sizeof() below.
|
||||
template <int n>
|
||||
struct char_array
|
||||
{
|
||||
char elements[n+1];
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CHAR_ARRAY_DWA2002129_HPP
|
||||
@@ -1,114 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. 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.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
// Revision History:
|
||||
// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams)
|
||||
|
||||
#ifndef CONFIG_DWA052200_H_
|
||||
# define CONFIG_DWA052200_H_
|
||||
|
||||
#if defined(__ALPHA) && defined(__osf__) && defined(__DECCXX_VER)
|
||||
# include <pyconfig.h>
|
||||
#endif
|
||||
# include <boost/config.hpp>
|
||||
|
||||
# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
// A gcc bug forces some symbols into the global namespace
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
# define BOOST_PYTHON_CONVERSION
|
||||
# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x
|
||||
# else
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python {
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python
|
||||
# define BOOST_PYTHON_CONVERSION boost::python
|
||||
# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';'
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_MSVC)
|
||||
# if _MSC_VER <= 1200
|
||||
# define BOOST_MSVC6_OR_EARLIER 1
|
||||
# endif
|
||||
|
||||
# pragma warning (disable : 4786) // disable truncated debug symbols
|
||||
# pragma warning (disable : 4251) // disable exported dll function
|
||||
# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or 'false'
|
||||
# pragma warning (disable : 4275) // non dll-interface class
|
||||
|
||||
# elif defined(__ICL) && __ICL < 600 // Intel C++ 5
|
||||
|
||||
# pragma warning(disable: 985) // identifier was truncated in debug information
|
||||
|
||||
# endif
|
||||
|
||||
// The STLport puts all of the standard 'C' library names in std (as far as the
|
||||
// user is concerned), but without it you need a fix if you're using MSVC or
|
||||
// Intel C++
|
||||
# if defined(BOOST_MSVC_STD_ITERATOR)
|
||||
# define BOOST_CSTD_
|
||||
# else
|
||||
# define BOOST_CSTD_ std
|
||||
# endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Set up dll import/export options:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
// backwards compatibility:
|
||||
#ifdef BOOST_PYTHON_STATIC_LIB
|
||||
# define BOOST_PYTHON_STATIC_LINK
|
||||
# elif !defined(BOOST_PYTHON_DYNAMIC_LIB)
|
||||
# define BOOST_PYTHON_DYNAMIC_LIB
|
||||
#endif
|
||||
|
||||
#if defined(__MWERKS__) \
|
||||
|| (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730)
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32)
|
||||
# if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_DECL __declspec(dllexport)
|
||||
# define BOOST_PYTHON_BUILD_DLL
|
||||
# else
|
||||
# define BOOST_PYTHON_DECL __declspec(dllimport)
|
||||
# endif
|
||||
|
||||
// MinGW, at least, has some problems exporting template instantiations
|
||||
# if defined(__GNUC__) && __GNUC__ < 3 && !defined(__CYGWIN__)
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_DECL
|
||||
# define BOOST_PYTHON_DECL
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_EXPORT
|
||||
# define BOOST_PYTHON_EXPORT extern
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_PYTHON_NO_TEMPLATE_EXPORT)
|
||||
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL instantiation
|
||||
#else
|
||||
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD
|
||||
#endif
|
||||
|
||||
#if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031)
|
||||
// Replace broken Tru64/cxx offsetof macro
|
||||
# define BOOST_PYTHON_OFFSETOF(s_name, s_member) \
|
||||
((size_t)__INTADDR__(&(((s_name *)0)->s_member)))
|
||||
#else
|
||||
# define BOOST_PYTHON_OFFSETOF offsetof
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_DWA052200_H_
|
||||
@@ -1,43 +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 CONSTRUCT_REFERENCE_DWA2002716_HPP
|
||||
# define CONSTRUCT_REFERENCE_DWA2002716_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class T, class Arg>
|
||||
void construct_pointee(void* storage, Arg& x
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
, T const volatile*
|
||||
# else
|
||||
, T const*
|
||||
# endif
|
||||
)
|
||||
{
|
||||
new (storage) T(x);
|
||||
}
|
||||
|
||||
template <class T, class Arg>
|
||||
void construct_referent_impl(void* storage, Arg& x, T&(*)())
|
||||
{
|
||||
construct_pointee(storage, x, (T*)0);
|
||||
}
|
||||
|
||||
template <class T, class Arg>
|
||||
void construct_referent(void* storage, Arg const& x, T(*tag)() = 0)
|
||||
{
|
||||
construct_referent_impl(storage, x, tag);
|
||||
}
|
||||
|
||||
template <class T, class Arg>
|
||||
void construct_referent(void* storage, Arg& x, T(*tag)() = 0)
|
||||
{
|
||||
construct_referent_impl(storage, x, tag);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CONSTRUCT_REFERENCE_DWA2002716_HPP
|
||||
@@ -1,39 +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 CONVERTIBLE_DWA2002614_HPP
|
||||
# define CONVERTIBLE_DWA2002614_HPP
|
||||
|
||||
# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/type_traits/conversion_traits.hpp>
|
||||
# endif
|
||||
|
||||
// Supplies a runtime is_convertible check which can be used with tag
|
||||
// dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
typedef char* yes_convertible;
|
||||
typedef int* no_convertible;
|
||||
|
||||
template <class Target>
|
||||
struct convertible
|
||||
{
|
||||
# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 || __EDG_VERSION__ == 238
|
||||
static inline no_convertible check(...) { return 0; }
|
||||
static inline yes_convertible check(Target) { return 0; }
|
||||
# else
|
||||
template <class X>
|
||||
static inline typename mpl::if_c<
|
||||
is_convertible<X,Target>::value
|
||||
, yes_convertible
|
||||
, no_convertible
|
||||
>::type check(X const&) { return 0; }
|
||||
# endif
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CONVERTIBLE_DWA2002614_HPP
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright David Abrahams 2003. 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 COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
|
||||
# define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
|
||||
|
||||
#include <boost/python/detail/is_auto_ptr.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class T>
|
||||
struct copy_ctor_mutates_rhs
|
||||
: is_auto_ptr<T>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
|
||||
@@ -1,34 +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 CV_CATEGORY_DWA200222_HPP
|
||||
# define CV_CATEGORY_DWA200222_HPP
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <bool is_const_, bool is_volatile_>
|
||||
struct cv_tag
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_const = is_const_);
|
||||
BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_);
|
||||
};
|
||||
|
||||
typedef cv_tag<false,false> cv_unqualified;
|
||||
typedef cv_tag<true,false> const_;
|
||||
typedef cv_tag<false,true> volatile_;
|
||||
typedef cv_tag<true,true> const_volatile_;
|
||||
|
||||
template <class T>
|
||||
struct cv_category
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
|
||||
typedef cv_tag<c,v> type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CV_CATEGORY_DWA200222_HPP
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright Gottfried Ganßauge 2003. 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 BOOST_PYTHON_DETAIL_DEALLOC_HPP_
|
||||
# define BOOST_PYTHON_DETAIL_DEALLOC_HPP_
|
||||
namespace boost { namespace python { namespace detail {
|
||||
extern "C"
|
||||
{
|
||||
inline void dealloc(PyObject* self)
|
||||
{
|
||||
PyObject_Del(self);
|
||||
}
|
||||
}
|
||||
}}} // namespace boost::python::detail
|
||||
# endif // BOOST_PYTHON_DETAIL_DEALLOC_HPP_
|
||||
@@ -1,77 +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 DECORATED_TYPE_ID_DWA2002517_HPP
|
||||
# define DECORATED_TYPE_ID_DWA2002517_HPP
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct decorated_type_info : totally_ordered<decorated_type_info>
|
||||
{
|
||||
enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 };
|
||||
|
||||
decorated_type_info(type_info, decoration = decoration());
|
||||
|
||||
inline bool operator<(decorated_type_info const& rhs) const;
|
||||
inline bool operator==(decorated_type_info const& rhs) const;
|
||||
|
||||
friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&);
|
||||
|
||||
operator type_info const&() const;
|
||||
private: // type
|
||||
typedef type_info base_id_t;
|
||||
|
||||
private: // data members
|
||||
decoration m_decoration;
|
||||
base_id_t m_base_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline decorated_type_info decorated_type_id(boost::type<T>* = 0)
|
||||
{
|
||||
return decorated_type_info(
|
||||
type_id<T>()
|
||||
, decorated_type_info::decoration(
|
||||
(is_const<T>::value || python::detail::is_reference_to_const<T>::value
|
||||
? decorated_type_info::const_ : 0)
|
||||
| (is_volatile<T>::value || python::detail::is_reference_to_volatile<T>::value
|
||||
? decorated_type_info::volatile_ : 0)
|
||||
| (is_reference<T>::value ? decorated_type_info::reference : 0)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
inline decorated_type_info::decorated_type_info(type_info base_t, decoration decoration)
|
||||
: m_decoration(decoration)
|
||||
, m_base_type(base_t)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const
|
||||
{
|
||||
return m_decoration < rhs.m_decoration
|
||||
|| m_decoration == rhs.m_decoration
|
||||
&& m_base_type < rhs.m_base_type;
|
||||
}
|
||||
|
||||
inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const
|
||||
{
|
||||
return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type;
|
||||
}
|
||||
|
||||
inline decorated_type_info::operator type_info const&() const
|
||||
{
|
||||
return m_base_type;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&);
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // DECORATED_TYPE_ID_DWA2002517_HPP
|
||||
@@ -1,22 +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 DECREF_GUARD_DWA20021220_HPP
|
||||
# define DECREF_GUARD_DWA20021220_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct decref_guard
|
||||
{
|
||||
decref_guard(PyObject* o) : obj(o) {}
|
||||
~decref_guard() { Py_XDECREF(obj); }
|
||||
void cancel() { obj = 0; }
|
||||
private:
|
||||
PyObject* obj;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // DECREF_GUARD_DWA20021220_HPP
|
||||
@@ -1,212 +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 DEF_HELPER_DWA200287_HPP
|
||||
# define DEF_HELPER_DWA200287_HPP
|
||||
|
||||
# include <boost/python/args.hpp>
|
||||
# include <boost/type_traits/ice.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
# include <boost/mpl/and.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# include <boost/mpl/lambda.hpp>
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/tuple/tuple.hpp>
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
struct default_call_policies;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// tuple_extract<Tuple,Predicate>::extract(t) returns the first
|
||||
// element of a Tuple whose type E satisfies the given Predicate
|
||||
// applied to add_reference<E>. The Predicate must be an MPL
|
||||
// metafunction class.
|
||||
template <class Tuple, class Predicate>
|
||||
struct tuple_extract;
|
||||
|
||||
// Implementation class for when the tuple's head type does not
|
||||
// satisfy the Predicate
|
||||
template <bool matched>
|
||||
struct tuple_extract_impl
|
||||
{
|
||||
template <class Tuple, class Predicate>
|
||||
struct apply
|
||||
{
|
||||
typedef typename Tuple::head_type result_type;
|
||||
|
||||
static typename Tuple::head_type extract(Tuple const& x)
|
||||
{
|
||||
return x.get_head();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Implementation specialization for when the tuple's head type
|
||||
// satisfies the predicate
|
||||
template <>
|
||||
struct tuple_extract_impl<false>
|
||||
{
|
||||
template <class Tuple, class Predicate>
|
||||
struct apply
|
||||
{
|
||||
// recursive application of tuple_extract on the tail of the tuple
|
||||
typedef tuple_extract<typename Tuple::tail_type, Predicate> next;
|
||||
typedef typename next::result_type result_type;
|
||||
|
||||
static result_type extract(Tuple const& x)
|
||||
{
|
||||
return next::extract(x.get_tail());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// A metafunction which selects a version of tuple_extract_impl to
|
||||
// use for the implementation of tuple_extract
|
||||
template <class Tuple, class Predicate>
|
||||
struct tuple_extract_base_select
|
||||
{
|
||||
typedef typename Tuple::head_type head_type;
|
||||
typedef typename mpl::apply1<Predicate, typename add_reference<head_type>::type>::type match_t;
|
||||
BOOST_STATIC_CONSTANT(bool, match = match_t::value);
|
||||
typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type;
|
||||
};
|
||||
|
||||
template <class Tuple, class Predicate>
|
||||
struct tuple_extract
|
||||
: tuple_extract_base_select<
|
||||
Tuple
|
||||
, typename mpl::lambda<Predicate>::type
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Specialized extractors for the docstring, keywords, CallPolicies,
|
||||
// and default implementation of virtual functions
|
||||
//
|
||||
|
||||
template <class Tuple>
|
||||
struct doc_extract
|
||||
: tuple_extract<
|
||||
Tuple
|
||||
, mpl::not_<
|
||||
mpl::or_<
|
||||
is_reference_to_class<mpl::_1>
|
||||
, is_reference_to_member_function_pointer<mpl::_1 >
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Tuple>
|
||||
struct keyword_extract
|
||||
: tuple_extract<Tuple, is_reference_to_keywords<mpl::_1 > >
|
||||
{
|
||||
};
|
||||
|
||||
template <class Tuple>
|
||||
struct policy_extract
|
||||
: tuple_extract<
|
||||
Tuple
|
||||
, mpl::and_<
|
||||
mpl::not_<is_same<not_specified const&,mpl::_1> >
|
||||
, is_reference_to_class<mpl::_1 >
|
||||
, mpl::not_<is_reference_to_keywords<mpl::_1 > >
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Tuple>
|
||||
struct default_implementation_extract
|
||||
: tuple_extract<
|
||||
Tuple
|
||||
, is_reference_to_member_function_pointer<mpl::_1 >
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// A helper class for decoding the optional arguments to def()
|
||||
// invocations, which can be supplied in any order and are
|
||||
// discriminated by their type properties. The template parameters
|
||||
// are expected to be the types of the actual (optional) arguments
|
||||
// passed to def().
|
||||
//
|
||||
template <class T1, class T2 = not_specified, class T3 = not_specified, class T4 = not_specified>
|
||||
struct def_helper
|
||||
{
|
||||
// A tuple type which begins with references to the supplied
|
||||
// arguments and ends with actual representatives of the default
|
||||
// types.
|
||||
typedef boost::tuples::tuple<
|
||||
T1 const&
|
||||
, T2 const&
|
||||
, T3 const&
|
||||
, T4 const&
|
||||
, default_call_policies
|
||||
, keywords<0>
|
||||
, char const*
|
||||
, void(not_specified::*)() // A function pointer type which is never an
|
||||
// appropriate default implementation
|
||||
> all_t;
|
||||
|
||||
// Constructors; these initialize an member of the tuple type
|
||||
// shown above.
|
||||
def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {}
|
||||
def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {}
|
||||
def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {}
|
||||
def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {}
|
||||
|
||||
private: // types
|
||||
typedef typename default_implementation_extract<all_t>::result_type default_implementation_t;
|
||||
|
||||
public: // Constants which can be used for static assertions.
|
||||
|
||||
// Users must not supply a default implementation for non-class
|
||||
// methods.
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, has_default_implementation = (
|
||||
!is_same<default_implementation_t, void(not_specified::*)()>::value));
|
||||
|
||||
public: // Extractor functions which pull the appropriate value out
|
||||
// of the tuple
|
||||
char const* doc() const
|
||||
{
|
||||
return doc_extract<all_t>::extract(m_all);
|
||||
}
|
||||
|
||||
typename keyword_extract<all_t>::result_type keywords() const
|
||||
{
|
||||
return keyword_extract<all_t>::extract(m_all);
|
||||
}
|
||||
|
||||
typename policy_extract<all_t>::result_type policies() const
|
||||
{
|
||||
return policy_extract<all_t>::extract(m_all);
|
||||
}
|
||||
|
||||
default_implementation_t default_implementation() const
|
||||
{
|
||||
return default_implementation_extract<all_t>::extract(m_all);
|
||||
}
|
||||
|
||||
private: // data members
|
||||
all_t m_all;
|
||||
not_specified m_nil; // for filling in not_specified slots
|
||||
};
|
||||
}
|
||||
|
||||
}} // namespace boost::python::detail
|
||||
|
||||
#endif // DEF_HELPER_DWA200287_HPP
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user