mirror of
https://github.com/boostorg/python.git
synced 2026-02-02 09:02:15 +00:00
Compare commits
101 Commits
svn-branch
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca162434ca | ||
|
|
8ff5450ece | ||
|
|
5d30ddac22 | ||
|
|
80f697ef2a | ||
|
|
47c7748707 | ||
|
|
9f33aa2afc | ||
|
|
1dc6600b59 | ||
|
|
1ec58c1161 | ||
|
|
d023d577b2 | ||
|
|
21d65ca0bf | ||
|
|
bcf4401858 | ||
|
|
262396d48b | ||
|
|
0a9d5f680f | ||
|
|
64239f1c04 | ||
|
|
7590d546f1 | ||
|
|
021070f066 | ||
|
|
55a4318839 | ||
|
|
90647f30f8 | ||
|
|
8cc9080d36 | ||
|
|
6e5fc91885 | ||
|
|
71de2b5ec5 | ||
|
|
7703f91ee2 | ||
|
|
ecc8abcc50 | ||
|
|
14917c9791 | ||
|
|
25c56164b0 | ||
|
|
12988b879e | ||
|
|
684e391a9a | ||
|
|
7a16cd4c37 | ||
|
|
b3117c2b02 | ||
|
|
6a75fa83b5 | ||
|
|
88a8721b89 | ||
|
|
1f12857551 | ||
|
|
71032f6c4c | ||
|
|
088b1cab83 | ||
|
|
f40a534bfb | ||
|
|
f278530239 | ||
|
|
0389aab0a3 | ||
|
|
51a66a3202 | ||
|
|
248985e51a | ||
|
|
996d83eae0 | ||
|
|
98a1329dd7 | ||
|
|
ed2ebc7d3d | ||
|
|
41634f9998 | ||
|
|
93501af046 | ||
|
|
078585db28 | ||
|
|
03e9e4c1d9 | ||
|
|
4a1d077238 | ||
|
|
f7a5e6deb8 | ||
|
|
dabb22bb6a | ||
|
|
3d03ca3d10 | ||
|
|
386992c3b8 | ||
|
|
a48f252cfa | ||
|
|
c3a311ab85 | ||
|
|
7926e1bc3c | ||
|
|
b796db648a | ||
|
|
0964ecac8c | ||
|
|
dd1ac7952b | ||
|
|
7d1cbcb0c1 | ||
|
|
98c9e67625 | ||
|
|
aeef66ce35 | ||
|
|
8cff66e8c6 | ||
|
|
10a04acf41 | ||
|
|
9923a4c4ff | ||
|
|
0dafa9e229 | ||
|
|
e83e8a8f1c | ||
|
|
72aa768235 | ||
|
|
65c74e3976 | ||
|
|
cdac34efea | ||
|
|
03fef3106d | ||
|
|
d598d0a4db | ||
|
|
ab22e1b3a9 | ||
|
|
26d520af3c | ||
|
|
fb333f3641 | ||
|
|
1cc65a47eb | ||
|
|
8d56c52991 | ||
|
|
4b88b9eed1 | ||
|
|
462b91fb08 | ||
|
|
b65f4ff963 | ||
|
|
8d27b48225 | ||
|
|
e2623c5e82 | ||
|
|
acdae42fc5 | ||
|
|
451aac806e | ||
|
|
586e6178b4 | ||
|
|
1201761ff3 | ||
|
|
bdf68f092e | ||
|
|
a179f87d54 | ||
|
|
b2944a12de | ||
|
|
bfcb36927c | ||
|
|
ccd21d5254 | ||
|
|
a7b8448107 | ||
|
|
e934be2d99 | ||
|
|
015b875a9e | ||
|
|
1247ff2543 | ||
|
|
dc831fb3f6 | ||
|
|
94c0e947f5 | ||
|
|
ed9bc835a2 | ||
|
|
2eb2e52a79 | ||
|
|
14f6f88526 | ||
|
|
1f78c74085 | ||
|
|
c494649dde | ||
|
|
460f3aebe9 |
70
Jamfile
Normal file
70
Jamfile
Normal file
@@ -0,0 +1,70 @@
|
||||
subproject libs/python ;
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
PYTHON_PROPERTIES
|
||||
+= <metrowerks><*><cxxflags>"-inline deferred"
|
||||
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
|
||||
<define>BOOST_PYTHON_DYNAMIC_LIB
|
||||
<define>BOOST_PYTHON_V2
|
||||
;
|
||||
|
||||
{
|
||||
dll bpl
|
||||
:
|
||||
src/converter/from_python.cpp
|
||||
src/converter/registry.cpp
|
||||
src/converter/type_id.cpp
|
||||
src/object/class.cpp
|
||||
src/object/function.cpp
|
||||
src/object/inheritance.cpp
|
||||
src/object/life_support.cpp
|
||||
src/errors.cpp
|
||||
src/module.cpp
|
||||
src/objects.cpp
|
||||
src/converter/builtin_converters.cpp
|
||||
:
|
||||
$(PYTHON_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
;
|
||||
|
||||
# -------- general test -------
|
||||
extension m1 : test/m1.cpp <lib>bpl
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
extension m2 : test/m2.cpp <lib>bpl
|
||||
:
|
||||
: debug-python ;
|
||||
|
||||
boost-python-runtest try : test/newtest.py <lib>m1 <lib>m2 : : debug-python ;
|
||||
|
||||
# ----------- builtin converters -----------
|
||||
|
||||
extension builtin_converters_ext : test/test_builtin_converters.cpp <lib>bpl
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
boost-python-runtest test_builtin_converters : test/test_builtin_converters.py
|
||||
<lib>builtin_converters_ext
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
# ----------- pointer adoption -----------
|
||||
|
||||
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <lib>bpl
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
|
||||
<lib>test_pointer_adoption_ext
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
}
|
||||
@@ -61,8 +61,10 @@ subproject libs/python/build ;
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_DYNAMIC_LIB ;
|
||||
|
||||
#######################
|
||||
local rule bpl-test ( test-name : sources + )
|
||||
rule bpl-test ( test-name : sources + )
|
||||
{
|
||||
boost-python-test $(test-name) : $(sources) <lib>libboost_python ;
|
||||
}
|
||||
@@ -75,21 +77,27 @@ local rule bpl-test ( test-name : sources + )
|
||||
|
||||
# Base names of the source files for libboost_python
|
||||
local CPP_SOURCES =
|
||||
types classes conversions extension_class functions
|
||||
init_function module_builder objects cross_module ;
|
||||
types classes conversions extension_class functions
|
||||
init_function module_builder objects cross_module errors
|
||||
;
|
||||
|
||||
lib libboost_python : ../src/$(CPP_SOURCES).cpp
|
||||
lib libboost_python_static : ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<define>BOOST_PYTHON_STATIC_LIB=1
|
||||
$(PYTHON_PROPERTIES) ;
|
||||
|
||||
dll libboost_python$(SUFDLL[1]) : ../src/$(CPP_SOURCES).cpp
|
||||
dll libboost_python
|
||||
# $(SUFDLL[1])
|
||||
: ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<define>BOOST_RE_BUILD_DLL=1
|
||||
$(PYTHON_PROPERTIES) ;
|
||||
<runtime-link>dynamic
|
||||
<define>BOOST_PYTHON_HAS_DLL_RUNTIME=1
|
||||
$(PYTHON_PROPERTIES)
|
||||
;
|
||||
|
||||
############# comprehensive module and test ###########
|
||||
bpl-test boost_python_test
|
||||
@@ -100,7 +108,7 @@ boost-python-runtest comprehensive
|
||||
|
||||
############# simple tests from ../example ############
|
||||
|
||||
local rule boost-python-example-runtest ( name )
|
||||
rule boost-python-example-runtest ( name )
|
||||
{
|
||||
bpl-test $(name)
|
||||
: ../example/$(name).cpp ;
|
||||
@@ -128,7 +136,7 @@ bpl-test noncopyable_import : ../example/noncopyable_import.cpp ;
|
||||
############## cross-module tests from ../example ##########
|
||||
|
||||
# A simple rule to build a test which depends on multiple modules in the PYTHONPATH
|
||||
local rule boost-python-multi-example-runtest ( test-name : modules + )
|
||||
rule boost-python-multi-example-runtest ( test-name : modules + )
|
||||
{
|
||||
boost-python-runtest $(test-name)
|
||||
: ../example/tst_$(test-name).py <lib>$(modules) <lib>libboost_python
|
||||
|
||||
@@ -7,6 +7,7 @@ LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
errors.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
|
||||
@@ -8,6 +8,7 @@ bpl_exa = "/libs/python/example"
|
||||
files = (
|
||||
bpl_src + "/classes.cpp",
|
||||
bpl_src + "/conversions.cpp",
|
||||
bpl_src + "/errors.cpp",
|
||||
bpl_src + "/extension_class.cpp",
|
||||
bpl_src + "/functions.cpp",
|
||||
bpl_src + "/init_function.cpp",
|
||||
|
||||
@@ -11,6 +11,7 @@ LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
errors.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.1/include/python2.1
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
|
||||
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
|
||||
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
|
||||
|
||||
STDOPTS=
|
||||
@@ -35,7 +35,7 @@ MAKEDEP=-M
|
||||
LD=CC -LANG:std -n32 -mips4
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE=PYTHONPATH=. /usr/bin/python
|
||||
PYINC=-I/usr/include/python1.5
|
||||
#PYEXE=PYTHONPATH=. /usr/bin/python
|
||||
#PYINC=-I/usr/include/python1.5
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.1/include/python2.1
|
||||
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
|
||||
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
|
||||
|
||||
STDOPTS=-fPIC -ftemplate-depth-21
|
||||
WARNOPTS=
|
||||
@@ -36,7 +36,7 @@ MAKEDEP=-M
|
||||
LD=$(CPP)
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
|
||||
@@ -52,7 +52,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \
|
||||
LD=g++
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.1/include/python2.1
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
|
||||
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
|
||||
#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport
|
||||
#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport
|
||||
#STLPORTOPTS= \
|
||||
@@ -46,7 +46,7 @@ LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*'
|
||||
|
||||
#HIDDEN=-hidden
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
|
||||
@@ -14,14 +14,14 @@ ROOT=R:
|
||||
BOOST_WIN="$(ROOT)\boost"
|
||||
BOOST_UNIX=$(HOME)/boost
|
||||
|
||||
PYEXE="C:\Program files\Python\python.exe"
|
||||
PYINC=/I"C:\Program files\Python\include"
|
||||
PYLIB="C:\Program files\Python\libs\python15.lib"
|
||||
#PYEXE="C:\Python21\python.exe"
|
||||
#PYINC=/I"C:\Python21\include"
|
||||
#PYLIB="C:\Python21\libs\python21.lib"
|
||||
#PYEXE="C:\Program files\Python\python.exe"
|
||||
#PYINC=/I"C:\Program files\Python\include"
|
||||
#PYLIB="C:\Program files\Python\libs\python15.lib"
|
||||
PYEXE="C:\Python21\python.exe"
|
||||
PYINC=/I"C:\Python21\include"
|
||||
PYLIB="C:\Python21\libs\python21.lib"
|
||||
|
||||
STDOPTS=/nologo /MD /GR /GX /Zm200
|
||||
STDOPTS=/nologo /MD /GR /GX /Zm300 /DBOOST_PYTHON_STATIC_LIB
|
||||
WARNOPTS=
|
||||
OPTOPTS=
|
||||
|
||||
@@ -32,7 +32,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \
|
||||
LD=link.exe
|
||||
LDOPTS=/nologo /dll /incremental:no
|
||||
|
||||
OBJ=classes.obj conversions.obj extension_class.obj functions.obj \
|
||||
OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \
|
||||
init_function.obj module_builder.obj \
|
||||
objects.obj types.obj cross_module.obj
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve)
|
||||
|
||||
ROOT=R:
|
||||
BOOST_WIN="$(ROOT)\boostdev"
|
||||
BOOST_WIN="$(ROOT)\boost"
|
||||
BOOST_UNIX=$(HOME)/boost
|
||||
|
||||
#PYEXE="C:\Program files\Python\python.exe"
|
||||
@@ -20,7 +20,7 @@ PYEXE="C:\Python21\python.exe"
|
||||
PYINC=-I"C:\Python21\include"
|
||||
PYLIB="C:\Python21\libs\python21.lib"
|
||||
|
||||
STDOPTS=-gccinc -prefix UseDLLPrefix.h
|
||||
STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB
|
||||
WARNOPTS=-warn on,nounusedexpr,nounused
|
||||
OPTOPTS=-O
|
||||
|
||||
@@ -31,7 +31,7 @@ CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \
|
||||
LD=mwld
|
||||
LDOPTS=-export dllexport -shared
|
||||
|
||||
OBJ=classes.obj conversions.obj extension_class.obj functions.obj \
|
||||
OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \
|
||||
init_function.obj module_builder.obj \
|
||||
objects.obj types.obj cross_module.obj
|
||||
|
||||
|
||||
326
doc/new-conversions.html
Normal file
326
doc/new-conversions.html
Normal file
@@ -0,0 +1,326 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>A New Type Conversion Mechanism for Boost.Python</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<p><img border="0" src="../../../c++boost.gif" width="277" height="86"
|
||||
alt="boost logo"></p>
|
||||
|
||||
<h1>A New Type Conversion Mechanism for Boost.Python</h1>
|
||||
|
||||
<p>By <a href="../../../people/dave_abrahams.htm">David Abrahams</a>.
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
This document describes a redesign of the mechanism for automatically
|
||||
converting objects between C++ and Python. The current implementation
|
||||
uses two functions for any type <tt>T</tt>:
|
||||
|
||||
<blockquote><pre>
|
||||
U from_python(PyObject*, type<T>);
|
||||
void to_python(V);
|
||||
</pre></blockquote>
|
||||
|
||||
where U is convertible to T and T is convertible to V. These functions
|
||||
are at the heart of C++/Python interoperability in Boost.Python, so
|
||||
why would we want to change them? There are many reasons:
|
||||
|
||||
<h3>Bugs</h3>
|
||||
<p>Firstly, the current mechanism relies on a common C++ compiler
|
||||
bug. This is not just embarrassing: as compilers get to be more
|
||||
conformant, the library stops working. The issue, in detail, is the
|
||||
use of inline friend functions in templates to generate
|
||||
conversions. It is a very powerful, and legal technique as long as
|
||||
it's used correctly:
|
||||
|
||||
<blockquote><pre>
|
||||
template <class Derived>
|
||||
struct add_some_functions
|
||||
{
|
||||
friend <i>return-type</i> some_function1(..., Derived <i>cv-*-&-opt</i>, ...);
|
||||
friend <i>return-type</i> some_function2(..., Derived <i>cv-*-&-opt</i>, ...);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct some_template : add_some_functions<some_template<T> >
|
||||
{
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
The <tt>add_some_functions</tt> template generates free functions
|
||||
which operate on <tt>Derived</tt>, or on related types. Strictly
|
||||
speaking the related types are not just cv-qualified <tt>Derived</tt>
|
||||
values, pointers and/or references. Section 3.4.2 in the standard
|
||||
describes exactly which types you must use as parameters to these
|
||||
functions if you want the functions to be found
|
||||
(there is also a less-technical description in section 11.5.1 of
|
||||
C++PL3 <a href="#ref_1">[1]</a>). Suffice it to say that
|
||||
with the current design, the <tt>from_python</tt> and
|
||||
<tt>to_python</tt> functions are not supposed to be callable under any
|
||||
conditions!
|
||||
|
||||
<h3>Compilation and Linking Time</h3>
|
||||
|
||||
The conversion functions generated for each wrapped class using the
|
||||
above technique are not function templates, but regular functions. The
|
||||
upshot is that they must <i>all</i> be generated regardless of whether
|
||||
they are actually used. Generating all of those functions can slow
|
||||
down module compilation, and resolving the references can slow down
|
||||
linking.
|
||||
|
||||
<h3>Efficiency</h3>
|
||||
|
||||
The conversion functions are primarily used in (member) function
|
||||
wrappers to convert the arguments and return values. Being functions,
|
||||
converters have no interface which allows us to ask "will the
|
||||
conversion succeed?" without calling the function. Since the
|
||||
return value of the function must be the object to be passed as an
|
||||
argument, Boost.Python currently uses C++ exception-handling to detect
|
||||
an unsuccessful conversion. It's not a particularly good use of
|
||||
exception-handling, since the failure is not handled very far from
|
||||
where it occurred. More importantly, it means that C++ exceptions are
|
||||
thrown during overload resolution as we seek an overload that matches
|
||||
the arguments passed. Depending on the implementation, this approach
|
||||
can result in significant slowdowns.
|
||||
|
||||
<p>It is also unclear that the current library generates a minimal
|
||||
amount of code for any type conversion. Many of the conversion
|
||||
functions are nontrivial, and partly because of compiler limitations,
|
||||
they are declared <tt>inline</tt>. Also, we could have done a better
|
||||
job separating the type-specific conversion code from the code which
|
||||
is type-independent.
|
||||
|
||||
<h3>Cross-module Support</h3>
|
||||
|
||||
The current strategy requires every module to contain the definition
|
||||
of conversions it uses. In general, a new module can never supply
|
||||
conversion code which is used by another module. Ralf Grosse-Kunstleve
|
||||
designed a clever system which imports conversions directly from one
|
||||
library into another using some explicit declarations, but it has some
|
||||
disadvantages also:
|
||||
|
||||
<ol>
|
||||
<li>The system Ullrich Koethe designed for implicit conversion between
|
||||
wrapped classes related through inheritance does not currently work if
|
||||
the classes are defined in separate modules.
|
||||
|
||||
<li>The writer of the importing module is required to know the name of
|
||||
the module supplying the imported conversions.
|
||||
|
||||
<li>There can be only one way to extract any given C++ type from a
|
||||
Python object in a given module.
|
||||
</ol>
|
||||
|
||||
The first item might be addressed by moving Boost.Python into a shared
|
||||
library, but the other two cannot. Ralf turned the limitation in item
|
||||
two into a feature: the required module is loaded implicitly when a
|
||||
conversion it defines is invoked. We will probably want to provide
|
||||
that functionality anyway, but it's not clear that we should require
|
||||
the declaration of all such conversions. The final item is a more
|
||||
serious limitation. If, for example, new numeric types are defined in
|
||||
separate modules, and these types can all be converted to
|
||||
<tt>double</tt>s, we have to choose just one conversion method.
|
||||
|
||||
<h3>Ease-of-use</h3>
|
||||
|
||||
One persistent source of confusion for users of Boost.Python has been
|
||||
the fact that conversions for a class are not be visible at
|
||||
compile-time until the declaration of that class has been seen. When
|
||||
the user tries to expose a (member) function operating on or returning
|
||||
an instance of the class in question, compilation fails...even though
|
||||
the user goes on to expose the class in the same translation unit!
|
||||
|
||||
<p>
|
||||
The new system lifts all compile-time checks for the existence of
|
||||
particular type conversions and replaces them with runtime checks, in
|
||||
true Pythonic style. While this might seem cavalier, the compile-time
|
||||
checks are actually not much use in the current system if many classes
|
||||
are wrapped in separate modules, since the checks are based only on
|
||||
the user's declaration that the conversions exist.
|
||||
|
||||
<h2>The New Design</h2>
|
||||
|
||||
<h3>Motivation</h3>
|
||||
|
||||
The new design was heavily influenced by a desire to generate as
|
||||
little code as possible in extension modules. Some of Boost.Python's
|
||||
clients are enormous projects where link time is proportional to the
|
||||
amount of object code, and there are many Python extension modules. As
|
||||
such, we try to keep type-specific conversion code out of modules
|
||||
other than the one the converters are defined in, and rely as much as
|
||||
possible on centralized control through a shared library.
|
||||
|
||||
<h3>The Basics</h3>
|
||||
|
||||
The library contains a <tt>registry</tt> which maps runtime type
|
||||
identifiers (actually an extension of <tt>std::type_info</tt> which
|
||||
preserves references and constness) to entries containing type
|
||||
converters. An <tt>entry</tt> can contain only one converter from C++ to Python
|
||||
(<tt>wrapper</tt>), but many converters from Python to C++
|
||||
(<tt>unwrapper</tt>s). <font color="#ff0000">What should happen if
|
||||
multiple modules try to register wrappers for the same type?</font>. Wrappers
|
||||
and unwrappers are known as <tt>body</tt> objects, and are accessed
|
||||
by the user and the library (in its function-wrapping code) through
|
||||
corresponding <tt>handle</tt> (<tt>wrap<T></tt> and
|
||||
<tt>unwrap<T></tt>) objects. The <tt>handle</tt> objects are
|
||||
extremely lightweight, and delegate <i>all</i> of their operations to
|
||||
the corresponding <tt>body</tt>.
|
||||
|
||||
<p>
|
||||
When a <tt>handle</tt> object is constructed, it accesses the
|
||||
registry to find a corresponding <tt>body</tt> that can convert the
|
||||
handle's constructor argument. Actually the registry record for any
|
||||
type
|
||||
<tt>T</tt>used in a module is looked up only once and stored in a
|
||||
static <tt>registration<T></tt> object for efficiency. For
|
||||
example, if the handle is an <tt>unwrap<Foo&></tt> object,
|
||||
the <tt>entry</tt> for <tt>Foo&</tt> is looked up in the
|
||||
<tt>registry</tt>, and each <tt>unwrapper</tt> it contains is queried
|
||||
to determine if it can convert the
|
||||
<tt>PyObject*</tt> with which the <tt>unwrap</tt> was constructed. If
|
||||
a body object which can perform the conversion is found, a pointer to
|
||||
it is stored in the handle. A body object may at any point store
|
||||
additional data in the handle to speed up the conversion process.
|
||||
|
||||
<p>
|
||||
Now that the handle has been constructed, the user can ask it whether
|
||||
the conversion can be performed. All handles can be tested as though
|
||||
they were convertible to <tt>bool</tt>; a <tt>true</tt> value
|
||||
indicates success. If the user forges ahead and tries to do the
|
||||
conversion without checking when no conversion is possible, an
|
||||
exception will be thrown as usual. The conversion itself is performed
|
||||
by the body object.
|
||||
|
||||
<h3>Handling complex conversions</h3>
|
||||
|
||||
<p>Some conversions may require a dynamic allocation. For example,
|
||||
when a Python tuple is converted to a <tt>std::vector<double>
|
||||
const&</tt>, we need some storage into which to construct the
|
||||
vector so that a reference to it can be formed. Furthermore, multiple
|
||||
conversions of the same type may need to be "active"
|
||||
simultaneously, so we can't keep a single copy of the storage
|
||||
anywhere. We could keep the storage in the <tt>body</tt> object, and
|
||||
have the body clone itself in case the storage is used, but in that
|
||||
case the storage in the body which lives in the registry is never
|
||||
used. If the storage was actually an object of the target type (the
|
||||
safest way in C++), we'd have to find a way to construct one for the
|
||||
body in the registry, since it may not have a default constructor.
|
||||
|
||||
<p>
|
||||
The most obvious way out of this quagmire is to allocate the object using a
|
||||
<i>new-expression</i>, and store a pointer to it in the handle. Since
|
||||
the <tt>body</tt> object knows everything about the data it needs to
|
||||
allocate (if any), it is also given responsibility for destroying that
|
||||
data. When the <tt>handle</tt> is destroyed it asks the <tt>body</tt>
|
||||
object to tear down any data it may have stored there. In many ways,
|
||||
you can think of the <tt>body</tt> as a "dynamically-determined
|
||||
vtable" for the handle.
|
||||
|
||||
<h3>Eliminating Redundancy</h3>
|
||||
|
||||
If you look at the current Boost.Python code, you'll see that there
|
||||
are an enormous number of conversion functions generated for each
|
||||
wrapped class. For a given class <tt>T</tt>, functions are generated
|
||||
to extract the following types <tt>from_python</tt>:
|
||||
|
||||
<blockquote><pre>
|
||||
T*
|
||||
T const*
|
||||
T const* const&
|
||||
T* const&
|
||||
T&
|
||||
T const&
|
||||
T
|
||||
std::auto_ptr<T>&
|
||||
std::auto_ptr<T>
|
||||
std::auto_ptr<T> const&
|
||||
boost::shared_ptr<T>&
|
||||
boost::shared_ptr<T>
|
||||
boost::shared_ptr<T> const&
|
||||
</pre></blockquote>
|
||||
|
||||
Most of these are implemented in terms of just a few conversions, and
|
||||
<t>if you're lucky</t>, they will be inlined and cause no extra
|
||||
overhead. In the new system, however, a significant amount of data
|
||||
will be associated with each type that needs to be converted. We
|
||||
certainly don't want to register a separate unwrapper object for all
|
||||
of the above types.
|
||||
|
||||
<p>Fortunately, much of the redundancy can be eliminated. For example,
|
||||
if we generate an unwrapper for <tt>T&</tt>, we don't need an
|
||||
unwrapper for <tt>T const&</tt> or <tt>T</tt>. Accordingly, the user's
|
||||
request to wrap/unwrap a given type is translated at compile-time into
|
||||
a request which helps to eliminate redundancy. The rules used to
|
||||
<tt>unwrap</tt> a type are:
|
||||
|
||||
<ol>
|
||||
<li> Treat built-in types specially: when unwrapping a value or
|
||||
constant reference to one of these, use a value for the target
|
||||
type. It will bind to a const reference if neccessary, and more
|
||||
importantly, avoids having to dynamically allocate room for
|
||||
an lvalue of types which can be cheaply copied.
|
||||
<li>
|
||||
Reduce everything else to a reference to an un-cv-qualified type
|
||||
where possible. Since cv-qualification is lost on Python
|
||||
anyway, there's no point in trying to convert to a
|
||||
<tt>const&</tt>. <font color="#ff0000">What about conversions
|
||||
to values like the tuple->vector example above? It seems to me
|
||||
that we don't want to make a <tt>vector<double>&</tt>
|
||||
(non-const) converter available for that case. We may need to
|
||||
rethink this slightly.</font>
|
||||
</ol>
|
||||
|
||||
<p>To handle the problem described above in item 2, we modify the
|
||||
procedure slightly. To unwrap any non-scalar <tt>T</tt>, we seek an
|
||||
unwrapper for <tt>add_reference<T>::type</tt>. Unwrappers for
|
||||
<tt>T const&</tt> always return <tt>T&</tt>, and are
|
||||
registered under both <tt>T &</tt> and
|
||||
<tt>T const&</tt>.
|
||||
|
||||
<p>For compilers not supporting partial specialization, unwrappers for
|
||||
<tt>T const&</tt> must return <tt>T const&</tt>
|
||||
(since constness can't be stripped), but a separate unwrapper object
|
||||
need to be registered for <tt>T &</tt> and
|
||||
<tt>T const&</tt> anyway, for the same reasons.
|
||||
|
||||
<font color="#ff0000">We may want to make it possible to compile as
|
||||
though partial specialization were unavailable even on compilers where
|
||||
it is available, in case modules could be compiled by different
|
||||
compilers with compatible ABIs (e.g. Intel C++ and MSVC6).</font>
|
||||
|
||||
<h3>Efficient Argument Conversion</h3>
|
||||
|
||||
Since type conversions are primarily used in function wrappers, an
|
||||
optimization is provided for the case where a group of conversions are
|
||||
used together. Each <tt>handle</tt> class has a corresponding
|
||||
"<tt>_more</tt>" class which does the same job, but has a
|
||||
trivial destructor. Instead of asking each "<tt>_more</tt>"
|
||||
handle to destroy its own body, it is linked into an endogenous list
|
||||
managed by the first (ordinary) handle. The <tt>wrap</tt> and
|
||||
<tt>unwrap</tt> destructors are responsible for traversing that list
|
||||
and asking each <tt>body</tt> class to tear down its
|
||||
<tt>handle</tt>. This mechanism is also used to determine if all of
|
||||
the argument/return-value conversions can succeed with a single
|
||||
function call in the function wrapping code. <font color="#ff0000">We
|
||||
might need to handle return values in a separate step for Python
|
||||
callbacks, since the availablility of a conversion won't be known
|
||||
until the result object is retrieved.</font>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<h2>References</h2>
|
||||
|
||||
<p><a name="ref_1">[1]</a>B. Stroustrup, The C++ Programming Language
|
||||
Special Edition Addison-Wesley, ISBN 0-201-70073-5.
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->19 December 2001<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
|
||||
<p>© Copyright David Abrahams, 2001</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
111
doc/new-conversions.txt
Normal file
111
doc/new-conversions.txt
Normal file
@@ -0,0 +1,111 @@
|
||||
This hierarchy contains converter handle classes.
|
||||
|
||||
|
||||
+-------------+
|
||||
| noncopyable |
|
||||
+-------------+
|
||||
^
|
||||
| A common base class used so that
|
||||
+--------+--------+ conversions can be linked into a
|
||||
| conversion_base | chain for efficient argument
|
||||
+-----------------+ conversion
|
||||
^
|
||||
|
|
||||
+---------+-----------+
|
||||
| |
|
||||
+-----------+----+ +------+-------+ only used for
|
||||
| unwrap_more<T> | | wrap_more<T> | chaining, and don't manage any
|
||||
+----------------+ +--------------+ resources.
|
||||
^ ^
|
||||
| |
|
||||
+-----+-----+ +-------+-+ These converters are what users
|
||||
| unwrap<T> | | wrap<T> | actually touch, but they do so
|
||||
+-----------+ +---------+ through a type generator which
|
||||
minimizes the number of converters
|
||||
that must be generated, so they
|
||||
|
||||
|
||||
Each unwrap<T>, unwrap_more<T>, wrap<T>, wrap_more<T> converter holds
|
||||
a reference to an appropriate converter object
|
||||
|
||||
This hierarchy contains converter body classes
|
||||
|
||||
Exposes use/release which
|
||||
are needed in case the converter
|
||||
+-----------+ in the registry needs to be
|
||||
| converter | cloned. That occurs when a
|
||||
+-----------+ unwrap target type is not
|
||||
^ contained within the Python object.
|
||||
|
|
||||
+------------------+-----+
|
||||
| |
|
||||
+--------+-------+ Exposes |
|
||||
| unwrapper_base | convertible() |
|
||||
+----------------+ |
|
||||
^ |
|
||||
| |
|
||||
+--------+----+ +-----+-----+
|
||||
| unwrapper<T>| | wrapper<T>|
|
||||
+-------------+ +-----------+
|
||||
Exposes T convert(PyObject*) Exposes PyObject* convert(T)
|
||||
|
||||
|
||||
unwrap:
|
||||
|
||||
constructed with a PyObject*, whose reference count is
|
||||
incremented.
|
||||
|
||||
find the registry entry for the target type
|
||||
|
||||
look in the collection of converters for one which claims to be
|
||||
able to convert the PyObject to the target type.
|
||||
|
||||
stick a pointer to the unwrapper in the unwrap object
|
||||
|
||||
when unwrap is queried for convertibility, it checks to see
|
||||
if it has a pointer to an unwrapper.
|
||||
|
||||
on conversion, the unwrapper is asked to allocate an
|
||||
implementation if the unwrap object isn't already holding
|
||||
one. The unwrap object "takes ownership" of the unwrapper's
|
||||
implementation. No memory allocation will actually take place
|
||||
unless this is a value conversion.
|
||||
|
||||
on destruction, the unwrapper is asked to free any implementation
|
||||
held by the unwrap object. No memory deallocation actually
|
||||
takes place unless this is a value conversion
|
||||
|
||||
on destruction, the reference count on the held PyObject is
|
||||
decremented.
|
||||
|
||||
We need to make sure that by default, you can't instantiate
|
||||
callback<> for reference and pointer return types: although the
|
||||
unwrappers may exist, they may convert by-value, which would cause
|
||||
the referent to be destroyed upon return.
|
||||
|
||||
wrap:
|
||||
|
||||
find the registry entry for the source type
|
||||
|
||||
see if there is a converter. If found, stick a pointer to it in
|
||||
the wrap object.
|
||||
|
||||
when queried for convertibility, it checks to see if it has a
|
||||
pointer to a converter.
|
||||
|
||||
on conversion, a reference to the target PyObject is held by the
|
||||
converter. Generally, the PyObject will have been created by the
|
||||
converter, but in certain cases it may be a pre-existing object,
|
||||
whose reference count will have been incremented.
|
||||
|
||||
when a wrap<T> x is used to return from a C++ function,
|
||||
x.release() is returned so that x no longer holds a reference to
|
||||
the PyObject when destroyed.
|
||||
|
||||
Otherwise, on destruction, any PyObject still held has its
|
||||
reference-count decremented.
|
||||
|
||||
|
||||
When a converter is created by the user, the appropriate element must
|
||||
be added to the registry; when it is destroyed, it must be removed
|
||||
from the registry.
|
||||
@@ -1,50 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
private:
|
||||
std::string country;
|
||||
public:
|
||||
world(const std::string& country) { this->country = country; }
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
};
|
||||
|
||||
// A function taking a world object as an argument.
|
||||
std::string invite(const world& w) {
|
||||
return w.greet() + " Please come soon!";
|
||||
}
|
||||
}
|
||||
|
||||
#include <py_cpp/class_wrapper.h>
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE_INIT(example2)
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
py::Module this_module("example2");
|
||||
|
||||
// Create the Python type object for our extension class.
|
||||
py::ClassWrapper<world> world_class(this_module, "world");
|
||||
|
||||
// Add the __init__ function.
|
||||
world_class.def(py::Constructor<std::string>());
|
||||
// Add a regular member function.
|
||||
world_class.def(&world::greet, "greet");
|
||||
|
||||
// Add invite() as a regular function to the module.
|
||||
this_module.def(invite, "invite");
|
||||
|
||||
// Even better, invite() can also be made a member of world_class!!!
|
||||
world_class.def(invite, "invite");
|
||||
}
|
||||
|
||||
// Win32 DLL boilerplate
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; }
|
||||
#endif // _WIN32
|
||||
@@ -1,101 +0,0 @@
|
||||
#include <py_cpp/class_wrapper.h>
|
||||
#include <py_cpp/objects.h>
|
||||
|
||||
#define rangei(n) for (int i = 0; i < n; i++)
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A wrapper is used to define additional constructors.
|
||||
//
|
||||
struct vector_double_wrapper: std::vector<double>
|
||||
{
|
||||
// Tell the compiler how to convert a base class object to
|
||||
// this wrapper object.
|
||||
vector_double_wrapper(PyObject*, const std::vector<double>& vd)
|
||||
: std::vector<double>(vd) {}
|
||||
|
||||
vector_double_wrapper(PyObject* self)
|
||||
: std::vector<double>() {}
|
||||
|
||||
vector_double_wrapper(PyObject* self, const int n)
|
||||
: std::vector<double>(n) {}
|
||||
|
||||
vector_double_wrapper(PyObject* self, py::Tuple tuple)
|
||||
: std::vector<double>(tuple.size())
|
||||
{
|
||||
std::vector<double>::iterator vd = begin();
|
||||
rangei(tuple.size())
|
||||
vd[i] = from_python(tuple[i].get(), py::Type<double>()); // GCC BUG
|
||||
}
|
||||
};
|
||||
|
||||
double getitem(const std::vector<double>& vd, const std::size_t key) {
|
||||
return vd[key];
|
||||
}
|
||||
|
||||
void setitem(std::vector<double>& vd, const std::size_t key,
|
||||
const double &d) {
|
||||
std::vector<double>::iterator vditer = vd.begin();
|
||||
vditer[key] = d;
|
||||
}
|
||||
|
||||
void delitem(std::vector<double>& vd, const std::size_t key) {
|
||||
std::vector<double>::iterator vditer = vd.begin();
|
||||
vd.erase(&vditer[key]);
|
||||
}
|
||||
|
||||
// Convert vector_double to a regular Python tuple.
|
||||
//
|
||||
py::Tuple as_tuple(const std::vector<double>& vd)
|
||||
{
|
||||
py::Tuple t(vd.size());
|
||||
rangei(vd.size()) t.set_item(i, py::Ptr(py::to_python(vd[i]))); // GCC BUG
|
||||
return t;
|
||||
}
|
||||
|
||||
// Function returning a vector_double object to Python.
|
||||
//
|
||||
std::vector<double> foo(const int n)
|
||||
{
|
||||
std::vector<double> vd(n);
|
||||
std::vector<double>::iterator vditer = vd.begin();
|
||||
rangei(n) vditer[i] = double(i);
|
||||
return vd;
|
||||
}
|
||||
|
||||
// Same as foo(), but avoid copying on return.
|
||||
//
|
||||
std::auto_ptr<std::vector<double> > bar(const int n)
|
||||
{
|
||||
std::auto_ptr<std::vector<double> > vdptr(new std::vector<double>(n));
|
||||
std::vector<double>::iterator vditer = vdptr->begin();
|
||||
rangei(n) vditer[i] = double(10 * i);
|
||||
return vdptr;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(example3)
|
||||
{
|
||||
py::Module this_module("example3");
|
||||
|
||||
py::ClassWrapper<std::vector<double>, vector_double_wrapper>
|
||||
vector_double(this_module, "vector_double");
|
||||
|
||||
vector_double.def(py::Constructor<>());
|
||||
vector_double.def(py::Constructor<const int>());
|
||||
vector_double.def(py::Constructor<py::Tuple>());
|
||||
vector_double.def(&std::vector<double>::size, "__len__");
|
||||
vector_double.def(getitem, "__getitem__");
|
||||
vector_double.def(setitem, "__setitem__");
|
||||
vector_double.def(delitem, "__delitem__");
|
||||
vector_double.def(as_tuple, "as_tuple");
|
||||
|
||||
this_module.def(foo, "foo");
|
||||
this_module.def(bar, "bar");
|
||||
}
|
||||
|
||||
// Win32 DLL boilerplate
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; }
|
||||
#endif // _WIN32
|
||||
@@ -91,7 +91,7 @@ BOOST_PYTHON_MODULE_INIT(simple_vector)
|
||||
vector_double(this_module, "vector_double");
|
||||
|
||||
vector_double.def(python::constructor<>());
|
||||
vector_double.def(python::constructor<const int>());
|
||||
vector_double.def(python::constructor<int>());
|
||||
vector_double.def(python::constructor<python::tuple>());
|
||||
vector_double.def(&std::vector<double>::size, "__len__");
|
||||
vector_double.def(getitem, "__getitem__");
|
||||
|
||||
210
include/boost/python/call.hpp
Normal file
210
include/boost/python/call.hpp
Normal file
@@ -0,0 +1,210 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
//
|
||||
// This work was funded in part by Lawrence Berkeley National Labs
|
||||
//
|
||||
// This file generated for 5-argument member functions and 6-argument free
|
||||
// functions by gen_call.py
|
||||
|
||||
#ifndef CALL_DWA20011214_HPP
|
||||
# define CALL_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/detail/returning.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class R>
|
||||
inline PyObject* call(R (*f)(), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CALL_DWA20011214_HPP
|
||||
|
||||
202
include/boost/python/class.hpp
Normal file
202
include/boost/python/class.hpp
Normal file
@@ -0,0 +1,202 @@
|
||||
// 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/reference.hpp>
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/detail/wrap_function.hpp>
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
# include <boost/python/object/class_converters.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
|
||||
namespace // put some convenience classes into the unnamed namespace for the user
|
||||
{
|
||||
// A type list for specifying bases
|
||||
template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) >
|
||||
struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type
|
||||
{};
|
||||
|
||||
// A type list for specifying arguments
|
||||
template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) >
|
||||
struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type
|
||||
{};
|
||||
}
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Forward declarations
|
||||
namespace objects
|
||||
{
|
||||
struct value_holder_generator;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// This is an mpl BinaryMetaFunction object with a runtime behavior,
|
||||
// which is to write the id of the type which is passed as its 2nd
|
||||
// compile-time argument into the iterator pointed to by its runtime
|
||||
// argument
|
||||
struct write_type_id
|
||||
{
|
||||
// The first argument is Ignored because mpl::for_each is still
|
||||
// currently an accumulate (reduce) implementation.
|
||||
template <class Ignored, class T> struct apply
|
||||
{
|
||||
// also an artifact of accumulate-based for_each
|
||||
typedef void type;
|
||||
|
||||
// Here's the runtime behavior
|
||||
static void execute(converter::undecorated_type_id_t** p)
|
||||
{
|
||||
*(*p)++ = converter::undecorated_type_id<T>();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// class_<T,Bases,HolderGenerator>
|
||||
//
|
||||
// This is the primary mechanism through which users will expose
|
||||
// C++ classes to Python. The three template arguments are:
|
||||
//
|
||||
// T - The class being exposed to Python
|
||||
//
|
||||
// Bases - An MPL sequence of base classes
|
||||
//
|
||||
// HolderGenerator -
|
||||
// An optional type generator for the "holder" which
|
||||
// maintains the C++ object inside the Python instance. The
|
||||
// default just holds the object "by-value", but other
|
||||
// holders can be substituted which will hold the C++ object
|
||||
// by smart pointer, for example.
|
||||
//
|
||||
template <
|
||||
class T // class being wrapped
|
||||
, class Bases
|
||||
, class HolderGenerator
|
||||
>
|
||||
class class_ : private objects::class_base
|
||||
{
|
||||
typedef class_<T,Bases,HolderGenerator> self;
|
||||
public:
|
||||
|
||||
// Automatically derive the class name - only works on some
|
||||
// compilers because type_info::name is sometimes mangled (gcc)
|
||||
class_();
|
||||
|
||||
// Construct with the class name. [ Would have used a default
|
||||
// argument but gcc-2.95.2 choked on typeid(T).name() as a default
|
||||
// parameter value]
|
||||
class_(char const* name);
|
||||
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Use function::add_to_namespace to achieve overloading if
|
||||
// appropriate.
|
||||
objects::function::add_to_namespace(
|
||||
this->object(), name, ref(detail::wrap_function(f)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Fn, class CallPolicy>
|
||||
self& def(char const* name, Fn fn, CallPolicy policy)
|
||||
{
|
||||
this->def(name, boost::python::make_function(fn, policy));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Define the constructor with the given Args, which should be an
|
||||
// MPL sequence of types.
|
||||
template <class Args>
|
||||
self& def_init(Args const& = Args())
|
||||
{
|
||||
def("__init__", make_constructor<T,Args,HolderGenerator>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Define the default constructor.
|
||||
self& def_init()
|
||||
{
|
||||
this->def_init(mpl::type_list<>::type());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// return the underlying object
|
||||
ref object() const;
|
||||
|
||||
private: // types
|
||||
typedef objects::class_id class_id;
|
||||
|
||||
// A helper class which will contain an array of id objects to be
|
||||
// passed to the base class constructor
|
||||
struct id_vector
|
||||
{
|
||||
typedef objects::class_id class_id;
|
||||
id_vector()
|
||||
{
|
||||
// Stick the derived class id into the first element of the array
|
||||
ids[0] = converter::undecorated_type_id<T>();
|
||||
|
||||
// Write the rest of the elements into succeeding positions.
|
||||
class_id* p = ids + 1;
|
||||
mpl::for_each<Bases, void, detail::write_type_id>::execute(&p);
|
||||
}
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, size = mpl::size<Bases>::value + 1);
|
||||
class_id ids[size];
|
||||
};
|
||||
|
||||
private: // helper functions
|
||||
void initialize_converters();
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
inline class_<T, Bases, HolderGenerator>::class_()
|
||||
: class_base(typeid(T).name(), id_vector::size, id_vector().ids)
|
||||
{
|
||||
// Bring the class converters into existence. This static object
|
||||
// will survive until the shared library this module lives in is
|
||||
// unloaded (that doesn't happen until Python terminates).
|
||||
static objects::class_converters<T,Bases> converters(object());
|
||||
}
|
||||
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
inline class_<T, Bases, HolderGenerator>::class_(char const* name)
|
||||
: class_base(name, id_vector::size, id_vector().ids)
|
||||
{
|
||||
// Bring the class converters into existence. This static object
|
||||
// will survive until the shared library this module lives in is
|
||||
// unloaded (that doesn't happen until Python terminates).
|
||||
static objects::class_converters<T,Bases> converters(object());
|
||||
}
|
||||
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
inline ref class_<T, Bases, HolderGenerator>::object() const
|
||||
{
|
||||
typedef objects::class_base base;
|
||||
|
||||
return this->base::object();
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_DWA200216_HPP
|
||||
30
include/boost/python/class_fwd.hpp
Normal file
30
include/boost/python/class_fwd.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct empty_list;
|
||||
}
|
||||
|
||||
namespace objects
|
||||
{
|
||||
struct value_holder_generator;
|
||||
}
|
||||
|
||||
template <
|
||||
class T // class being wrapped
|
||||
, class Bases = detail::empty_list
|
||||
, class HolderGenerator = objects::value_holder_generator
|
||||
>
|
||||
class class_;
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_FWD_DWA200222_HPP
|
||||
@@ -20,7 +20,7 @@
|
||||
namespace boost { namespace python {
|
||||
|
||||
// A simple type which acts something like a built-in Python class obj.
|
||||
class instance
|
||||
class BOOST_PYTHON_DECL instance
|
||||
: public boost::python::detail::python_object
|
||||
{
|
||||
public:
|
||||
@@ -105,7 +105,7 @@ class instance
|
||||
template <class T> class meta_class;
|
||||
|
||||
namespace detail {
|
||||
class class_base : public type_object_base
|
||||
class BOOST_PYTHON_DECL class_base : public type_object_base
|
||||
{
|
||||
public:
|
||||
class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space);
|
||||
@@ -128,6 +128,10 @@ namespace detail {
|
||||
|
||||
private: // boost::python::type_object_base required interface implementation
|
||||
void instance_dealloc(PyObject*) const; // subclasses should not override this
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
class_base(const class_base&);
|
||||
void operator=(const class_base&);
|
||||
|
||||
private:
|
||||
string m_name;
|
||||
@@ -141,11 +145,12 @@ namespace detail {
|
||||
// A type which acts a lot like a built-in Python class. T is the obj type,
|
||||
// so class_t<instance> is a very simple "class-alike".
|
||||
template <class T>
|
||||
class class_t
|
||||
class BOOST_PYTHON_DECL_TEMPLATE class_t
|
||||
: public boost::python::detail::class_base
|
||||
{
|
||||
public:
|
||||
class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space);
|
||||
~class_t();
|
||||
|
||||
// Standard Python functions.
|
||||
PyObject* call(PyObject* args, PyObject* keywords);
|
||||
@@ -218,15 +223,11 @@ class class_t
|
||||
|
||||
private: // Implementation of boost::python::detail::class_base required interface
|
||||
void delete_instance(PyObject*) const;
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
class_t(const class_t<T>&);
|
||||
void operator=(const class_t&);
|
||||
};
|
||||
|
||||
// The type of a class_t<T> object.
|
||||
template <class T>
|
||||
class meta_class
|
||||
class BOOST_PYTHON_DECL_TEMPLATE meta_class
|
||||
: public boost::python::detail::reprable<
|
||||
boost::python::detail::callable<
|
||||
boost::python::detail::getattrable<
|
||||
@@ -264,6 +265,11 @@ class_t<T>::class_t(meta_class<T>* meta_class_obj, string name, tuple bases, con
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class_t<T>::~class_t()
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void class_t<T>::delete_instance(PyObject* obj) const
|
||||
{
|
||||
@@ -344,7 +350,7 @@ int class_t<T>::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adjust_slice_indices(PyObject* obj, int& start, int& finish);
|
||||
void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish);
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_sequence_slice(PyObject* obj, int start, int finish) const
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <string>
|
||||
|
||||
@@ -122,61 +122,68 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
// Converters
|
||||
//
|
||||
PyObject* to_python(long);
|
||||
long from_python(PyObject* p, boost::python::type<long>);
|
||||
BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type<long>);
|
||||
long from_python(PyObject* p, boost::python::type<const long&>);
|
||||
|
||||
PyObject* to_python(unsigned long);
|
||||
unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned long);
|
||||
BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
|
||||
unsigned long from_python(PyObject* p, boost::python::type<const unsigned long&>);
|
||||
|
||||
PyObject* to_python(int);
|
||||
int from_python(PyObject*, boost::python::type<int>);
|
||||
BOOST_PYTHON_DECL int from_python(PyObject*, boost::python::type<int>);
|
||||
int from_python(PyObject*, boost::python::type<const int&>);
|
||||
|
||||
PyObject* to_python(unsigned int);
|
||||
unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned int);
|
||||
BOOST_PYTHON_DECL unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
|
||||
unsigned int from_python(PyObject*, boost::python::type<const unsigned int&>);
|
||||
|
||||
PyObject* to_python(short);
|
||||
short from_python(PyObject*, boost::python::type<short>);
|
||||
BOOST_PYTHON_DECL short from_python(PyObject*, boost::python::type<short>);
|
||||
short from_python(PyObject*, boost::python::type<const short&>);
|
||||
|
||||
PyObject* to_python(unsigned short);
|
||||
unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned short);
|
||||
BOOST_PYTHON_DECL unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
|
||||
unsigned short from_python(PyObject*, boost::python::type<const unsigned short&>);
|
||||
|
||||
PyObject* to_python(char);
|
||||
char from_python(PyObject*, boost::python::type<char>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(char);
|
||||
BOOST_PYTHON_DECL char from_python(PyObject*, boost::python::type<char>);
|
||||
char from_python(PyObject*, boost::python::type<const char&>);
|
||||
|
||||
PyObject* to_python(signed char);
|
||||
signed char from_python(PyObject*, boost::python::type<signed char>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(signed char);
|
||||
BOOST_PYTHON_DECL signed char from_python(PyObject*, boost::python::type<signed char>);
|
||||
signed char from_python(PyObject*, boost::python::type<const signed char&>);
|
||||
|
||||
PyObject* to_python(unsigned char);
|
||||
unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned char);
|
||||
BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
|
||||
unsigned char from_python(PyObject*, boost::python::type<const unsigned char&>);
|
||||
|
||||
# ifndef BOOST_MSVC6_OR_EARLIER
|
||||
PyObject* to_python(float);
|
||||
float from_python(PyObject*, boost::python::type<float>);
|
||||
float from_python(PyObject*, boost::python::type<const float&>);
|
||||
|
||||
PyObject* to_python(double);
|
||||
double from_python(PyObject*, boost::python::type<double>);
|
||||
# else
|
||||
BOOST_PYTHON_DECL PyObject* to_python(float);
|
||||
BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type<float>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(double);
|
||||
BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type<double>);
|
||||
# endif
|
||||
float from_python(PyObject*, boost::python::type<const float&>);
|
||||
|
||||
double from_python(PyObject*, boost::python::type<const double&>);
|
||||
|
||||
PyObject* to_python(bool);
|
||||
bool from_python(PyObject*, boost::python::type<bool>);
|
||||
BOOST_PYTHON_DECL bool from_python(PyObject*, boost::python::type<bool>);
|
||||
bool from_python(PyObject*, boost::python::type<const bool&>);
|
||||
|
||||
PyObject* to_python(void);
|
||||
void from_python(PyObject*, boost::python::type<void>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(void);
|
||||
BOOST_PYTHON_DECL void from_python(PyObject*, boost::python::type<void>);
|
||||
|
||||
PyObject* to_python(const char* s);
|
||||
const char* from_python(PyObject*, boost::python::type<const char*>);
|
||||
BOOST_PYTHON_DECL const char* from_python(PyObject*, boost::python::type<const char*>);
|
||||
|
||||
PyObject* to_python(const std::string& s);
|
||||
std::string from_python(PyObject*, boost::python::type<std::string>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(const std::string& s);
|
||||
BOOST_PYTHON_DECL std::string from_python(PyObject*, boost::python::type<std::string>);
|
||||
std::string from_python(PyObject*, boost::python::type<const std::string&>);
|
||||
|
||||
inline PyObject* to_python(const std::complex<float>& x)
|
||||
|
||||
62
include/boost/python/converter/body.hpp
Normal file
62
include/boost/python/converter/body.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef BODY_DWA2001127_HPP
|
||||
# define BODY_DWA2001127_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace registry
|
||||
{
|
||||
class entry;
|
||||
}
|
||||
|
||||
struct BOOST_PYTHON_DECL body
|
||||
{
|
||||
public:
|
||||
body(type_id_t key);
|
||||
virtual ~body() {}
|
||||
|
||||
type_id_t key() const;
|
||||
|
||||
protected:
|
||||
// true iff the registry is still alive
|
||||
bool can_unregister() const;
|
||||
|
||||
private:
|
||||
// called when the registry is destroyed, to prevent it from being
|
||||
// unregistered.
|
||||
void do_not_unregister();
|
||||
friend class registry::entry;
|
||||
|
||||
private:
|
||||
type_id_t m_key;
|
||||
bool m_can_unregister;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline body::body(type_id_t key)
|
||||
: m_key(key)
|
||||
, m_can_unregister(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline type_id_t body::key() const
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
|
||||
inline bool body::can_unregister() const
|
||||
{
|
||||
return m_can_unregister;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // BODY_DWA2001127_HPP
|
||||
69
include/boost/python/converter/builtin_converters.hpp
Normal file
69
include/boost/python/converter/builtin_converters.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# define BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <string>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Provide specializations of to_python_value
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct builtin_to_python
|
||||
{
|
||||
static bool convertible() { return true; }
|
||||
};
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
template <> struct to_python_value<T&> \
|
||||
: detail::builtin_to_python \
|
||||
{ \
|
||||
PyObject* operator()(T const& x) const \
|
||||
{ \
|
||||
return (expr); \
|
||||
} \
|
||||
}; \
|
||||
template <> struct to_python_value<T const&> \
|
||||
: detail::builtin_to_python \
|
||||
{ \
|
||||
PyObject* operator()(T const& x) const \
|
||||
{ \
|
||||
return (expr); \
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
# 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, PyInt_FromLong(x))
|
||||
|
||||
BOOST_PYTHON_TO_INT(char)
|
||||
BOOST_PYTHON_TO_INT(short)
|
||||
BOOST_PYTHON_TO_INT(int)
|
||||
BOOST_PYTHON_TO_INT(long)
|
||||
# undef BOOST_TO_PYTHON_INT
|
||||
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x)
|
||||
|
||||
namespace converter
|
||||
{
|
||||
|
||||
void initialize_builtin_converters();
|
||||
|
||||
}
|
||||
|
||||
}} // namespace boost::python::converter
|
||||
|
||||
#endif // BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
75
include/boost/python/converter/class.hpp
Normal file
75
include/boost/python/converter/class.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CLASS_DWA20011215_HPP
|
||||
# define CLASS_DWA20011215_HPP
|
||||
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T>
|
||||
struct class_from_python_converter
|
||||
{
|
||||
class_from_python_converter();
|
||||
|
||||
static void* convertible(PyObject*);
|
||||
static T& convert_ref(PyObject*, from_python_data&);
|
||||
static T const& convert_cref(PyObject*, from_python_data&);
|
||||
static T* convert_ptr(PyObject*, from_python_data&);
|
||||
static T const* convert_cptr(PyObject*, from_python_data&);
|
||||
|
||||
from_python_converter<T&> to_ref;
|
||||
from_python_converter<T const&> to_cref;
|
||||
from_python_converter<T*> to_ptr;
|
||||
from_python_converter<T const*> to_cptr;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
class_from_python_converter<T>::class_from_python_converter()
|
||||
: to_ref(convertible, convert_ref)
|
||||
, to_cref(convertible, convert_cref)
|
||||
, to_ptr(convertible, convert_ptr)
|
||||
, to_cptr(convertible, convert_cptr)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
T& class_from_python_converter<T>::convert_ref(PyObject*, from_python_data& x)
|
||||
{
|
||||
return *static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const& class_from_python_converter<T>::convert_cref(PyObject*, from_python_data& x)
|
||||
{
|
||||
return *static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
T* class_from_python_converter<T>::convert_ptr(PyObject*, from_python_data& x)
|
||||
{
|
||||
return static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const* class_from_python_converter<T>::convert_cptr(PyObject*, from_python_data& x)
|
||||
{
|
||||
return static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void* class_from_python_converter<T>::convertible(PyObject* p)
|
||||
{
|
||||
return objects::find_instance<T>(p);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CLASS_DWA20011215_HPP
|
||||
198
include/boost/python/converter/from_python.hpp
Normal file
198
include/boost/python/converter/from_python.hpp
Normal file
@@ -0,0 +1,198 @@
|
||||
// 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_DWA2002127_HPP
|
||||
# define FROM_PYTHON_DWA2002127_HPP
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/converter/body.hpp>
|
||||
# include <boost/python/converter/from_python_function.hpp>
|
||||
# include <boost/python/converter/from_python_data.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// The type of convertibility checking functions
|
||||
typedef void* (*from_python_check)(PyObject*);
|
||||
typedef void (*from_python_destructor)(from_python_data&);
|
||||
|
||||
// forward declaration
|
||||
template <class T> struct from_python_lookup;
|
||||
|
||||
// from_python --
|
||||
// A body class representing a conversion from python to C++.
|
||||
|
||||
struct BOOST_PYTHON_DECL from_python_converter_base : body
|
||||
{
|
||||
from_python_converter_base(type_id_t, from_python_check); // registers
|
||||
|
||||
// Must return non-null iff the conversion will be successful. Any
|
||||
// non-null pointer is acceptable, and will be passed on to the
|
||||
// convert() function, so useful data can be stored there.
|
||||
inline void* convertible(PyObject*) const;
|
||||
|
||||
// Given the head of a from_python converter chain, find the
|
||||
// converter which can convert p, leaving its intermediate data in
|
||||
// data.
|
||||
inline static from_python_converter_base const*
|
||||
find(from_python_converter_base const*chain, PyObject* p, void*& data);
|
||||
|
||||
private:
|
||||
from_python_check m_convertible;
|
||||
from_python_converter_base* m_next;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct from_python_converter : from_python_converter_base
|
||||
{
|
||||
public: // types
|
||||
typedef typename from_python_function<T>::type conversion_function;
|
||||
|
||||
public: // member functions
|
||||
from_python_converter(from_python_check, conversion_function, from_python_destructor = 0);
|
||||
T convert(PyObject*, from_python_data&) const;
|
||||
void destroy(from_python_data&) const;
|
||||
|
||||
// Find a converter for converting p to a T.
|
||||
static from_python_converter<T> const* find(PyObject* p, void*& data);
|
||||
|
||||
private: // data members
|
||||
conversion_function m_convert;
|
||||
from_python_destructor m_destroy;
|
||||
|
||||
// Keeps the chain of converters which convert from PyObject* to T
|
||||
static from_python_converter_base*const& chain;
|
||||
};
|
||||
|
||||
// Initialized to refer to a common place in the registry.
|
||||
template <class T>
|
||||
from_python_converter_base*const&
|
||||
from_python_converter<T>::chain = registry::from_python_chain(type_id<T>());
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// A class which implements from_python with a registry lookup.
|
||||
template <class T>
|
||||
struct from_python_lookup // : from_python_base
|
||||
{
|
||||
public: // types
|
||||
|
||||
public: // member functions
|
||||
from_python_lookup(PyObject* source);
|
||||
~from_python_lookup();
|
||||
|
||||
bool convertible() const;
|
||||
T operator()(PyObject*);
|
||||
|
||||
public: // functions for use by conversion implementations
|
||||
// Get the converter object
|
||||
from_python_converter<T> const* converter() const;
|
||||
|
||||
private: // data members
|
||||
typedef typename from_python_intermediate_data<T>::type intermediate_t;
|
||||
mutable intermediate_t m_intermediate_data;
|
||||
from_python_converter<T> const* m_converter;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline void* from_python_converter_base::convertible(PyObject* o) const
|
||||
{
|
||||
return m_convertible(o);
|
||||
}
|
||||
|
||||
inline from_python_converter_base const*
|
||||
from_python_converter_base::find(
|
||||
from_python_converter_base const* chain, PyObject* p, void*& data)
|
||||
{
|
||||
for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next)
|
||||
{
|
||||
void* d = q->convertible(p);
|
||||
if (d != 0)
|
||||
{
|
||||
data = d;
|
||||
return q;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T>::from_python_converter(
|
||||
from_python_check checker
|
||||
, conversion_function converter
|
||||
, from_python_destructor destructor // = 0
|
||||
)
|
||||
: from_python_converter_base(type_id<T>(), checker)
|
||||
, m_convert(converter)
|
||||
, m_destroy(destructor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T> const*
|
||||
from_python_converter<T>::find(PyObject* p, void*& data)
|
||||
{
|
||||
return static_cast<from_python_converter<T> const*>(
|
||||
from_python_converter_base::find(chain, p, data));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T from_python_converter<T>::convert(PyObject* src, from_python_data& data) const
|
||||
{
|
||||
return this->m_convert(src, data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void from_python_converter<T>::destroy(from_python_data& data) const
|
||||
{
|
||||
if (this->m_destroy)
|
||||
{
|
||||
this->m_destroy(data);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_lookup<T>::from_python_lookup(PyObject* src)
|
||||
: m_converter(
|
||||
from_python_converter<T>::find(
|
||||
src, m_intermediate_data.stage1))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_lookup<T>::~from_python_lookup()
|
||||
{
|
||||
if (m_converter != 0)
|
||||
m_converter->destroy(m_intermediate_data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool from_python_lookup<T>::convertible() const
|
||||
{
|
||||
return this->m_converter != 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T from_python_lookup<T>::operator()(PyObject* obj)
|
||||
{
|
||||
return this->m_converter->convert(obj, m_intermediate_data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T> const*
|
||||
from_python_lookup<T>::converter() const
|
||||
{
|
||||
return this->m_converter;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_DWA2002127_HPP
|
||||
206
include/boost/python/converter/from_python_data.hpp
Normal file
206
include/boost/python/converter/from_python_data.hpp
Normal file
@@ -0,0 +1,206 @@
|
||||
// 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/detail/char_array.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
// Keep these for the metaprogram which EDG is choking on.
|
||||
# if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/type_traits/alignment_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// A POD which is layout-compatible with the real intermediate data
|
||||
// for all from_python conversions. There may be additional storage if
|
||||
// we are converting a reference type.
|
||||
struct from_python_data
|
||||
{
|
||||
void* stage1;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T> struct referent_alignment;
|
||||
template <class T> struct referent_size;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
struct referent_alignment<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = alignment_of<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct referent_size<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = sizeof(T));
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
template <class U>
|
||||
struct alignment_chars
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_T, n = alignment_of<U>::value);
|
||||
char elements[n + 1];
|
||||
};
|
||||
|
||||
template <class T> struct referent_alignment
|
||||
{
|
||||
template <class U>
|
||||
static alignment_chars<U> helper(U&);
|
||||
|
||||
static T t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = sizeof(helper(t).elements) - 1);
|
||||
};
|
||||
|
||||
|
||||
template <class T> struct referent_size
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t));
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
struct unknown_alignment
|
||||
{
|
||||
void* p;
|
||||
};
|
||||
|
||||
// EDG is too slow to handle this metaprogram :(
|
||||
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
struct alignment_dummy;
|
||||
|
||||
template <std::size_t target_alignment>
|
||||
struct best_alignment_type
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, align1 = alignment_of<T1>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, align2 = alignment_of<T2>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, aligned2 = (
|
||||
(align2 >= target_alignment)
|
||||
& (align2 % target_alignment == 0))
|
||||
);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, choose_t2 = (
|
||||
aligned2 && (
|
||||
is_same<T1,unknown_alignment>::value
|
||||
| (align2 < alignment_of<T1>::value)
|
||||
| (sizeof(T2) < sizeof(T1)))
|
||||
));
|
||||
|
||||
typedef mpl::select_type<choose_t2, T2, T1>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
typedef mpl::type_list<
|
||||
char,short,int,long,float,double,long double
|
||||
,void*
|
||||
,void(*)()
|
||||
,void (alignment_dummy::*)()
|
||||
, char (alignment_dummy::*)
|
||||
>
|
||||
align_types;
|
||||
#endif // EDG is too slow
|
||||
|
||||
template <class Align, std::size_t size>
|
||||
struct aligned_storage
|
||||
{
|
||||
typedef Align align_t;
|
||||
union
|
||||
{
|
||||
Align align;
|
||||
char bytes[size
|
||||
// this is just a STATIC_ASSERT. For some reason
|
||||
// MSVC was barfing on the boost one.
|
||||
- (is_same<align_t,unknown_alignment>::value ? size : 0)];
|
||||
};
|
||||
};
|
||||
|
||||
template <class Reference>
|
||||
struct referent_storage
|
||||
{
|
||||
// EDG is too slow to handle this metaprogram :(
|
||||
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
typedef mpl::for_each<
|
||||
align_types
|
||||
, unknown_alignment
|
||||
, best_alignment_type<referent_alignment<Reference>::value>
|
||||
> loop;
|
||||
typedef typename loop::state align_t;
|
||||
#else
|
||||
// The Python source makes the assumption that double has
|
||||
// maximal alignment anyway
|
||||
typedef double align_t;
|
||||
#endif
|
||||
|
||||
typedef aligned_storage<align_t,referent_size<Reference>::value> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct intermediate_data : from_python_data
|
||||
{
|
||||
typename referent_storage<T>::type stage2;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct intermediate_data<void> : from_python_data
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Auxiliary POD storage where the convertible and/or convert functions of a
|
||||
// from_python object may place arbitrary data.
|
||||
//
|
||||
// Always starts with a void*
|
||||
//
|
||||
// For references, we produce additional aligned storage sufficient to
|
||||
// store the referent
|
||||
|
||||
template <class T>
|
||||
struct from_python_intermediate_data
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_reference<T>::value, T, void>::type just_reference_t;
|
||||
|
||||
typedef detail::intermediate_data<just_reference_t> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void* get_storage(from_python_data& x, boost::type<T>* = 0)
|
||||
{
|
||||
typedef typename from_python_intermediate_data<T>::type layout;
|
||||
return static_cast<layout*>(&x)->stage2.bytes;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
23
include/boost/python/converter/from_python_function.hpp
Normal file
23
include/boost/python/converter/from_python_function.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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_FUNCTION_DWA2002128_HPP
|
||||
# define FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct from_python_data;
|
||||
|
||||
template <class T>
|
||||
struct from_python_function
|
||||
{
|
||||
typedef T (*type)(PyObject*, from_python_data&);
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
108
include/boost/python/converter/handle.hpp
Normal file
108
include/boost/python/converter/handle.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
// 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 HANDLE_DWA20011130_HPP
|
||||
# define HANDLE_DWA20011130_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL body;
|
||||
|
||||
// The common base class for unwrap_ and wrap_ handle objects. They
|
||||
// share a common base so that handles can be linked into a chain
|
||||
// within a function wrapper which is managed by a single object.
|
||||
struct BOOST_PYTHON_DECL handle : boost::noncopyable
|
||||
{
|
||||
public: // member functions
|
||||
|
||||
// All constructors take a body* passed from the derived class.
|
||||
//
|
||||
// Constructors taking a handle links this into a chain of
|
||||
// handles, for more efficient management in function wrappers
|
||||
handle();
|
||||
handle(body* body);
|
||||
handle(body* body, handle& prev);
|
||||
|
||||
// returns true iff all handles in the chain can convert their
|
||||
// arguments
|
||||
bool convertible() const;
|
||||
|
||||
// safe_bool idiom from Peter Dimov: provides handles to/from
|
||||
// bool without enabling handles to integer types/void*.
|
||||
private:
|
||||
struct dummy { inline void nonnull() {} };
|
||||
typedef void (dummy::*safe_bool)();
|
||||
public:
|
||||
inline operator safe_bool() const;
|
||||
inline safe_bool operator!() const;
|
||||
|
||||
protected: // member functions for derived classes
|
||||
// Get the body we hold
|
||||
inline body* get_body() const;
|
||||
|
||||
inline void set_body(body*);
|
||||
inline void set_prev(handle&);
|
||||
|
||||
// Release all bodies in the chain, in reverse order of
|
||||
// initialization. Only actually called for the head of the chain.
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
// Holds implementation
|
||||
body* m_body;
|
||||
|
||||
// handle for next argument, if any.
|
||||
handle* m_next;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline handle::handle()
|
||||
: m_next(0)
|
||||
{}
|
||||
|
||||
inline handle::handle(body* body, handle& prev)
|
||||
: m_body(body), m_next(0)
|
||||
{
|
||||
prev.m_next = this;
|
||||
}
|
||||
|
||||
inline handle::handle(body* body)
|
||||
: m_body(body), m_next(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline handle::operator handle::safe_bool() const
|
||||
{
|
||||
return convertible() ? &dummy::nonnull : 0;
|
||||
}
|
||||
|
||||
inline handle::safe_bool handle::operator!() const
|
||||
{
|
||||
return convertible() ? 0 : &dummy::nonnull;
|
||||
}
|
||||
|
||||
inline body* handle::get_body() const
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
||||
inline void handle::set_body(body* body)
|
||||
{
|
||||
m_body = body;
|
||||
}
|
||||
|
||||
inline void handle::set_prev(handle& prev)
|
||||
{
|
||||
prev.m_next = this;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // HANDLE_DWA20011130_HPP
|
||||
32
include/boost/python/converter/registry.hpp
Normal file
32
include/boost/python/converter/registry.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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/converter/type_id.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/to_python_function.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL from_python_converter_base;
|
||||
|
||||
// This namespace acts as a sort of singleton
|
||||
namespace registry
|
||||
{
|
||||
BOOST_PYTHON_DECL to_python_value_function const&
|
||||
to_python_function(undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // REGISTRY_DWA20011127_HPP
|
||||
70
include/boost/python/converter/smart_ptr.hpp
Normal file
70
include/boost/python/converter/smart_ptr.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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 SMART_PTR_DWA2002123_HPP
|
||||
# define SMART_PTR_DWA2002123_HPP
|
||||
|
||||
# include <boost/python/converter/class.hpp>
|
||||
# include <boost/python/object/pointer_holder.hpp>
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class Pointer, class Value>
|
||||
class smart_ptr_wrapper
|
||||
: wrapper<Pointer const&>
|
||||
{
|
||||
smart_ptr_wrapper(ref const& type_)
|
||||
: m_class_object(type_)
|
||||
{
|
||||
assert(type_->ob_type == (PyTypeObject*)class_metatype().get());
|
||||
}
|
||||
|
||||
PyObject* convert(Pointer x) const;
|
||||
|
||||
private:
|
||||
ref m_class_object;
|
||||
|
||||
smart_ptr_converters();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
template <class Pointer, class Value>
|
||||
PyObject* smart_ptr_wrapper<Pointer,Value>::convert(Pointer x) const
|
||||
{
|
||||
if (x.operator->() == 0)
|
||||
return detail::none();
|
||||
|
||||
// Don't call the type to do the construction, since that
|
||||
// would require the registration of an __init__ copy
|
||||
// constructor. Instead, just construct the object in place.
|
||||
PyObject* raw_result = (PyObject*)PyObject_New(
|
||||
instance, (PyTypeObject*)m_class_object.get());
|
||||
|
||||
if (raw_result == 0)
|
||||
return 0;
|
||||
|
||||
// Everything's OK; Bypass NULL checks but guard against
|
||||
// exceptions.
|
||||
ref result(raw_result, ref::allow_null());
|
||||
|
||||
// Build a value_holder to contain the object using the copy
|
||||
// constructor
|
||||
objects::pointer_holder<Pointer,Value>*
|
||||
p = new objects::pointer_holder<Pointer,Value>(x);
|
||||
|
||||
// Install it in the instance
|
||||
p->install(raw_result);
|
||||
|
||||
// Return the new result
|
||||
return result.release();
|
||||
}
|
||||
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // SMART_PTR_DWA2002123_HPP
|
||||
191
include/boost/python/converter/target.hpp
Normal file
191
include/boost/python/converter/target.hpp
Normal file
@@ -0,0 +1,191 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#ifndef TARGET_DWA20011119_HPP
|
||||
# define TARGET_DWA20011119_HPP
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// target --
|
||||
//
|
||||
// This type generator (see
|
||||
// ../../../more/generic_programming.html#type_generator) is used
|
||||
// to select the return type of the appropriate converter for
|
||||
// unwrapping a given type.
|
||||
|
||||
// Strategy:
|
||||
//
|
||||
// 1. reduce everything to a common, un-cv-qualified reference
|
||||
// type where possible. This will save on registering many different
|
||||
// converter types.
|
||||
//
|
||||
// 2. Treat built-in types specially: when unwrapping a value or
|
||||
// constant reference to one of these, use a value for the target
|
||||
// type. It will bind to a const reference if neccessary, and more
|
||||
// importantly, avoids having to dynamically allocate room for
|
||||
// an lvalue of types which can be cheaply copied.
|
||||
//
|
||||
|
||||
// Target Source
|
||||
// int int
|
||||
// int const& int
|
||||
// int& int&
|
||||
// int volatile& int volatile&
|
||||
// int const volatile& int const volatile&
|
||||
|
||||
// On compilers supporting partial specialization:
|
||||
//
|
||||
// Target Source
|
||||
// T T const&
|
||||
// T& T&
|
||||
// T const& T const&
|
||||
// T volatile T&
|
||||
// T const volatile& T const&
|
||||
// T* T*
|
||||
// T const* T const*
|
||||
// T volatile T*
|
||||
// T const volatile* T const*
|
||||
// T cv*const& same as T cv*
|
||||
// T cv*& T*& <- should this be legal?
|
||||
// T cv*volatile& T*& <- should this be legal?
|
||||
// T cv*const volatile& T*& <- should this be legal?
|
||||
|
||||
// On others:
|
||||
//
|
||||
// Target Source
|
||||
// T T&
|
||||
// T cv& T cv&
|
||||
// T cv* T cv*
|
||||
// T cv*cv& T cv*cv&
|
||||
|
||||
// As you can see, in order to handle the same range of types without
|
||||
// partial specialization, more converters need to be registered.
|
||||
|
||||
template <class T>
|
||||
struct target
|
||||
{
|
||||
// Some pointer types are handled in a more sophisticated way on
|
||||
// compilers supporting partial specialization.
|
||||
BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_scalar<T>::value));
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
use_identity
|
||||
, T
|
||||
, typename add_reference<
|
||||
typename add_const<
|
||||
typename remove_volatile<T>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// When partial specialization is not present, we'll simply need to
|
||||
// register many more converters.
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
struct target<T&>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type& type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T const&>
|
||||
{
|
||||
typedef typename boost::mpl::select_type<
|
||||
is_scalar<T>::value
|
||||
, typename remove_cv<T>::type
|
||||
, typename remove_volatile<T>::type const&
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T*>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
// Handle T*-cv for completeness. Function arguments in a signature
|
||||
// are never actually cv-qualified, but who knows how these converters
|
||||
// might be used, or whether compiler bugs lurk which make it seem
|
||||
// otherwise?
|
||||
template <class T>
|
||||
struct target<T* const>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T* volatile>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T* const volatile>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
// non-const references to pointers should be handled by the
|
||||
// specialization for T&, above.
|
||||
template <class T>
|
||||
struct target<T* const&>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
# endif
|
||||
|
||||
// Fortunately, we can handle T const& where T is an arithmetic type
|
||||
// by explicit specialization. These specializations will cause value
|
||||
// and const& arguments to be converted to values, rather than to
|
||||
// references.
|
||||
# define BOOST_PYTHON_UNWRAP_VALUE(T) \
|
||||
template <> \
|
||||
struct target<T> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T const> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T volatile> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T const volatile> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T const&> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_UNWRAP_VALUE(char);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned char);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed char);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned int);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed int);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned short);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed short);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned long);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed long);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(char const*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TARGET_DWA20011119_HPP
|
||||
32
include/boost/python/converter/to_python_function.hpp
Normal file
32
include/boost/python/converter/to_python_function.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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_DWA2002128_HPP
|
||||
# define TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/type_traits/transform_traits.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_value_function)(void const*);
|
||||
|
||||
// Given a typesafe to_python conversion function, produces a
|
||||
// to_python_value_function which can be registered in the usual way.
|
||||
template <class T, class ToPython>
|
||||
struct as_to_python_value_function
|
||||
{
|
||||
static PyObject* convert(void const* x)
|
||||
{
|
||||
return ToPython::convert(*(T const*)x);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
176
include/boost/python/converter/type_id.hpp
Normal file
176
include/boost/python/converter/type_id.hpp
Normal file
@@ -0,0 +1,176 @@
|
||||
// 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 TYPE_ID_DWA20011127_HPP
|
||||
# define TYPE_ID_DWA20011127_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/python/detail/msvc_typeinfo.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
# include <boost/type.hpp>
|
||||
# include <typeinfo>
|
||||
# include <iosfwd>
|
||||
# include <cstring>
|
||||
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// for this compiler at least, cross-shared-library type_info
|
||||
// comparisons don't work, so use typeid(x).name() instead. It's not
|
||||
// yet clear what the best default strategy is.
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3
|
||||
# define BOOST_PYTHON_TYPE_ID_NAME
|
||||
# endif
|
||||
|
||||
// type ids which represent the same information as std::type_info
|
||||
// (i.e. the top-level reference and cv-qualifiers are stripped), but
|
||||
// which works across shared libraries.
|
||||
struct undecorated_type_id_t : totally_ordered<undecorated_type_id_t>
|
||||
{
|
||||
undecorated_type_id_t(std::type_info const&);
|
||||
|
||||
// default constructor needed to build arrays, etc.
|
||||
undecorated_type_id_t();
|
||||
|
||||
bool operator<(undecorated_type_id_t const& rhs) const;
|
||||
bool operator==(undecorated_type_id_t const& rhs) const;
|
||||
|
||||
char const* name() const;
|
||||
friend BOOST_PYTHON_DECL std::ostream& operator<<(
|
||||
std::ostream&, undecorated_type_id_t const&);
|
||||
|
||||
private: // data members
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
typedef char const* base_id_t;
|
||||
# else
|
||||
typedef std::type_info const* base_id_t;
|
||||
# endif
|
||||
|
||||
base_id_t m_base_type;
|
||||
};
|
||||
|
||||
struct type_id_t : totally_ordered<type_id_t>
|
||||
{
|
||||
enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 };
|
||||
|
||||
type_id_t(undecorated_type_id_t, decoration = decoration());
|
||||
|
||||
bool operator<(type_id_t const& rhs) const;
|
||||
bool operator==(type_id_t const& rhs) const;
|
||||
|
||||
friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&);
|
||||
|
||||
operator undecorated_type_id_t const&() const;
|
||||
private: // type
|
||||
typedef undecorated_type_id_t base_id_t;
|
||||
|
||||
private: // data members
|
||||
decoration m_decoration;
|
||||
base_id_t m_base_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline undecorated_type_id_t undecorated_type_id(boost::type<T>* = 0)
|
||||
{
|
||||
return undecorated_type_id_t(
|
||||
# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600)
|
||||
typeid(T)
|
||||
# else // strip the decoration which msvc and Intel mistakenly leave in
|
||||
python::detail::msvc_typeid<T>()
|
||||
# endif
|
||||
);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline type_id_t type_id(boost::type<T>* = 0)
|
||||
{
|
||||
return type_id_t(
|
||||
undecorated_type_id<T>()
|
||||
, type_id_t::decoration(
|
||||
(is_const<T>::value || python::detail::is_reference_to_const<T>::value
|
||||
? type_id_t::const_ : 0)
|
||||
| (is_volatile<T>::value || python::detail::is_reference_to_volatile<T>::value
|
||||
? type_id_t::volatile_ : 0)
|
||||
| (is_reference<T>::value ? type_id_t::reference : 0)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
inline undecorated_type_id_t::undecorated_type_id_t(std::type_info const& id)
|
||||
: m_base_type(
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
id.name()
|
||||
# else
|
||||
&id
|
||||
# endif
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
inline undecorated_type_id_t::undecorated_type_id_t()
|
||||
: m_base_type()
|
||||
{
|
||||
}
|
||||
|
||||
inline type_id_t::type_id_t(undecorated_type_id_t base_t, decoration decoration)
|
||||
: m_decoration(decoration)
|
||||
, m_base_type(base_t)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool undecorated_type_id_t::operator<(undecorated_type_id_t const& rhs) const
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
return std::strcmp(m_base_type, rhs.m_base_type) < 0;
|
||||
# else
|
||||
return m_base_type->before(*rhs.m_base_type);
|
||||
# endif
|
||||
}
|
||||
|
||||
inline bool type_id_t::operator<(type_id_t const& rhs) const
|
||||
{
|
||||
return m_decoration < rhs.m_decoration
|
||||
|| m_decoration == rhs.m_decoration
|
||||
&& m_base_type < rhs.m_base_type;
|
||||
}
|
||||
|
||||
inline bool undecorated_type_id_t::operator==(undecorated_type_id_t const& rhs) const
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
return !std::strcmp(m_base_type, rhs.m_base_type);
|
||||
# else
|
||||
return *m_base_type == *rhs.m_base_type;
|
||||
# endif
|
||||
}
|
||||
|
||||
inline bool type_id_t::operator==(type_id_t const& rhs) const
|
||||
{
|
||||
return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type;
|
||||
}
|
||||
|
||||
inline type_id_t::operator undecorated_type_id_t const&() const
|
||||
{
|
||||
return m_base_type;
|
||||
}
|
||||
|
||||
inline char const* undecorated_type_id_t::name() const
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
return m_base_type;
|
||||
# else
|
||||
return m_base_type->name();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, undecorated_type_id_t const&);
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TYPE_ID_DWA20011127_HPP
|
||||
36
include/boost/python/converter/unwrapper_base.hpp
Normal file
36
include/boost/python/converter/unwrapper_base.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef UNWRAPPER_BASE_DWA20011215_HPP
|
||||
# define UNWRAPPER_BASE_DWA20011215_HPP
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/body.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL unwrapper_base : body
|
||||
{
|
||||
public:
|
||||
unwrapper_base(type_id_t); // registers
|
||||
~unwrapper_base(); // unregisters
|
||||
|
||||
// Must return non-null iff the conversion will be successful. Any
|
||||
// non-null pointer is acceptable, and will be passed on to the
|
||||
// convert() function, so useful data can be stored there.
|
||||
virtual void* can_convert(PyObject*) const = 0;
|
||||
|
||||
protected:
|
||||
// this is an arbitrary non-null pointer you can use to indicate success
|
||||
static void* const non_null;
|
||||
|
||||
private: // body required interface implementation
|
||||
void destroy_handle(handle*) const {}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // UNWRAPPER_BASE_DWA20011215_HPP
|
||||
33
include/boost/python/converter/unwrapper_select.hpp
Normal file
33
include/boost/python/converter/unwrapper_select.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
# define UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T> struct unwrapper;
|
||||
|
||||
// Select the type returned by unwrapper objects when unwrapping a
|
||||
// given type. When unwrapping T const&, the unwrapper returns T&, so
|
||||
// that the same unwrapper object can be used for both conversions (on
|
||||
// a conforming compiler).
|
||||
template <class T>
|
||||
struct unwrapper_select
|
||||
{
|
||||
typedef unwrapper<T> type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct unwrapper_select<T const&>
|
||||
{
|
||||
typedef unwrapper<T&> type;
|
||||
};
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
42
include/boost/python/copy_const_reference.hpp
Normal file
42
include/boost/python/copy_const_reference.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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/select_type.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::select_type<
|
||||
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
|
||||
42
include/boost/python/copy_non_const_reference.hpp
Normal file
42
include/boost/python/copy_non_const_reference.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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/select_type.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::select_type<
|
||||
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
|
||||
@@ -18,26 +18,28 @@
|
||||
# include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
struct import_error : error_already_set {};
|
||||
struct export_error : error_already_set {};
|
||||
}}
|
||||
struct BOOST_PYTHON_DECL import_error: error_already_set {};
|
||||
struct BOOST_PYTHON_DECL export_error : error_already_set {};
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Concept: throw exception if api_major is changed
|
||||
// show warning on stderr if api_minor is changed
|
||||
const int export_converters_api_major = 4;
|
||||
const int export_converters_api_minor = 1;
|
||||
extern const char* converters_attribute_name;
|
||||
void* import_converter_object(const std::string& module_name,
|
||||
const std::string& py_class_name,
|
||||
const std::string& attribute_name);
|
||||
void check_export_converters_api(const int importing_major,
|
||||
const int importing_minor,
|
||||
const int imported_major,
|
||||
const int imported_minor);
|
||||
const int export_converters_api_major = 4;
|
||||
const int export_converters_api_minor = 1;
|
||||
extern BOOST_PYTHON_DECL const char* converters_attribute_name;
|
||||
BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name,
|
||||
const std::string& py_class_name,
|
||||
const std::string& attribute_name);
|
||||
BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major,
|
||||
const int importing_minor,
|
||||
const int imported_major,
|
||||
const int imported_minor);
|
||||
|
||||
}}}
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
// forward declaration
|
||||
namespace boost { namespace python { namespace detail {
|
||||
@@ -232,56 +234,56 @@ struct export_converter_object : export_converter_object_noncopyable<T>
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/* This class template is instantiated by import_converters<T>.
|
||||
Its purpose is to import the converter_object via the Python API.
|
||||
The actual import is only done once. The pointer to the
|
||||
imported converter object is kept in the static data member
|
||||
imported_converters.
|
||||
*/
|
||||
template <class T>
|
||||
class import_extension_class
|
||||
: public python_import_extension_class_converters<T>
|
||||
{
|
||||
public:
|
||||
inline import_extension_class(const char* module, const char* py_class) {
|
||||
m_module = module;
|
||||
m_py_class = py_class;
|
||||
}
|
||||
*/
|
||||
template <class T>
|
||||
class import_extension_class
|
||||
: public python_import_extension_class_converters<T>
|
||||
{
|
||||
public:
|
||||
inline import_extension_class(const char* module, const char* py_class) {
|
||||
m_module = module;
|
||||
m_py_class = py_class;
|
||||
}
|
||||
|
||||
static boost::python::export_converter_object_base<T>* get_converters();
|
||||
static boost::python::export_converter_object_base<T>* get_converters();
|
||||
|
||||
private:
|
||||
static std::string m_module;
|
||||
static std::string m_py_class;
|
||||
static boost::python::export_converter_object_base<T>* imported_converters;
|
||||
};
|
||||
private:
|
||||
static std::string m_module;
|
||||
static std::string m_py_class;
|
||||
static boost::python::export_converter_object_base<T>* imported_converters;
|
||||
};
|
||||
|
||||
template <class T> std::string import_extension_class<T>::m_module;
|
||||
template <class T> std::string import_extension_class<T>::m_py_class;
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::imported_converters = 0;
|
||||
template <class T> std::string import_extension_class<T>::m_module;
|
||||
template <class T> std::string import_extension_class<T>::m_py_class;
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::imported_converters = 0;
|
||||
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::get_converters() {
|
||||
if (imported_converters == 0) {
|
||||
void* cobject
|
||||
= import_converter_object(m_module, m_py_class,
|
||||
converters_attribute_name);
|
||||
imported_converters
|
||||
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
|
||||
check_export_converters_api(
|
||||
export_converters_api_major,
|
||||
export_converters_api_minor,
|
||||
imported_converters->get_api_major(),
|
||||
imported_converters->get_api_minor());
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::get_converters() {
|
||||
if (imported_converters == 0) {
|
||||
void* cobject
|
||||
= import_converter_object(m_module, m_py_class,
|
||||
converters_attribute_name);
|
||||
imported_converters
|
||||
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
|
||||
check_export_converters_api(
|
||||
export_converters_api_major,
|
||||
export_converters_api_minor,
|
||||
imported_converters->get_api_major(),
|
||||
imported_converters->get_api_minor());
|
||||
}
|
||||
return imported_converters;
|
||||
}
|
||||
return imported_converters;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
78
include/boost/python/default_call_policies.hpp
Normal file
78
include/boost/python/default_call_policies.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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/select_type.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_result_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::select_type<
|
||||
is_illegal
|
||||
, detail::specify_a_result_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
|
||||
341
include/boost/python/detail/arg_tuple_size.hpp
Normal file
341
include/boost/python/detail/arg_tuple_size.hpp
Normal file
@@ -0,0 +1,341 @@
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// This work was funded in part by Lawrence Berkeley National Labs
|
||||
//
|
||||
// This file generated for 5-argument member functions and 6-argument free
|
||||
// functions by gen_arg_tuple_size.python
|
||||
|
||||
#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
# define ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
|
||||
# include <boost/python/detail/char_array.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// Computes (at compile-time) the number of elements that a Python
|
||||
// argument tuple must have in order to be passed to a wrapped C++
|
||||
// (member) function of the given type.
|
||||
template <class F> struct arg_tuple_size;
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__)
|
||||
|
||||
template <class R>
|
||||
struct arg_tuple_size<R (*)()>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 0);
|
||||
};
|
||||
|
||||
template <class R, class A1>
|
||||
struct arg_tuple_size<R (*)(A1)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2>
|
||||
struct arg_tuple_size<R (*)(A1, A2)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5, A6)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)()>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
// Metrowerks thinks this creates ambiguities
|
||||
# if !defined(__MWERKS__) || __MWERKS__ > 0x2406
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)() const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)() volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)() const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
# endif // __MWERKS__
|
||||
# else
|
||||
|
||||
// We will use the "sizeof() trick" to work around the lack of
|
||||
// partial specialization in MSVC6 and its broken-ness in borland.
|
||||
// See http://opensource.adobe.com or
|
||||
// http://groups.yahoo.com/group/boost/message/5441 for
|
||||
// more examples
|
||||
|
||||
// The following helper functions are never actually called, since
|
||||
// they are only used within a sizeof() expression, but the type of
|
||||
// their return value is used to discriminate between various free
|
||||
// and member function pointers at compile-time.
|
||||
|
||||
template <class R>
|
||||
char_array<0> arg_tuple_size_helper(R (*)());
|
||||
|
||||
template <class R, class A1>
|
||||
char_array<1> arg_tuple_size_helper(R (*)(A1));
|
||||
|
||||
template <class R, class A1, class A2>
|
||||
char_array<2> arg_tuple_size_helper(R (*)(A1, A2));
|
||||
|
||||
template <class R, class A1, class A2, class A3>
|
||||
char_array<3> arg_tuple_size_helper(R (*)(A1, A2, A3));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4>
|
||||
char_array<4> arg_tuple_size_helper(R (*)(A1, A2, A3, A4));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<5> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
char_array<6> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5, A6));
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)());
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1));
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5));
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() const);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const);
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() volatile);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) volatile);
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() const volatile);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const volatile);
|
||||
|
||||
|
||||
template <class F>
|
||||
struct arg_tuple_size
|
||||
{
|
||||
// The sizeof() magic happens here
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value
|
||||
= sizeof(arg_tuple_size_helper(F(0)).elements) - 1);
|
||||
};
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
# define BASE_OBJECT_DWA051600_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/signatures.hpp> // really just for type<>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <cstring>
|
||||
|
||||
@@ -45,10 +44,7 @@ template <class PythonType>
|
||||
base_object<PythonType>::base_object(PyTypeObject* type_obj)
|
||||
{
|
||||
base_python_type* bp = this;
|
||||
#if !defined(_MSC_VER) || defined(__STLPORT)
|
||||
std::
|
||||
#endif
|
||||
memset(bp, 0, sizeof(base_python_type));
|
||||
BOOST_CSTD_::memset(bp, 0, sizeof(base_python_type));
|
||||
Py_INCREF(type_obj);
|
||||
PyObject_INIT(bp, type_obj);
|
||||
}
|
||||
|
||||
66
include/boost/python/detail/call_object.hpp
Normal file
66
include/boost/python/detail/call_object.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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 CALL_OBJECT_DWA20011222_HPP
|
||||
# define CALL_OBJECT_DWA20011222_HPP
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/detail/types.hpp>
|
||||
# include <boost/bind.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// A function object adaptor which turns a function returning R into
|
||||
// an "equivalent" function returning void, but taking an R& in
|
||||
// which the adapted function's result is stored.
|
||||
template <class R, class F>
|
||||
struct return_by_reference
|
||||
{
|
||||
typedef void return_type;
|
||||
|
||||
return_by_reference(R& result, F f)
|
||||
: m_result(result)
|
||||
, m_f(f)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
m_result = m_f();
|
||||
}
|
||||
|
||||
R& m_result;
|
||||
F m_f;
|
||||
};
|
||||
|
||||
// An object generator for the above adaptors
|
||||
template <class R, class F>
|
||||
return_by_reference<R,F> bind_return(R& result, F f)
|
||||
{
|
||||
return return_by_reference<R,F>(result, f);
|
||||
}
|
||||
|
||||
// Given a function object f with signature
|
||||
//
|
||||
// R f(PyTypeObject*,PyObject*)
|
||||
//
|
||||
// calls f inside of handle_exception_impl, placing f's result in
|
||||
// ret. Returns true iff an exception is thrown by f, leaving ret
|
||||
// unmodified.
|
||||
template <class R, class F>
|
||||
bool call_object(R& ret, PyObject* obj, F f)
|
||||
{
|
||||
return handle_exception(
|
||||
detail::bind_return(
|
||||
ret
|
||||
, boost::bind<R>(
|
||||
f, static_cast<type_object_base*>(obj->ob_type), obj)));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CALL_OBJECT_DWA20011222_HPP
|
||||
217
include/boost/python/detail/caller.hpp
Normal file
217
include/boost/python/detail/caller.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
// 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 CALLER_DWA20011214_HPP
|
||||
# define CALLER_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/eval.hpp>
|
||||
# include <boost/python/detail/returning.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <class T> struct to_python;
|
||||
}}
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct caller
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
|
||||
template <class P, class R>
|
||||
PyObject* operator()(R (*f)(), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (*f)(A0), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (*f)(A0, A1), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)(), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)() const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)() volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CALLER_DWA20011214_HPP
|
||||
@@ -9,8 +9,9 @@
|
||||
#ifndef CAST_DWA052500_H_
|
||||
# define CAST_DWA052500_H_
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
# ifndef BOOST_PYTHON_V2
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
@@ -75,4 +76,6 @@ struct downcast
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
# endif // BOOST_PYTHON_V2
|
||||
|
||||
#endif // CAST_DWA052500_H_
|
||||
|
||||
23
include/boost/python/detail/char_array.hpp
Normal file
23
include/boost/python/detail/char_array.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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
|
||||
@@ -59,9 +59,9 @@
|
||||
|
||||
# ifndef BOOST_PYTHON_MODULE_INIT
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name()
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
|
||||
# else
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name()
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -72,23 +72,35 @@
|
||||
****************************************************************************/
|
||||
|
||||
// backwards compatibility:
|
||||
#ifdef BOOST_RE_STATIC_LIB
|
||||
#ifdef BOOST_PYTHON_STATIC_LIB
|
||||
# define BOOST_PYTHON_STATIC_LINK
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC) && defined(_DLL)
|
||||
# define BOOST_PYTHON_HAS_DLL_RUNTIME
|
||||
#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(__BORLANDC__) && defined(_RTLDLL)
|
||||
# define BOOST_PYTHON_HAS_DLL_RUNTIME
|
||||
#if defined(__GNUC__)
|
||||
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern
|
||||
#endif
|
||||
|
||||
#if defined(__ICL) && defined(_DLL)
|
||||
# define BOOST_PYTHON_HAS_DLL_RUNTIME
|
||||
// Handle default cases
|
||||
#ifndef BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
|
||||
# ifdef _WIN32
|
||||
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
|
||||
# else
|
||||
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_HAS_DLL_RUNTIME) && !defined(BOOST_PYTHON_STATIC_LINK)
|
||||
#ifndef BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
|
||||
#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
|
||||
@@ -101,10 +113,26 @@
|
||||
# define BOOST_PYTHON_DECL
|
||||
#endif
|
||||
|
||||
#if (defined(BOOST_MSVC) || defined(__BORLANDC__)) && !defined(BOOST_PYTHON_NO_LIB) && !defined(BOOST_PYTHON_SOURCE)
|
||||
# include <boost/python/detail/python_library_include.hpp>
|
||||
#ifndef BOOST_PYTHON_DECL_TEMPLATE
|
||||
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
# define BOOST_PYTHON_DECL_TEMPLATE BOOST_PYTHON_DECL
|
||||
# else
|
||||
# define BOOST_PYTHON_DECL_TEMPLATE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
|
||||
#else
|
||||
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
|
||||
#endif
|
||||
|
||||
# ifndef BOOST_PYTHON_EXPORT_TEMPLATE
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template
|
||||
# endif
|
||||
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL
|
||||
|
||||
// Borland C++ Fix/error check:
|
||||
#if defined(__BORLANDC__)
|
||||
# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
|
||||
@@ -117,7 +145,7 @@
|
||||
# endif
|
||||
# endif
|
||||
# ifndef _RTLDLL
|
||||
// this is harmless for a staic link:
|
||||
// this is harmless for a static link:
|
||||
# define _RWSTD_COMPILE_INSTANTIATE
|
||||
# endif
|
||||
# endif
|
||||
@@ -129,4 +157,13 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
|
||||
// Work around a compiler bug.
|
||||
// boost::python::detail::function has to be seen by the compiler before the
|
||||
// boost::function class template.
|
||||
namespace boost { namespace python { namespace detail {
|
||||
class function;
|
||||
}}}
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_DWA052200_H_
|
||||
|
||||
34
include/boost/python/detail/cv_category.hpp
Normal file
34
include/boost/python/detail/cv_category.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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
|
||||
38
include/boost/python/detail/eval.hpp
Normal file
38
include/boost/python/detail/eval.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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 EVAL_DWA2002124_HPP
|
||||
# define EVAL_DWA2002124_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class T> struct undefined;
|
||||
template <class UnaryMetaFunction, class T>
|
||||
struct eval
|
||||
{
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
|
||||
// based on the (non-conforming) MSVC trick from MPL
|
||||
template<bool>
|
||||
struct unarymetafunction_vc : UnaryMetaFunction {};
|
||||
|
||||
// illegal C++ which causes VC to admit that unarymetafunction_vc
|
||||
// can have a nested template:
|
||||
template<>
|
||||
struct unarymetafunction_vc<true>
|
||||
{
|
||||
template<class> struct apply;
|
||||
};
|
||||
|
||||
typedef typename unarymetafunction_vc<
|
||||
::boost::mpl::detail::msvc_never_true<UnaryMetaFunction>::value
|
||||
>::template apply<T>::type type;
|
||||
# else
|
||||
typedef typename UnaryMetaFunction::template apply<T>::type type;
|
||||
# endif
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // EVAL_DWA2002124_HPP
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
@@ -26,7 +26,7 @@
|
||||
# include <memory>
|
||||
# include <boost/python/detail/init_function.hpp>
|
||||
# include <typeinfo>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/type_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
@@ -38,20 +38,45 @@ template <class T> struct right_operand;
|
||||
|
||||
enum without_downcast_t { without_downcast };
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// forward declarations
|
||||
class extension_instance;
|
||||
class extension_class_base;
|
||||
template <class T> class instance_holder;
|
||||
template <class T, class U> class instance_value_holder;
|
||||
template <class ref, class T> class instance_ptr_holder;
|
||||
template <class Specified> struct operand_select;
|
||||
class extension_instance;
|
||||
class extension_class_base;
|
||||
template <class T> class instance_holder;
|
||||
template <class T, class U> class instance_value_holder;
|
||||
template <class ref, class T> class instance_ptr_holder;
|
||||
template <class Specified> struct operand_select;
|
||||
template <long> struct choose_op;
|
||||
template <long> struct choose_rop;
|
||||
template <long> struct choose_unary_op;
|
||||
template <long> struct define_operator;
|
||||
|
||||
class BOOST_PYTHON_DECL extension_instance : public instance
|
||||
{
|
||||
public:
|
||||
extension_instance(PyTypeObject* class_);
|
||||
~extension_instance();
|
||||
|
||||
void add_implementation(std::auto_ptr<instance_holder_base> holder);
|
||||
|
||||
typedef std::vector<instance_holder_base*> held_objects;
|
||||
const held_objects& wrapped_objects() const
|
||||
{ return m_wrapped_objects; }
|
||||
private:
|
||||
held_objects m_wrapped_objects;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t<detail::extension_instance>;
|
||||
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class<detail::extension_instance>;
|
||||
# endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
BOOST_PYTHON_DECL meta_class<extension_instance>* extension_meta_class();
|
||||
BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p);
|
||||
BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
@@ -702,25 +727,80 @@ class held_instance : public Held
|
||||
public:
|
||||
held_instance(PyObject*) : Held() {}
|
||||
template <class A1>
|
||||
held_instance(PyObject*, A1 a1) : Held(a1) {}
|
||||
held_instance(PyObject*, A1 a1) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)) {}
|
||||
template <class A1, class A2>
|
||||
held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)) {}
|
||||
template <class A1, class A2, class A3>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)) {}
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(a1, a2, a3, a4, a5, a6, a7, a8) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)
|
||||
, typename unwrap_parameter<A8>::type(a8)) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)
|
||||
, typename unwrap_parameter<A8>::type(a8)
|
||||
, typename unwrap_parameter<A9>::type(a9)) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)
|
||||
, typename unwrap_parameter<A8>::type(a8)
|
||||
, typename unwrap_parameter<A9>::type(a9)
|
||||
, typename unwrap_parameter<A10>::type(a10)) {}
|
||||
};
|
||||
|
||||
// Abstract base class for all obj holders. Base for template class
|
||||
@@ -813,21 +893,6 @@ class instance_ptr_holder : public instance_holder<HeldType>
|
||||
PtrType m_ptr;
|
||||
};
|
||||
|
||||
class BOOST_PYTHON_DECL extension_instance : public instance
|
||||
{
|
||||
public:
|
||||
extension_instance(PyTypeObject* class_);
|
||||
~extension_instance();
|
||||
|
||||
void add_implementation(std::auto_ptr<instance_holder_base> holder);
|
||||
|
||||
typedef std::vector<instance_holder_base*> held_objects;
|
||||
const held_objects& wrapped_objects() const
|
||||
{ return m_wrapped_objects; }
|
||||
private:
|
||||
held_objects m_wrapped_objects;
|
||||
};
|
||||
|
||||
//
|
||||
// Template function implementations
|
||||
//
|
||||
|
||||
174
include/boost/python/detail/indirect_traits.hpp
Normal file
174
include/boost/python/detail/indirect_traits.hpp
Normal file
@@ -0,0 +1,174 @@
|
||||
// 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 INDIRECT_TRAITS_DWA2002131_HPP
|
||||
# define INDIRECT_TRAITS_DWA2002131_HPP
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_reference_to_const
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_const<T const&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_volatile
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_volatile<T volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T*&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T* const&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T* volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T* const volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
# else
|
||||
|
||||
typedef char (&inner_yes_type)[3];
|
||||
typedef char (&inner_no_type)[2];
|
||||
typedef char (&outer_no_type)[1];
|
||||
|
||||
template <typename V>
|
||||
struct is_const_help
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_const<V>::value
|
||||
, inner_yes_type
|
||||
, inner_no_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct is_volatile_help
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_volatile<V>::value
|
||||
, inner_yes_type
|
||||
, inner_no_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct is_pointer_help
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_pointer<V>::value
|
||||
, inner_yes_type
|
||||
, inner_no_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
typename is_const_help<V>::type reference_to_const_helper(V&);
|
||||
outer_no_type
|
||||
reference_to_const_helper(...);
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_const
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)));
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)));
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
typename is_volatile_help<V>::type reference_to_volatile_helper(V&);
|
||||
outer_no_type reference_to_volatile_helper(...);
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_volatile
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)));
|
||||
};
|
||||
|
||||
|
||||
template <typename V>
|
||||
typename is_pointer_help<V>::type reference_to_pointer_helper(V&);
|
||||
outer_no_type reference_to_pointer_helper(...);
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_pointer_helper(t)) == sizeof(inner_yes_type))
|
||||
);
|
||||
};
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // INDIRECT_TRAITS_DWA2002131_HPP
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
@@ -89,11 +89,14 @@ namespace detail {
|
||||
typedef void const_reference;
|
||||
};
|
||||
|
||||
struct reference_parameter_base {};
|
||||
|
||||
template <class T>
|
||||
class reference_parameter
|
||||
: public reference_parameter_base
|
||||
{
|
||||
typedef typename parameter_traits<T>::const_reference const_reference;
|
||||
public:
|
||||
typedef typename parameter_traits<T>::const_reference const_reference;
|
||||
reference_parameter(const_reference value)
|
||||
: value(value) {}
|
||||
operator const_reference() { return value; }
|
||||
@@ -101,6 +104,51 @@ namespace detail {
|
||||
const_reference value;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct unwrap_parameter
|
||||
{
|
||||
typedef typename boost::add_reference<T>::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unwrap_parameter<reference_parameter<T> >
|
||||
{
|
||||
typedef typename reference_parameter<T>::const_reference type;
|
||||
};
|
||||
# else
|
||||
template <bool is_wrapped>
|
||||
struct unwrap_parameter_helper
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::const_reference type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwrap_parameter_helper<false>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename add_reference<T>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unwrap_parameter
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, is_wrapped = (is_base_and_derived<T,reference_parameter_base>::value));
|
||||
|
||||
typedef typename unwrap_parameter_helper<
|
||||
is_wrapped
|
||||
>::template apply<T>::type type;
|
||||
};
|
||||
# endif
|
||||
|
||||
class extension_instance;
|
||||
class instance_holder_base;
|
||||
|
||||
|
||||
44
include/boost/python/detail/map_entry.hpp
Normal file
44
include/boost/python/detail/map_entry.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef MAP_ENTRY_DWA2002118_HPP
|
||||
# define MAP_ENTRY_DWA2002118_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// A trivial type that works well as the value_type of associative
|
||||
// vector maps
|
||||
template <class Key, class Value>
|
||||
struct map_entry
|
||||
{
|
||||
map_entry() {}
|
||||
map_entry(Key k) : key(k), value() {}
|
||||
map_entry(Key k, Value v) : key(k), value(v) {}
|
||||
|
||||
bool operator<(map_entry const& rhs) const
|
||||
{
|
||||
return this->key < rhs.key;
|
||||
}
|
||||
|
||||
Key key;
|
||||
Value value;
|
||||
};
|
||||
|
||||
template <class Key, class Value>
|
||||
bool operator<(map_entry<Key,Value> const& e, Key const& k)
|
||||
{
|
||||
return e.key < k;
|
||||
}
|
||||
|
||||
template <class Key, class Value>
|
||||
bool operator<(Key const& k, map_entry<Key,Value> const& e)
|
||||
{
|
||||
return k < e.key;
|
||||
}
|
||||
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // MAP_ENTRY_DWA2002118_HPP
|
||||
99
include/boost/python/detail/msvc_typeinfo.hpp
Normal file
99
include/boost/python/detail/msvc_typeinfo.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// 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 MSVC_TYPEINFO_DWA200222_HPP
|
||||
# define MSVC_TYPEINFO_DWA200222_HPP
|
||||
|
||||
#include <boost/type.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
//
|
||||
// Fix for MSVC's broken typeid() implementation which doesn't strip
|
||||
// decoration. This fix doesn't handle cv-qualified array types. It
|
||||
// could probably be done, but I haven't figured it out yet.
|
||||
//
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
typedef std::type_info const& typeinfo;
|
||||
|
||||
template<int>struct value_id_accessor;
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<0>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<1>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T const*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<2>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T volatile*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<3>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T const volatile*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template <bool> struct bool_t{};
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_nonref(boost::type<T>* = 0)
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
|
||||
return value_id_accessor<(2 * v + c)>::get((T*)0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_ref(boost::type<T>*, ...)
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class U, class T>
|
||||
inline typeinfo typeid_ref(boost::type<U>*, T& (*)())
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_array(bool_t<false>, boost::type<T>* = 0)
|
||||
{
|
||||
typedef T (*x)();
|
||||
return typeid_ref((boost::type<T>*)0, x(0));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_array(bool_t<true>, boost::type<T>* = 0)
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo msvc_typeid(boost::type<T>* = 0)
|
||||
{
|
||||
typedef bool_t<is_array<T>::value> tag;
|
||||
return typeid_array(tag(), (boost::type<T>*)0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
# endif // BOOST_MSVC
|
||||
#endif // MSVC_TYPEINFO_DWA200222_HPP
|
||||
183
include/boost/python/detail/python_library_include.hpp
Normal file
183
include/boost/python/detail/python_library_include.hpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#error obsolete
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2000
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_libary_include.hpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers.
|
||||
* Note this is an internal header file included
|
||||
* by regex.hpp, do not include on its own.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
#define BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
#ifndef BOOST_REGEX_NO_LIB
|
||||
|
||||
#if defined(BOOST_MSVC) && !defined(BOOST_REGEX_BUILD_DLL)
|
||||
#ifdef __SGI_STL_PORT
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#if defined(_DEBUG) && defined(__STL_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300ddl.lib")
|
||||
#elif defined(_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc6-stlport-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc6-stlport-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#if defined(_DEBUG) && defined(__STL_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300ddm.lib")
|
||||
#elif defined(_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-stlport-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
// STLPort does not support single threaded builds:
|
||||
#error STLPort does not support single threaded builds
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#elif _MSC_VER < 1300
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc6-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc6-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300d.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-re300.lib")
|
||||
#endif //_DEBUG
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#else
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc7-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc7-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc7-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300d.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc7-re300.lib")
|
||||
#endif //_DEBUG
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#endif // __SGI_STL_PORT
|
||||
#endif //BOOST_MSVC
|
||||
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(BOOST_REGEX_BUILD_DLL)
|
||||
|
||||
#if __BORLANDC__ < 0x550
|
||||
|
||||
#ifdef BOOST_REGEX_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "bcb4re300lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "bcb4re300v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb4re300lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb4re300l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb4re300m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb4re300.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#else // C++ Builder 5:
|
||||
|
||||
#ifdef BOOST_REGEX_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "bcb5re300lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "bcb5re300v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb5re300lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb5re300l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb5re300m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb5re300.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#endif
|
||||
|
||||
#endif //__BORLANDC__
|
||||
|
||||
#endif //BOOST_REGEX_NO_LIB
|
||||
|
||||
#endif // BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
1338
include/boost/python/detail/returning.hpp
Normal file
1338
include/boost/python/detail/returning.hpp
Normal file
File diff suppressed because it is too large
Load Diff
217
include/boost/python/detail/signature.hpp
Normal file
217
include/boost/python/detail/signature.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
// (C) 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.
|
||||
//
|
||||
// This work was funded in part by Lawrence Berkeley and Lawrence
|
||||
// Livermore National Labs
|
||||
//
|
||||
// This file generated for 5-argument member functions and 6-argument free
|
||||
// functions by gen_signature.py
|
||||
|
||||
#ifndef SIGNATURE_DWA2002128_HPP
|
||||
# define SIGNATURE_DWA2002128_HPP
|
||||
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class R>
|
||||
mpl::type_list<R>
|
||||
signature(R (*)())
|
||||
{
|
||||
return mpl::type_list<R>();
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
mpl::type_list<R,A0>
|
||||
signature(R (*)(A0))
|
||||
{
|
||||
return mpl::type_list<R,A0>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
mpl::type_list<R,A0,A1>
|
||||
signature(R (*)(A0, A1))
|
||||
{
|
||||
return mpl::type_list<R,A0,A1>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
mpl::type_list<R,A0,A1,A2>
|
||||
signature(R (*)(A0, A1, A2))
|
||||
{
|
||||
return mpl::type_list<R,A0,A1,A2>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
mpl::type_list<R,A0,A1,A2,A3>
|
||||
signature(R (*)(A0, A1, A2, A3))
|
||||
{
|
||||
return mpl::type_list<R,A0,A1,A2,A3>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
mpl::type_list<R,A0,A1,A2,A3,A4>
|
||||
signature(R (*)(A0, A1, A2, A3, A4))
|
||||
{
|
||||
return mpl::type_list<R,A0,A1,A2,A3,A4>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
mpl::type_list<R,A0,A1,A2,A3,A4,A5>
|
||||
signature(R (*)(A0, A1, A2, A3, A4, A5))
|
||||
{
|
||||
return mpl::type_list<R,A0,A1,A2,A3,A4,A5>();
|
||||
}
|
||||
template <class R, class A0>
|
||||
mpl::type_list<R,A0&> signature(R (A0::*)())
|
||||
{
|
||||
return mpl::type_list<R,A0&>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
mpl::type_list<R,A0&,A1> signature(R (A0::*)(A1))
|
||||
{
|
||||
return mpl::type_list<R,A0&,A1>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
mpl::type_list<R,A0&,A1,A2> signature(R (A0::*)(A1, A2))
|
||||
{
|
||||
return mpl::type_list<R,A0&,A1,A2>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
mpl::type_list<R,A0&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3))
|
||||
{
|
||||
return mpl::type_list<R,A0&,A1,A2,A3>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
mpl::type_list<R,A0&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4))
|
||||
{
|
||||
return mpl::type_list<R,A0&,A1,A2,A3,A4>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
mpl::type_list<R,A0&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5))
|
||||
{
|
||||
return mpl::type_list<R,A0&,A1,A2,A3,A4,A5>();
|
||||
}
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
mpl::type_list<R,A0 const&> signature(R (A0::*)() const)
|
||||
{
|
||||
return mpl::type_list<R,A0 const&>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
mpl::type_list<R,A0 const&,A1> signature(R (A0::*)(A1) const)
|
||||
{
|
||||
return mpl::type_list<R,A0 const&,A1>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
mpl::type_list<R,A0 const&,A1,A2> signature(R (A0::*)(A1, A2) const)
|
||||
{
|
||||
return mpl::type_list<R,A0 const&,A1,A2>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
mpl::type_list<R,A0 const&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3) const)
|
||||
{
|
||||
return mpl::type_list<R,A0 const&,A1,A2,A3>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
mpl::type_list<R,A0 const&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4) const)
|
||||
{
|
||||
return mpl::type_list<R,A0 const&,A1,A2,A3,A4>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
mpl::type_list<R,A0 const&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5) const)
|
||||
{
|
||||
return mpl::type_list<R,A0 const&,A1,A2,A3,A4,A5>();
|
||||
}
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
mpl::type_list<R,A0 volatile&> signature(R (A0::*)() volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 volatile&>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
mpl::type_list<R,A0 volatile&,A1> signature(R (A0::*)(A1) volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 volatile&,A1>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
mpl::type_list<R,A0 volatile&,A1,A2> signature(R (A0::*)(A1, A2) volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 volatile&,A1,A2>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
mpl::type_list<R,A0 volatile&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3) volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 volatile&,A1,A2,A3>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
mpl::type_list<R,A0 volatile&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4) volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 volatile&,A1,A2,A3,A4>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
mpl::type_list<R,A0 volatile&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5) volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 volatile&,A1,A2,A3,A4,A5>();
|
||||
}
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
mpl::type_list<R,A0 const volatile&> signature(R (A0::*)() const volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 const volatile&>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
mpl::type_list<R,A0 const volatile&,A1> signature(R (A0::*)(A1) const volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 const volatile&,A1>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
mpl::type_list<R,A0 const volatile&,A1,A2> signature(R (A0::*)(A1, A2) const volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 const volatile&,A1,A2>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
mpl::type_list<R,A0 const volatile&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3) const volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 const volatile&,A1,A2,A3>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4) const volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4>();
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5) const volatile)
|
||||
{
|
||||
return mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4,A5>();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // SIGNATURE_DWA2002128_HPP
|
||||
|
||||
16
include/boost/python/detail/type_list.hpp
Normal file
16
include/boost/python/detail/type_list.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// 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 TYPE_LIST_DWA200222_HPP
|
||||
# define TYPE_LIST_DWA200222_HPP
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct empty_list : boost::mpl::type_list<>::type {};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // TYPE_LIST_DWA200222_HPP
|
||||
@@ -31,12 +31,8 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class string;
|
||||
|
||||
namespace detail {
|
||||
|
||||
class instance_holder_base;
|
||||
|
||||
class BOOST_PYTHON_DECL type_object_base : public python_type
|
||||
{
|
||||
public:
|
||||
|
||||
156
include/boost/python/detail/unwind_type.hpp
Normal file
156
include/boost/python/detail/unwind_type.hpp
Normal file
@@ -0,0 +1,156 @@
|
||||
// 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 UNWIND_TYPE_DWA200222_HPP
|
||||
# define UNWIND_TYPE_DWA200222_HPP
|
||||
|
||||
# include <boost/python/detail/cv_category.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
|
||||
{
|
||||
return Generator::execute(p);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U const* p, const_, Generator* = 0)
|
||||
{
|
||||
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
|
||||
{
|
||||
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
|
||||
{
|
||||
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_ptr_type(U* p, Generator* = 0)
|
||||
{
|
||||
typedef typename cv_category<U>::type tag;
|
||||
return unwind_type_cv<Generator>(p, tag());
|
||||
}
|
||||
|
||||
template <bool is_ptr>
|
||||
struct unwind_helper
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U p, Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type(p, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper<false>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U& p, Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type(&p, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type(U& p, Generator* = 0)
|
||||
{
|
||||
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type(U const& p, Generator* = 0)
|
||||
{
|
||||
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
|
||||
}
|
||||
|
||||
enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
|
||||
template <int indirection> struct unwind_helper2;
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<direct_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<pointer_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U*(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<reference_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U&(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<reference_to_pointer_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U&(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type(U(0), (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
// Call this one with both template parameters explicitly specified
|
||||
// and no function arguments:
|
||||
//
|
||||
// return unwind_type<my_generator,T>();
|
||||
//
|
||||
// Doesn't work if T is an array type; we could handle that case, but
|
||||
// why bother?
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type(type<U>*p = 0, Generator* = 0)
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, indirection
|
||||
= (is_pointer<U>::value ? pointer_ : 0)
|
||||
+ (is_reference_to_pointer<U>::value
|
||||
? reference_to_pointer_
|
||||
: is_reference<U>::value
|
||||
? reference_
|
||||
: 0));
|
||||
|
||||
return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // UNWIND_TYPE_DWA200222_HPP
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
BOOST_PYTHON_DECL extern PyObject arbitrary_object;
|
||||
extern BOOST_PYTHON_DECL PyObject arbitrary_object;
|
||||
|
||||
template <class T>
|
||||
struct void_adaptor
|
||||
|
||||
56
include/boost/python/detail/wrap_function.hpp
Normal file
56
include/boost/python/detail/wrap_function.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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 WRAP_FUNCTION_DWA2002118_HPP
|
||||
# define WRAP_FUNCTION_DWA2002118_HPP
|
||||
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/type_traits/ice.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// A function which converts its argument into a Python callable
|
||||
// object. Not very general yet!
|
||||
|
||||
// This should eventually be replaced with a mechanism for specialized
|
||||
// wrap/unwrap objects. In other words, to_python(f), where f is a
|
||||
// function pointer or function type, should produce a callable Python
|
||||
// object.
|
||||
|
||||
template <bool needs_wrapping>
|
||||
struct wrap_function_select
|
||||
{
|
||||
template <class F>
|
||||
static objects::function* execute(F f)
|
||||
{
|
||||
return make_function(f);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct wrap_function_select<false>
|
||||
{
|
||||
template <class F>
|
||||
static F execute(F f)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
template <class F>
|
||||
PyObject* wrap_function(F f)
|
||||
{
|
||||
return wrap_function_select<
|
||||
type_traits::ice_or<
|
||||
is_function<F>::value
|
||||
, is_member_function_pointer<F>::value
|
||||
>::value >::execute(f);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // WRAP_FUNCTION_DWA2002118_HPP
|
||||
@@ -34,36 +34,38 @@
|
||||
// Some things we need in order to get Python.h to work with compilers other
|
||||
// than MSVC on Win32
|
||||
//
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# if defined(__GNUC__) && defined(__CYGWIN__)
|
||||
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2
|
||||
typedef int pid_t;
|
||||
# define WORD_BIT 32
|
||||
# define hypot _hypot
|
||||
# include <stdio.h>
|
||||
# if PY_MAJOR_VERSION < 2
|
||||
# define HAVE_CLOCK
|
||||
# define HAVE_STRFTIME
|
||||
# define HAVE_STRERROR
|
||||
# endif
|
||||
# define NT_THREADS
|
||||
# if __GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3
|
||||
# define WITH_THREAD
|
||||
# endif
|
||||
# ifndef NETSCAPE_PI
|
||||
# define USE_SOCKET
|
||||
# endif
|
||||
|
||||
# ifdef USE_DL_IMPORT
|
||||
# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
|
||||
# endif
|
||||
|
||||
# ifdef USE_DL_EXPORT
|
||||
# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
|
||||
# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
|
||||
# endif
|
||||
|
||||
# define HAVE_LONG_LONG 1
|
||||
# define LONG_LONG long long
|
||||
# endif
|
||||
# if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2
|
||||
# define HAVE_CLOCK
|
||||
# define HAVE_STRFTIME
|
||||
# define HAVE_STRERROR
|
||||
# endif
|
||||
# define NT_THREADS
|
||||
# define WITH_THREAD
|
||||
# ifndef NETSCAPE_PI
|
||||
# define USE_SOCKET
|
||||
# endif
|
||||
|
||||
# ifdef USE_DL_IMPORT
|
||||
# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
|
||||
# endif
|
||||
|
||||
# ifdef USE_DL_EXPORT
|
||||
# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
|
||||
# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
|
||||
# endif
|
||||
|
||||
# define HAVE_LONG_LONG 1
|
||||
# define LONG_LONG long long
|
||||
|
||||
# elif defined(__MWERKS__)
|
||||
|
||||
|
||||
@@ -9,57 +9,31 @@
|
||||
#ifndef ERRORS_DWA052500_H_
|
||||
# define ERRORS_DWA052500_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/function.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
struct error_already_set {};
|
||||
struct argument_error : error_already_set {};
|
||||
|
||||
struct object_functor_base
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
virtual PyObject* operator()() const = 0;
|
||||
private:
|
||||
static void* operator new(std::size_t); // don't allow dynamic allocation
|
||||
void operator delete(void*);
|
||||
void operator delete(void*, size_t);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct object_functor : object_functor_base
|
||||
{
|
||||
object_functor(T const& f)
|
||||
: m_f(f)
|
||||
{
|
||||
}
|
||||
|
||||
PyObject* operator()() const
|
||||
{
|
||||
return m_f();
|
||||
}
|
||||
private:
|
||||
T const& m_f;
|
||||
};
|
||||
|
||||
|
||||
// Handles exceptions caught just before returning to Python code.
|
||||
PyObject* handle_exception_impl(object_functor_base const& f);
|
||||
// Returns true iff an exception was caught.
|
||||
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>);
|
||||
|
||||
template <class T>
|
||||
PyObject* handle_exception(T const& f)
|
||||
bool handle_exception(T f)
|
||||
{
|
||||
return handle_exception_impl(object_functor<T>(f));
|
||||
return handle_exception_impl(function0<void>(boost::ref(f)));
|
||||
}
|
||||
|
||||
void handle_exception(void (*)());
|
||||
BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x);
|
||||
|
||||
template <class T>
|
||||
T* expect_non_null(T* x)
|
||||
{
|
||||
if (x == 0)
|
||||
throw error_already_set();
|
||||
return x;
|
||||
return (T*)expect_non_null((PyObject*)x);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
42
include/boost/python/from_python.hpp
Normal file
42
include/boost/python/from_python.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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_DWA2002128_HPP
|
||||
# define FROM_PYTHON_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/converter/target.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
struct from_python
|
||||
: converter::from_python_lookup<typename converter::target<T>::type>
|
||||
{
|
||||
typedef converter::from_python_lookup<typename converter::target<T>::type> base;
|
||||
from_python(PyObject*);
|
||||
};
|
||||
|
||||
// specialization for PyObject*
|
||||
template <>
|
||||
struct from_python<PyObject*>
|
||||
{
|
||||
from_python(PyObject*) {}
|
||||
bool convertible() const { return true; }
|
||||
PyObject* operator()(PyObject* source) const { return source; }
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
from_python<T>::from_python(PyObject* source)
|
||||
: base(source)
|
||||
{
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // FROM_PYTHON_DWA2002128_HPP
|
||||
54
include/boost/python/make_function.hpp
Normal file
54
include/boost/python/make_function.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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 MAKE_FUNCTION_DWA20011221_HPP
|
||||
# define MAKE_FUNCTION_DWA20011221_HPP
|
||||
|
||||
# include <boost/python/object/function.hpp>
|
||||
# include <boost/python/object/make_holder.hpp>
|
||||
# include <boost/python/detail/caller.hpp>
|
||||
# include <boost/python/detail/arg_tuple_size.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/function.hpp>
|
||||
# include <boost/bind.hpp>
|
||||
# include <boost/python/default_call_policies.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class F>
|
||||
objects::function* make_function(F f)
|
||||
{
|
||||
return new objects::function(
|
||||
objects::py_function(
|
||||
::boost::bind<PyObject*>(detail::caller(), f, _1, _2, default_call_policies()))
|
||||
, detail::arg_tuple_size<F>::value);
|
||||
}
|
||||
|
||||
template <class F, class Policies>
|
||||
objects::function* make_function(F f, Policies const& policies)
|
||||
{
|
||||
return new objects::function(
|
||||
objects::py_function(
|
||||
::boost::bind<PyObject*>(detail::caller(), f, _1, _2, policies))
|
||||
, detail::arg_tuple_size<F>::value);
|
||||
}
|
||||
|
||||
template <class T, class ArgList, class Generator>
|
||||
objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0)
|
||||
{
|
||||
enum { nargs = mpl::size<ArgList>::value };
|
||||
|
||||
return new objects::function(
|
||||
objects::py_function(
|
||||
::boost::bind<PyObject*>(detail::caller(),
|
||||
objects::make_holder<nargs>
|
||||
::template apply<T,Generator,ArgList>::execute
|
||||
, _1, _2, default_call_policies()))
|
||||
, nargs + 1);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // MAKE_FUNCTION_DWA20011221_HPP
|
||||
42
include/boost/python/manage_new_object.hpp
Normal file
42
include/boost/python/manage_new_object.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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 MANAGE_NEW_OBJECT_DWA200222_HPP
|
||||
# define MANAGE_NEW_OBJECT_DWA200222_HPP
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct manage_new_object_requires_a_pointer_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
struct manage_new_object
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
boost::is_pointer<T>::value
|
||||
, to_python_indirect<T, detail::make_owning_holder>
|
||||
, detail::manage_new_object_requires_a_pointer_return_type<T>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // MANAGE_NEW_OBJECT_DWA200222_HPP
|
||||
110
include/boost/python/module.hpp
Normal file
110
include/boost/python/module.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
// 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 MODULE_DWA2001128_HPP
|
||||
# define MODULE_DWA2001128_HPP
|
||||
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/objects.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/class_fwd.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class BOOST_PYTHON_DECL module_base
|
||||
{
|
||||
public:
|
||||
// Create a module. REQUIRES: only one module is created per module.
|
||||
module_base(const char* name);
|
||||
~module_base();
|
||||
|
||||
// Add elements to the module
|
||||
void setattr(const char* name, PyObject*);
|
||||
void setattr(const char* name, ref const&);
|
||||
void add(PyTypeObject* x); // just use the type's name
|
||||
void add_type(ref);
|
||||
|
||||
// Return a reference to the Python module object being built
|
||||
ref module() const;
|
||||
|
||||
private:
|
||||
ref m_module;
|
||||
static PyMethodDef initial_methods[1];
|
||||
};
|
||||
|
||||
class module : public module_base
|
||||
{
|
||||
public:
|
||||
module(const char* name)
|
||||
: module_base(name) {}
|
||||
|
||||
// Add elements to the module
|
||||
module& setattr(const char* name, PyObject*);
|
||||
module& setattr(const char* name, PyTypeObject*);
|
||||
module& setattr(const char* name, ref const&);
|
||||
module& add(PyTypeObject* x); // just use the type's name
|
||||
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
module& add(class_<T,Bases,HolderGenerator> const& c)
|
||||
{
|
||||
Py_INCREF(c.object());
|
||||
this->add_type(c.object());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
module& def(char const* name, Fn fn)
|
||||
{
|
||||
this->setattr(name, boost::python::make_function(fn));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class Fn, class ResultHandler>
|
||||
module& def(char const* name, Fn fn, ResultHandler handler)
|
||||
{
|
||||
this->setattr(name, boost::python::make_function(fn, handler));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// inline implementations
|
||||
//
|
||||
inline ref module_base::module() const
|
||||
{
|
||||
return m_module;
|
||||
}
|
||||
|
||||
inline module& module::setattr(const char* name, PyObject* x)
|
||||
{
|
||||
this->module_base::setattr(name, x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline module& module::setattr(const char* name, PyTypeObject* x)
|
||||
{
|
||||
this->module_base::setattr(name, (PyObject*)x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline module& module::setattr(const char* name, ref const& x)
|
||||
{
|
||||
this->module_base::setattr(name, x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline module& module::add(PyTypeObject* x)
|
||||
{
|
||||
this->module_base::add(x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // MODULE_DWA20011221_HPP
|
||||
@@ -16,30 +16,18 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class module_builder
|
||||
class BOOST_PYTHON_DECL module_builder_base
|
||||
{
|
||||
public:
|
||||
// Create a module. REQUIRES: only one module_builder is created per module.
|
||||
module_builder(const char* name);
|
||||
~module_builder();
|
||||
module_builder_base(const char* name);
|
||||
~module_builder_base();
|
||||
|
||||
// Add elements to the module
|
||||
void add(detail::function* x, const char* name);
|
||||
void add(PyTypeObject* x, const char* name = 0);
|
||||
void add(ref x, const char*name);
|
||||
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
void def(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_wrapped_function(fn), name);
|
||||
}
|
||||
|
||||
// Return true iff a module is currently being built.
|
||||
static bool initializing();
|
||||
|
||||
@@ -55,10 +43,29 @@ class module_builder
|
||||
static PyMethodDef initial_methods[1];
|
||||
};
|
||||
|
||||
class module_builder : public module_builder_base
|
||||
{
|
||||
public:
|
||||
module_builder(const char* name)
|
||||
: module_builder_base(name) {}
|
||||
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
void def(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_wrapped_function(fn), name);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// inline implementations
|
||||
//
|
||||
inline PyObject* module_builder::module() const
|
||||
inline PyObject* module_builder_base::module() const
|
||||
{
|
||||
return m_module;
|
||||
}
|
||||
|
||||
23
include/boost/python/object/auto_ptr_generator.hpp
Normal file
23
include/boost/python/object/auto_ptr_generator.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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 AUTO_PTR_GENERATOR_DWA2002123_HPP
|
||||
# define AUTO_PTR_GENERATOR_DWA2002123_HPP
|
||||
# include <memory>
|
||||
|
||||
namespace boost { namespace python { namespace object {
|
||||
|
||||
struct auto_ptr_generator
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef std::auto_ptr<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // AUTO_PTR_GENERATOR_DWA2002123_HPP
|
||||
111
include/boost/python/object/class.hpp
Normal file
111
include/boost/python/object/class.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CLASS_DWA20011214_HPP
|
||||
# define CLASS_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/module.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/iterator_adaptors.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class module;
|
||||
|
||||
namespace objects {
|
||||
|
||||
template <class T> struct holder;
|
||||
|
||||
// To identify a class, we don't need cv/reference decorations
|
||||
typedef converter::undecorated_type_id_t class_id;
|
||||
|
||||
struct BOOST_PYTHON_DECL class_base : noncopyable
|
||||
{
|
||||
// constructor
|
||||
class_base(
|
||||
char const* name // The name of the class
|
||||
|
||||
, std::size_t num_types // A list of class_ids. The first is the type
|
||||
, class_id const*const types // this is wrapping. The rest are the types of
|
||||
// any bases.
|
||||
);
|
||||
|
||||
// Retrieve the underlying object
|
||||
ref object() const { return m_object; }
|
||||
private:
|
||||
ref m_object;
|
||||
};
|
||||
|
||||
// Base class for all holders
|
||||
struct BOOST_PYTHON_DECL instance_holder : noncopyable
|
||||
{
|
||||
public:
|
||||
instance_holder();
|
||||
virtual ~instance_holder();
|
||||
|
||||
// return the next holder in a chain
|
||||
instance_holder* next() const;
|
||||
|
||||
virtual void* holds(converter::type_id_t) = 0;
|
||||
|
||||
void install(PyObject* inst) throw();
|
||||
|
||||
struct iterator_policies : default_iterator_policies
|
||||
{
|
||||
template <class Iterator>
|
||||
void increment(Iterator& p)
|
||||
{
|
||||
p.base() = p.base()->next();
|
||||
}
|
||||
};
|
||||
|
||||
typedef iterator_adaptor<
|
||||
instance_holder*
|
||||
, iterator_policies
|
||||
, value_type_is<noncopyable>
|
||||
, reference_is<instance_holder&>
|
||||
, pointer_is<instance_holder*>
|
||||
, iterator_category_is<std::input_iterator_tag> > iterator;
|
||||
|
||||
private:
|
||||
instance_holder* m_next;
|
||||
};
|
||||
|
||||
// Each extension instance will be one of these
|
||||
struct instance
|
||||
{
|
||||
PyObject_HEAD
|
||||
instance_holder* objects;
|
||||
};
|
||||
|
||||
// Given a type_id, find the instance data which corresponds to it, or
|
||||
// return 0 in case no such type is held.
|
||||
BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t);
|
||||
|
||||
template <class T>
|
||||
T* find_instance(PyObject* p, T* = 0)
|
||||
{
|
||||
return static_cast<T*>(find_instance_impl(p, converter::type_id<T>()));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL ref class_metatype();
|
||||
BOOST_PYTHON_DECL ref class_type();
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
inline instance_holder* instance_holder::next() const
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // CLASS_DWA20011214_HPP
|
||||
102
include/boost/python/object/class_converters.hpp
Normal file
102
include/boost/python/object/class_converters.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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_CONVERTERS_DWA2002119_HPP
|
||||
# define CLASS_CONVERTERS_DWA2002119_HPP
|
||||
|
||||
# include <boost/python/converter/class.hpp>
|
||||
# include <boost/python/object/class_wrapper.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
// Instantiating this class brings into existence all converters
|
||||
// associated with a class Bases is expected to be an mpl sequence of
|
||||
// base types.
|
||||
template <class Derived, class Bases>
|
||||
struct class_converters
|
||||
{
|
||||
public: // member functions
|
||||
// Constructor takes the python class object associated with T
|
||||
class_converters(ref const& python_class);
|
||||
|
||||
private: // data members
|
||||
converter::class_from_python_converter<Derived> m_unwrapper;
|
||||
class_wrapper<Derived> m_wrapper;
|
||||
};
|
||||
|
||||
//
|
||||
// Implementation details
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// register_base_of<T> -
|
||||
// A BinaryMetaFunction object which registers a single base
|
||||
// class of T, and the corresponding cast(s)
|
||||
//
|
||||
|
||||
|
||||
// register_downcast/do_nothing -
|
||||
// Helpers for register_base_of<> which take care of registering
|
||||
// down-casts
|
||||
template <class Base, class Derived>
|
||||
struct register_downcast
|
||||
{
|
||||
static void execute()
|
||||
{
|
||||
register_conversion<Base, Derived>(true);
|
||||
}
|
||||
};
|
||||
|
||||
struct do_nothing
|
||||
{
|
||||
static void execute() { }
|
||||
};
|
||||
|
||||
// Here's where the real work gets done:
|
||||
template <class Derived>
|
||||
struct register_base_of
|
||||
{
|
||||
// Ignored is needed because mpl::for_each is still actually
|
||||
// accumulate. We're not using any state so it just sits there.
|
||||
template <class Ignored, class Base>
|
||||
struct apply
|
||||
{
|
||||
typedef void type; // 'type' needs to be defined for the same reasons
|
||||
|
||||
// Here's the runtime part:
|
||||
static void execute()
|
||||
{
|
||||
// Register the Base class
|
||||
register_dynamic_id<Base>();
|
||||
// Register the up-cast
|
||||
register_conversion<Derived,Base>(false);
|
||||
|
||||
// Register the down-cast, if appropriate.
|
||||
mpl::select_type<
|
||||
is_polymorphic<Base>::value
|
||||
, register_downcast<Base,Derived>
|
||||
, do_nothing
|
||||
>::type::execute();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Bases>
|
||||
class_converters<Derived,Bases>::class_converters(ref const& type_object)
|
||||
: m_wrapper(type_object)
|
||||
{
|
||||
// register all up/downcasts here
|
||||
register_dynamic_id<Derived>();
|
||||
|
||||
// register each base in the sequence
|
||||
mpl::for_each<Bases, void, register_base_of<Derived> >::execute();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // CLASS_CONVERTERS_DWA2002119_HPP
|
||||
26
include/boost/python/object/class_object.hpp
Normal file
26
include/boost/python/object/class_object.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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_OBJECT_DWA200222_HPP
|
||||
# define CLASS_OBJECT_DWA200222_HPP
|
||||
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class T>
|
||||
struct class_object
|
||||
{
|
||||
static PyTypeObject*& reference;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
PyTypeObject*& class_object<T>::reference = converter::registry::class_object(
|
||||
converter::undecorated_type_id<T>());
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // CLASS_OBJECT_DWA200222_HPP
|
||||
61
include/boost/python/object/class_wrapper.hpp
Normal file
61
include/boost/python/object/class_wrapper.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CLASS_WRAPPER_DWA20011221_HPP
|
||||
# define CLASS_WRAPPER_DWA20011221_HPP
|
||||
|
||||
# include <boost/python/object/value_holder.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/to_python_converter.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class T>
|
||||
struct class_wrapper
|
||||
: to_python_converter<T, class_wrapper<T> >
|
||||
{
|
||||
class_wrapper(ref const& type_)
|
||||
: m_class_object_keeper(type_)
|
||||
{
|
||||
assert(type_->ob_type == (PyTypeObject*)class_metatype().get());
|
||||
m_class_object = (PyTypeObject*)type_.get();
|
||||
}
|
||||
|
||||
static PyObject* convert(T const& x)
|
||||
{
|
||||
// Don't call the type directly to do the construction, since
|
||||
// that would require the registration of an appropriate
|
||||
// __init__ function.
|
||||
PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0);
|
||||
|
||||
if (raw_result == 0)
|
||||
return 0;
|
||||
|
||||
// Everything's OK; Bypass NULL checks but guard against
|
||||
// exceptions.
|
||||
ref result(raw_result, ref::allow_null());
|
||||
|
||||
// Build a value_holder to contain the object using the copy
|
||||
// constructor
|
||||
value_holder<T>* p = new value_holder<T>(raw_result, cref(x));
|
||||
|
||||
// Install it in the instance
|
||||
p->install(raw_result);
|
||||
|
||||
// Return the new result
|
||||
return result.release();
|
||||
}
|
||||
|
||||
private:
|
||||
ref m_class_object_keeper;
|
||||
static PyTypeObject* m_class_object;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
PyTypeObject* class_wrapper<T>::m_class_object;
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // CLASS_WRAPPER_DWA20011221_HPP
|
||||
24
include/boost/python/object/construct.hpp
Normal file
24
include/boost/python/object/construct.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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 CONSTRUCT_DWA20011215_HPP
|
||||
# define CONSTRUCT_DWA20011215_HPP
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class T, class ArgList>
|
||||
struct construct
|
||||
{
|
||||
static
|
||||
template <class
|
||||
void operator()(PyObject* args, PyObject* keywords)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // CONSTRUCT_DWA20011215_HPP
|
||||
37
include/boost/python/object/forward.hpp
Normal file
37
include/boost/python/object/forward.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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 FORWARD_DWA20011215_HPP
|
||||
# define FORWARD_DWA20011215_HPP
|
||||
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
// A little metaprogram which selects the type to pass through an
|
||||
// intermediate forwarding function when the destination argument type
|
||||
// is T.
|
||||
template <class T>
|
||||
struct forward
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, by_value = (is_scalar<T>::value | is_reference<T>::value)
|
||||
);
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
by_value
|
||||
, T
|
||||
, reference_wrapper<
|
||||
typename add_const<T>::type
|
||||
>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // FORWARD_DWA20011215_HPP
|
||||
51
include/boost/python/object/function.hpp
Normal file
51
include/boost/python/object/function.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// 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 FUNCTION_DWA20011214_HPP
|
||||
# define FUNCTION_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/function.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
// We use boost::function to avoid generating lots of virtual tables
|
||||
typedef boost::function2<PyObject*, PyObject*, PyObject*> py_function;
|
||||
|
||||
struct BOOST_PYTHON_DECL function : PyObject
|
||||
{
|
||||
function(py_function, unsigned min_args, unsigned max_args = 0);
|
||||
~function();
|
||||
|
||||
PyObject* call(PyObject*, PyObject*) const;
|
||||
|
||||
// Add an attributeto the name_space with the given name. If it is
|
||||
// a function object (this class), and an existing function is
|
||||
// already there, add it as an overload.
|
||||
static void add_to_namespace(
|
||||
ref const& name_space, char const* name, ref const& attribute);
|
||||
|
||||
private: // helper functions
|
||||
void argument_error(PyObject* args, PyObject* keywords) const;
|
||||
void add_overload(function*);
|
||||
|
||||
private: // data members
|
||||
py_function m_fn;
|
||||
unsigned m_min_args;
|
||||
unsigned m_max_args;
|
||||
function* m_overloads;
|
||||
};
|
||||
|
||||
extern BOOST_PYTHON_DECL PyTypeObject function_type;
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // FUNCTION_DWA20011214_HPP
|
||||
165
include/boost/python/object/inheritance.hpp
Normal file
165
include/boost/python/object/inheritance.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
// 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 INHERITANCE_DWA200216_HPP
|
||||
# define INHERITANCE_DWA200216_HPP
|
||||
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
typedef converter::undecorated_type_id_t class_id;
|
||||
using converter::undecorated_type_id;
|
||||
|
||||
// Types used to get address and id of most derived type
|
||||
typedef std::pair<void*,class_id> dynamic_id_t;
|
||||
typedef dynamic_id_t (*dynamic_id_function)(void*);
|
||||
|
||||
BOOST_PYTHON_DECL void register_dynamic_id_aux(
|
||||
class_id static_id, dynamic_id_function get_dynamic_id);
|
||||
|
||||
BOOST_PYTHON_DECL void add_cast(
|
||||
class_id src_t, class_id dst_t, void* (*cast)(void*), bool polymorphic);
|
||||
|
||||
BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst);
|
||||
|
||||
BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst);
|
||||
|
||||
// is_polymorphic test from John Maddock
|
||||
template <class T>
|
||||
struct is_polymorphic
|
||||
{
|
||||
struct d1 : public T
|
||||
{
|
||||
d1();
|
||||
char padding[256];
|
||||
};
|
||||
struct d2 : public T
|
||||
{
|
||||
d2();
|
||||
virtual ~d2();
|
||||
virtual void foo();
|
||||
char padding[256];
|
||||
};
|
||||
BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1)));
|
||||
};
|
||||
|
||||
//
|
||||
// a generator with an execute() function which, given a source type
|
||||
// and a pointer to an object of that type, returns its most-derived
|
||||
// /reachable/ type identifier and object pointer.
|
||||
//
|
||||
|
||||
// first, the case where T has virtual functions
|
||||
template <class T>
|
||||
struct polymorphic_id_generator
|
||||
{
|
||||
static dynamic_id_t execute(void* p_)
|
||||
{
|
||||
T* p = static_cast<T*>(p_);
|
||||
return std::make_pair(dynamic_cast<void*>(p), class_id(typeid(*p)));
|
||||
}
|
||||
};
|
||||
|
||||
// now, the non-polymorphic case.
|
||||
template <class T>
|
||||
struct non_polymorphic_id_generator
|
||||
{
|
||||
static dynamic_id_t execute(void* p_)
|
||||
{
|
||||
return std::make_pair(p_, converter::undecorated_type_id<T>());
|
||||
}
|
||||
};
|
||||
|
||||
// Now the generalized selector
|
||||
template <class T>
|
||||
struct dynamic_id_generator
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_polymorphic<T>::value
|
||||
, polymorphic_id_generator<T>
|
||||
, non_polymorphic_id_generator<T> >::type type;
|
||||
};
|
||||
|
||||
// Register the dynamic id function for T with the type-conversion
|
||||
// system.
|
||||
template <class T>
|
||||
void register_dynamic_id(T* = 0)
|
||||
{
|
||||
typedef typename dynamic_id_generator<T>::type generator;
|
||||
register_dynamic_id_aux(
|
||||
converter::undecorated_type_id<T>(), &generator::execute);
|
||||
}
|
||||
|
||||
//
|
||||
// a generator with an execute() function which, given a void*
|
||||
// pointing to an object of type Source will attempt to convert it to
|
||||
// an object of type Target.
|
||||
//
|
||||
|
||||
template <class Source, class Target>
|
||||
struct dynamic_cast_generator
|
||||
{
|
||||
static void* execute(void* source)
|
||||
{
|
||||
return dynamic_cast<Target*>(
|
||||
static_cast<Source*>(source));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class Source, class Target>
|
||||
struct implicit_cast_generator
|
||||
{
|
||||
static void* execute(void* source)
|
||||
{
|
||||
Target* result = static_cast<Source*>(source);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Source, class Target>
|
||||
struct cast_generator
|
||||
{
|
||||
// CWPro7 will return false sometimes, but that's OK since we can
|
||||
// always cast up with dynamic_cast<>
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, is_upcast = (
|
||||
is_base_and_derived<Target,Source>::value
|
||||
));
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
is_upcast
|
||||
# if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
// grab a few more implicit_cast cases for CodeWarrior
|
||||
|| !is_polymorphic<Source>::value
|
||||
|| !is_polymorphic<Target>::value
|
||||
# endif
|
||||
, implicit_cast_generator<Source,Target>
|
||||
, dynamic_cast_generator<Source,Target>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Source, class Target>
|
||||
inline void register_conversion(
|
||||
// We need this parameter because CWPro7 can't determine
|
||||
// which is the base reliably.
|
||||
bool is_downcast = !cast_generator<Source,Target>::is_upcast
|
||||
|
||||
// These parameters shouldn't be used, they're an MSVC bug workaround
|
||||
, Source* = 0, Target* = 0)
|
||||
{
|
||||
typedef typename cast_generator<Source,Target>::type generator;
|
||||
|
||||
add_cast(converter::undecorated_type_id<Source>()
|
||||
, converter::undecorated_type_id<Target>()
|
||||
, &generator::execute
|
||||
, is_downcast);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // INHERITANCE_DWA200216_HPP
|
||||
17
include/boost/python/object/life_support.hpp
Normal file
17
include/boost/python/object/life_support.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// 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 LIFE_SUPPORT_DWA200222_HPP
|
||||
# define LIFE_SUPPORT_DWA200222_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient);
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // LIFE_SUPPORT_DWA200222_HPP
|
||||
176
include/boost/python/object/make_holder.hpp
Normal file
176
include/boost/python/object/make_holder.hpp
Normal file
@@ -0,0 +1,176 @@
|
||||
// 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 MAKE_HOLDER_DWA20011215_HPP
|
||||
# define MAKE_HOLDER_DWA20011215_HPP
|
||||
|
||||
# include <boost/mpl/at.hpp>
|
||||
# include <boost/python/object/forward.hpp>
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/eval.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <int nargs> struct make_holder;
|
||||
|
||||
template <>
|
||||
struct make_holder<0>
|
||||
{
|
||||
template <class T, class Generator, class ArgList>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<Generator,T>::type holder;
|
||||
static void execute(
|
||||
PyObject* p)
|
||||
{
|
||||
(new holder(p))->install(p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct make_holder<1>
|
||||
{
|
||||
template <class T, class Generator, class ArgList>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<Generator,T>::type holder;
|
||||
typedef typename mpl::at<0,ArgList>::type t0;
|
||||
typedef typename forward<t0>::type f0;
|
||||
|
||||
static void execute(
|
||||
PyObject* p
|
||||
, t0 a0)
|
||||
{
|
||||
(new holder(p, f0(a0)))->install(p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_holder<2>
|
||||
{
|
||||
template <class T, class Generator, class ArgList>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<Generator,T>::type holder;
|
||||
typedef typename mpl::at<0,ArgList>::type t0;
|
||||
typedef typename forward<t0>::type f0;
|
||||
typedef typename mpl::at<1,ArgList>::type t1;
|
||||
typedef typename forward<t1>::type f1;
|
||||
|
||||
static void execute(
|
||||
PyObject* p, t0 a0, t1 a1)
|
||||
{
|
||||
(new holder(p, f0(a0), f1(a1)))->install(p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_holder<3>
|
||||
{
|
||||
template <class T, class Generator, class ArgList>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<Generator,T>::type holder;
|
||||
typedef typename mpl::at<0,ArgList>::type t0;
|
||||
typedef typename forward<t0>::type f0;
|
||||
typedef typename mpl::at<1,ArgList>::type t1;
|
||||
typedef typename forward<t1>::type f1;
|
||||
typedef typename mpl::at<2,ArgList>::type t2;
|
||||
typedef typename forward<t2>::type f2;
|
||||
|
||||
static void execute(
|
||||
PyObject* p, t0 a0, t1 a1, t2 a2)
|
||||
{
|
||||
(new holder(p, f0(a0), f1(a1), f2(a2)))->install(p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_holder<4>
|
||||
{
|
||||
template <class T, class Generator, class ArgList>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<Generator,T>::type holder;
|
||||
typedef typename mpl::at<0,ArgList>::type t0;
|
||||
typedef typename forward<t0>::type f0;
|
||||
typedef typename mpl::at<1,ArgList>::type t1;
|
||||
typedef typename forward<t1>::type f1;
|
||||
typedef typename mpl::at<2,ArgList>::type t2;
|
||||
typedef typename forward<t2>::type f2;
|
||||
typedef typename mpl::at<3,ArgList>::type t3;
|
||||
typedef typename forward<t3>::type f3;
|
||||
|
||||
static void execute(
|
||||
PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3)
|
||||
{
|
||||
(new holder(p, f0(a0), f1(a1), f2(a2), f3(a3)))->install(p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_holder<5>
|
||||
{
|
||||
template <class T, class Generator, class ArgList>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<Generator,T>::type holder;
|
||||
typedef typename mpl::at<0,ArgList>::type t0;
|
||||
typedef typename forward<t0>::type f0;
|
||||
typedef typename mpl::at<1,ArgList>::type t1;
|
||||
typedef typename forward<t1>::type f1;
|
||||
typedef typename mpl::at<2,ArgList>::type t2;
|
||||
typedef typename forward<t2>::type f2;
|
||||
typedef typename mpl::at<3,ArgList>::type t3;
|
||||
typedef typename forward<t3>::type f3;
|
||||
typedef typename mpl::at<4,ArgList>::type t4;
|
||||
typedef typename forward<t4>::type f4;
|
||||
|
||||
static void execute(
|
||||
PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4)
|
||||
{
|
||||
(new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4)))->install(p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_holder<6>
|
||||
{
|
||||
template <class T, class Generator, class ArgList>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<Generator,T>::type holder;
|
||||
typedef typename mpl::at<0,ArgList>::type t0;
|
||||
typedef typename forward<t0>::type f0;
|
||||
typedef typename mpl::at<1,ArgList>::type t1;
|
||||
typedef typename forward<t1>::type f1;
|
||||
typedef typename mpl::at<2,ArgList>::type t2;
|
||||
typedef typename forward<t2>::type f2;
|
||||
typedef typename mpl::at<3,ArgList>::type t3;
|
||||
typedef typename forward<t3>::type f3;
|
||||
typedef typename mpl::at<4,ArgList>::type t4;
|
||||
typedef typename forward<t4>::type f4;
|
||||
typedef typename mpl::at<5,ArgList>::type t5;
|
||||
typedef typename forward<t5>::type f5;
|
||||
|
||||
static void execute(
|
||||
PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)
|
||||
{
|
||||
(new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4), f5(a5)))->install(p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // MAKE_HOLDER_DWA20011215_HPP
|
||||
201
include/boost/python/object/pointer_holder.hpp
Normal file
201
include/boost/python/object/pointer_holder.hpp
Normal file
@@ -0,0 +1,201 @@
|
||||
// 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 POINTER_HOLDER_DWA20011215_HPP
|
||||
# define POINTER_HOLDER_DWA20011215_HPP
|
||||
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/python/detail/eval.hpp>
|
||||
# include <boost/ref.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class Pointer, class Value>
|
||||
struct pointer_holder : instance_holder
|
||||
{
|
||||
pointer_holder(Pointer);
|
||||
|
||||
// Forward construction to the held object
|
||||
pointer_holder(PyObject*)
|
||||
: m_p(new Value) {}
|
||||
|
||||
|
||||
template <class A1>
|
||||
pointer_holder(PyObject*, A1 a1)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
)) {}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
)) {}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
, (typename unwrap_reference<A8>::type&)(a8)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
, (typename unwrap_reference<A8>::type&)(a8)
|
||||
, (typename unwrap_reference<A9>::type&)(a9)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
|
||||
: m_p(new Value(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
, (typename unwrap_reference<A8>::type&)(a8)
|
||||
, (typename unwrap_reference<A9>::type&)(a9)
|
||||
, (typename unwrap_reference<A10>::type&)(a10)
|
||||
))
|
||||
{}
|
||||
|
||||
private: // required holder implementation
|
||||
void* holds(converter::type_id_t);
|
||||
|
||||
private: // data members
|
||||
Pointer m_p;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
// back to namespace boost for this forward declaration
|
||||
namespace boost
|
||||
{
|
||||
template <class T> class shared_ptr;
|
||||
}
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
struct shared_ptr_generator
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef boost::shared_ptr<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
// A generator metafunction which can be passed to make_holder
|
||||
// PointerGenerator should be another generator metafunction which
|
||||
// makes the appropriate (smart) pointer type to hold the argument to
|
||||
// pointer_holder_generator.
|
||||
template <class PointerGenerator>
|
||||
struct pointer_holder_generator
|
||||
{
|
||||
template <class Held>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<PointerGenerator,Held>::type pointer;
|
||||
typedef pointer_holder<pointer, Held> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Pointer, class Value>
|
||||
pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
|
||||
: m_p(p)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Pointer, class Value>
|
||||
void* pointer_holder<Pointer, Value>::holds(converter::type_id_t dst_t)
|
||||
{
|
||||
if (dst_t == converter::type_id<Pointer>())
|
||||
return &this->m_p;
|
||||
|
||||
converter::type_id_t src_t = converter::type_id<Value>();
|
||||
return src_t == dst_t ? &*this->m_p
|
||||
: find_dynamic_type(&*this->m_p, src_t, dst_t);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // POINTER_HOLDER_DWA20011215_HPP
|
||||
163
include/boost/python/object/value_holder.hpp
Normal file
163
include/boost/python/object/value_holder.hpp
Normal file
@@ -0,0 +1,163 @@
|
||||
// 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 VALUE_HOLDER_DWA20011215_HPP
|
||||
# define VALUE_HOLDER_DWA20011215_HPP
|
||||
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/ref.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class Held>
|
||||
struct value_holder : instance_holder
|
||||
{
|
||||
// Forward construction to the held object
|
||||
value_holder(PyObject*)
|
||||
: m_held() {}
|
||||
|
||||
template <class A1>
|
||||
value_holder(PyObject*, A1 a1)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
)
|
||||
{}
|
||||
|
||||
template <class A1, class A2>
|
||||
value_holder(PyObject*, A1 a1, A2 a2)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
)
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
)
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
)
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
) {}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
) {}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
)
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
, (typename unwrap_reference<A8>::type&)(a8)
|
||||
)
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
, (typename unwrap_reference<A8>::type&)(a8)
|
||||
, (typename unwrap_reference<A9>::type&)(a9)
|
||||
)
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
|
||||
: m_held(
|
||||
(typename unwrap_reference<A1>::type&)(a1)
|
||||
, (typename unwrap_reference<A2>::type&)(a2)
|
||||
, (typename unwrap_reference<A3>::type&)(a3)
|
||||
, (typename unwrap_reference<A4>::type&)(a4)
|
||||
, (typename unwrap_reference<A5>::type&)(a5)
|
||||
, (typename unwrap_reference<A6>::type&)(a6)
|
||||
, (typename unwrap_reference<A7>::type&)(a7)
|
||||
, (typename unwrap_reference<A8>::type&)(a8)
|
||||
, (typename unwrap_reference<A9>::type&)(a9)
|
||||
, (typename unwrap_reference<A10>::type&)(a10)
|
||||
)
|
||||
{}
|
||||
|
||||
private: // required holder implementation
|
||||
void* holds(converter::type_id_t);
|
||||
|
||||
private: // data members
|
||||
Held m_held;
|
||||
};
|
||||
|
||||
// A generator metafunction which can be passed to make_holder
|
||||
struct value_holder_generator
|
||||
{
|
||||
template <class Held>
|
||||
struct apply
|
||||
{
|
||||
typedef value_holder<Held> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Held>
|
||||
void* value_holder<Held>::holds(converter::type_id_t dst_t)
|
||||
{
|
||||
converter::type_id_t src_t = converter::type_id<Held>();
|
||||
return src_t == dst_t ? &m_held
|
||||
: find_static_type(&m_held, src_t, dst_t);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // VALUE_HOLDER_DWA20011215_HPP
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class object
|
||||
class BOOST_PYTHON_DECL object
|
||||
{
|
||||
public:
|
||||
explicit object(ref p);
|
||||
@@ -32,15 +32,36 @@ class object
|
||||
ref m_p;
|
||||
};
|
||||
|
||||
class tuple : public object
|
||||
class tuple;
|
||||
|
||||
class BOOST_PYTHON_DECL tuple_base : public object
|
||||
{
|
||||
public:
|
||||
explicit tuple(std::size_t n = 0);
|
||||
explicit tuple(ref p);
|
||||
explicit tuple_base(std::size_t n = 0);
|
||||
explicit tuple_base(ref p);
|
||||
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(ref p);
|
||||
std::size_t size() const;
|
||||
ref operator[](std::size_t pos) const;
|
||||
|
||||
void set_item(std::size_t pos, const ref& rhs);
|
||||
|
||||
tuple slice(int low, int high) const;
|
||||
|
||||
friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&);
|
||||
friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&);
|
||||
};
|
||||
|
||||
class tuple : public tuple_base
|
||||
{
|
||||
public:
|
||||
explicit tuple(std::size_t n = 0) : tuple_base(n) {}
|
||||
explicit tuple(ref p) : tuple_base(p) {}
|
||||
|
||||
template <class First, class Second>
|
||||
tuple(const std::pair<First,Second>& x)
|
||||
: object(ref(PyTuple_New(2)))
|
||||
: tuple_base(ref(PyTuple_New(2)))
|
||||
{
|
||||
set_item(0, x.first);
|
||||
set_item(1, x.second);
|
||||
@@ -48,7 +69,7 @@ class tuple : public object
|
||||
|
||||
template <class First, class Second>
|
||||
tuple(const First& first, const Second& second)
|
||||
: object(ref(PyTuple_New(2)))
|
||||
: tuple_base(ref(PyTuple_New(2)))
|
||||
{
|
||||
set_item(0, first);
|
||||
set_item(1, second);
|
||||
@@ -56,7 +77,7 @@ class tuple : public object
|
||||
|
||||
template <class First, class Second, class Third>
|
||||
tuple(const First& first, const Second& second, const Third& third)
|
||||
: object(ref(PyTuple_New(3)))
|
||||
: tuple_base(ref(PyTuple_New(3)))
|
||||
{
|
||||
set_item(0, first);
|
||||
set_item(1, second);
|
||||
@@ -65,7 +86,7 @@ class tuple : public object
|
||||
|
||||
template <class First, class Second, class Third, class Fourth>
|
||||
tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth)
|
||||
: object(ref(PyTuple_New(4)))
|
||||
: tuple_base(ref(PyTuple_New(4)))
|
||||
{
|
||||
set_item(0, first);
|
||||
set_item(1, second);
|
||||
@@ -73,32 +94,31 @@ class tuple : public object
|
||||
set_item(3, fourth);
|
||||
}
|
||||
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(ref p);
|
||||
std::size_t size() const;
|
||||
ref operator[](std::size_t pos) const;
|
||||
|
||||
template <class T>
|
||||
void set_item(std::size_t pos, const T& rhs)
|
||||
{
|
||||
this->set_item(pos, make_ref(rhs));
|
||||
}
|
||||
|
||||
void set_item(std::size_t pos, const ref& rhs);
|
||||
|
||||
tuple slice(int low, int high) const;
|
||||
|
||||
friend tuple operator+(const tuple&, const tuple&);
|
||||
tuple& operator+=(const tuple& rhs);
|
||||
void set_item(std::size_t pos, const ref& rhs)
|
||||
{
|
||||
tuple_base::set_item(pos, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
class list : public object
|
||||
class list;
|
||||
|
||||
struct BOOST_PYTHON_DECL list_proxy;
|
||||
struct BOOST_PYTHON_DECL list_slice_proxy;
|
||||
|
||||
class BOOST_PYTHON_DECL list_base : public object
|
||||
{
|
||||
struct proxy;
|
||||
struct slice_proxy;
|
||||
protected:
|
||||
typedef list_proxy proxy;
|
||||
typedef list_slice_proxy slice_proxy;
|
||||
public:
|
||||
explicit list(ref p);
|
||||
explicit list(std::size_t sz = 0);
|
||||
explicit list_base(ref p);
|
||||
explicit list_base(std::size_t sz = 0);
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(ref p);
|
||||
std::size_t size() const;
|
||||
@@ -106,26 +126,14 @@ class list : public object
|
||||
proxy operator[](std::size_t pos);
|
||||
ref get_item(std::size_t pos) const;
|
||||
|
||||
template <class T>
|
||||
void set_item(std::size_t pos, const T& x)
|
||||
{ this->set_item(pos, make_ref(x)); }
|
||||
void set_item(std::size_t pos, const ref& );
|
||||
|
||||
// void set_item(std::size_t pos, const object& );
|
||||
|
||||
template <class T>
|
||||
void insert(std::size_t index, const T& x)
|
||||
{ this->insert(index, make_ref(x)); }
|
||||
void insert(std::size_t index, const ref& item);
|
||||
|
||||
template <class T>
|
||||
void push_back(const T& item)
|
||||
{ this->push_back(make_ref(item)); }
|
||||
void push_back(const ref& item);
|
||||
|
||||
template <class T>
|
||||
void append(const T& item)
|
||||
{ this->append(make_ref(item)); }
|
||||
void append(const ref& item);
|
||||
|
||||
list slice(int low, int high) const;
|
||||
@@ -135,7 +143,31 @@ class list : public object
|
||||
tuple as_tuple() const;
|
||||
};
|
||||
|
||||
class string
|
||||
class list : public list_base
|
||||
{
|
||||
public:
|
||||
explicit list(ref p) : list_base(p) {}
|
||||
explicit list(std::size_t sz = 0) : list_base(sz) {}
|
||||
template <class T>
|
||||
void set_item(std::size_t pos, const T& x)
|
||||
{ this->set_item(pos, make_ref(x)); }
|
||||
template <class T>
|
||||
void insert(std::size_t index, const T& x)
|
||||
{ this->insert(index, make_ref(x)); }
|
||||
template <class T>
|
||||
void push_back(const T& item)
|
||||
{ this->push_back(make_ref(item)); }
|
||||
template <class T>
|
||||
void append(const T& item)
|
||||
{ this->append(make_ref(item)); }
|
||||
|
||||
void set_item(std::size_t pos, const ref& x) { list_base::set_item(pos, x); }
|
||||
void insert(std::size_t index, const ref& item) { list_base::insert(index, item); }
|
||||
void push_back(const ref& item) { list_base::push_back(item); }
|
||||
void append(const ref& item) { list_base::append(item); }
|
||||
};
|
||||
|
||||
class BOOST_PYTHON_DECL string
|
||||
: public object, public boost::multipliable2<string, unsigned int>
|
||||
{
|
||||
public:
|
||||
@@ -175,48 +207,31 @@ class string
|
||||
friend string operator%(const string& format, const tuple& args);
|
||||
};
|
||||
|
||||
class dictionary : public object
|
||||
class dictionary;
|
||||
|
||||
struct BOOST_PYTHON_DECL dictionary_proxy;
|
||||
|
||||
class BOOST_PYTHON_DECL dictionary_base : public object
|
||||
{
|
||||
private:
|
||||
struct proxy;
|
||||
protected:
|
||||
typedef dictionary_proxy proxy;
|
||||
|
||||
public:
|
||||
explicit dictionary(ref p);
|
||||
dictionary();
|
||||
explicit dictionary_base(ref p);
|
||||
dictionary_base();
|
||||
void clear();
|
||||
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(ref p);
|
||||
|
||||
public:
|
||||
template <class Key>
|
||||
proxy operator[](const Key& key)
|
||||
{ return this->operator[](make_ref(key)); }
|
||||
proxy operator[](ref key);
|
||||
|
||||
template <class Key>
|
||||
ref operator[](const Key& key) const
|
||||
{ return this->operator[](make_ref(key)); }
|
||||
ref operator[](ref key) const;
|
||||
|
||||
template <class Key>
|
||||
ref get_item(const Key& key) const
|
||||
{ return this->get_item(make_ref(key)); }
|
||||
ref get_item(const ref& key) const;
|
||||
|
||||
template <class Key, class Default>
|
||||
ref get_item(const Key& key, const Default& default_) const
|
||||
{ return this->get_item(make_ref(key), make_ref(default_)); }
|
||||
ref get_item(const ref& key, const ref& default_) const;
|
||||
|
||||
template <class Key, class Value>
|
||||
void set_item(const Key& key, const Value& value)
|
||||
{ this->set_item(make_ref(key), make_ref(value)); }
|
||||
void set_item(const ref& key, const ref& value);
|
||||
|
||||
template <class Key>
|
||||
void erase(const Key& key)
|
||||
{ this->erase(make_ref(key)); }
|
||||
void erase(ref key);
|
||||
|
||||
// proxy operator[](const object& key);
|
||||
@@ -235,7 +250,7 @@ class dictionary : public object
|
||||
// TODO: iterator support
|
||||
};
|
||||
|
||||
struct dictionary::proxy
|
||||
struct BOOST_PYTHON_DECL dictionary_proxy
|
||||
{
|
||||
template <class T>
|
||||
const ref& operator=(const T& rhs)
|
||||
@@ -244,19 +259,63 @@ struct dictionary::proxy
|
||||
|
||||
operator ref() const;
|
||||
private:
|
||||
friend class dictionary;
|
||||
proxy(const ref& dict, const ref& key);
|
||||
friend class dictionary_base;
|
||||
dictionary_proxy(const ref& dict, const ref& key);
|
||||
|
||||
// This is needed to work around the very strange MSVC error report that the
|
||||
// return type of the built-in operator= differs from that of the ones
|
||||
// defined above. Couldn't hurt to make these un-assignable anyway, though.
|
||||
const ref& operator=(const proxy&); // Not actually implemented
|
||||
const ref& operator=(const dictionary_proxy&); // Not actually implemented
|
||||
private:
|
||||
ref m_dict;
|
||||
ref m_key;
|
||||
};
|
||||
|
||||
struct list::proxy
|
||||
class dictionary : public dictionary_base
|
||||
{
|
||||
typedef dictionary_proxy proxy;
|
||||
public:
|
||||
explicit dictionary(ref p) : dictionary_base(p) {}
|
||||
dictionary() : dictionary_base() {}
|
||||
|
||||
template <class Key>
|
||||
proxy operator[](const Key& key)
|
||||
{ return this->operator[](make_ref(key)); }
|
||||
proxy operator[](ref key)
|
||||
{ return dictionary_base::operator[](key); }
|
||||
|
||||
template <class Key>
|
||||
ref operator[](const Key& key) const
|
||||
{ return this->operator[](make_ref(key)); }
|
||||
ref operator[](ref key) const
|
||||
{ return dictionary_base::operator[](key); }
|
||||
|
||||
template <class Key>
|
||||
ref get_item(const Key& key) const
|
||||
{ return this->get_item(make_ref(key)); }
|
||||
ref get_item(const ref& key) const
|
||||
{ return dictionary_base::get_item(key); }
|
||||
|
||||
template <class Key, class Default>
|
||||
ref get_item(const Key& key, const Default& default_) const
|
||||
{ return this->get_item(make_ref(key), make_ref(default_)); }
|
||||
ref get_item(const ref& key, const ref& default_) const
|
||||
{ return dictionary_base::get_item(key, default_); }
|
||||
|
||||
template <class Key, class Value>
|
||||
void set_item(const Key& key, const Value& value)
|
||||
{ this->set_item(make_ref(key), make_ref(value)); }
|
||||
void set_item(const ref& key, const ref& value)
|
||||
{ dictionary_base::set_item(key, value); }
|
||||
|
||||
template <class Key>
|
||||
void erase(const Key& key)
|
||||
{ this->erase(make_ref(key)); }
|
||||
void erase(ref key)
|
||||
{ dictionary_base::erase(key); }
|
||||
};
|
||||
|
||||
struct BOOST_PYTHON_DECL list_proxy
|
||||
{
|
||||
template <class T>
|
||||
const ref& operator=(const T& rhs)
|
||||
@@ -266,19 +325,19 @@ struct list::proxy
|
||||
operator ref() const;
|
||||
|
||||
private:
|
||||
friend class list;
|
||||
proxy(const ref& list, std::size_t index);
|
||||
friend class list_base;
|
||||
list_proxy(const ref& list, std::size_t index);
|
||||
|
||||
// This is needed to work around the very strange MSVC error report that the
|
||||
// return type of the built-in operator= differs from that of the ones
|
||||
// defined above. Couldn't hurt to make these un-assignable anyway, though.
|
||||
const ref& operator=(const proxy&); // Not actually implemented
|
||||
const ref& operator=(const list_proxy&); // Not actually implemented
|
||||
private:
|
||||
list m_list;
|
||||
std::size_t m_index;
|
||||
};
|
||||
|
||||
struct list::slice_proxy
|
||||
struct BOOST_PYTHON_DECL list_slice_proxy
|
||||
{
|
||||
const list& operator=(const list& rhs);
|
||||
operator ref() const;
|
||||
@@ -286,8 +345,8 @@ struct list::slice_proxy
|
||||
std::size_t size() const;
|
||||
ref operator[](std::size_t pos) const;
|
||||
private:
|
||||
friend class list;
|
||||
slice_proxy(const ref& list, int low, int high);
|
||||
friend class list_base;
|
||||
list_slice_proxy(const ref& list, int low, int high);
|
||||
private:
|
||||
ref m_list;
|
||||
int m_low, m_high;
|
||||
@@ -295,34 +354,36 @@ struct list::slice_proxy
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
# ifndef BOOST_PYTHON_V2
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
PyObject* to_python(const boost::python::tuple&);
|
||||
boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple&);
|
||||
BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple>);
|
||||
|
||||
inline boost::python::tuple from_python(PyObject* p, boost::python::type<const boost::python::tuple&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<boost::python::tuple>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::list&);
|
||||
boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list&);
|
||||
BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list>);
|
||||
|
||||
inline boost::python::list from_python(PyObject* p, boost::python::type<const boost::python::list&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<boost::python::list>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::string&);
|
||||
boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string&);
|
||||
BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string>);
|
||||
|
||||
inline boost::python::string from_python(PyObject* p, boost::python::type<const boost::python::string&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<boost::python::string>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::dictionary&);
|
||||
boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary&);
|
||||
BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary>);
|
||||
|
||||
inline boost::python::dictionary from_python(PyObject* p, boost::python::type<const boost::python::dictionary&>)
|
||||
{
|
||||
@@ -330,5 +391,5 @@ inline boost::python::dictionary from_python(PyObject* p, boost::python::type<co
|
||||
}
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
# endif
|
||||
#endif // OBJECTS_DWA051100_H_
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
tuple standard_coerce(ref l, ref r);
|
||||
BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r);
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
@@ -14,9 +14,13 @@
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/cast.hpp>
|
||||
# include <cassert>
|
||||
# include <cstddef>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/conversions.hpp>
|
||||
# include <boost/python/detail/cast.hpp>
|
||||
|
||||
# ifndef BOOST_PYTHON_V2
|
||||
# include <boost/python/conversions.hpp>
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
@@ -35,14 +39,19 @@ struct py_ptr_conversions : Base
|
||||
};
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# ifndef BOOST_PYTHON_V2
|
||||
BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions);
|
||||
# endif
|
||||
|
||||
template <class T>
|
||||
class reference
|
||||
# ifndef BOOST_PYTHON_V2
|
||||
: public py_ptr_conversions<reference<T>, T>
|
||||
# endif
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
@@ -50,18 +59,10 @@ public:
|
||||
reference(const reference& rhs)
|
||||
: m_p(rhs.m_p)
|
||||
{
|
||||
Py_XINCREF(object());
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(m_p);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MSVC6_OR_EARLIER)
|
||||
template <class T2>
|
||||
reference(const reference<T2>& rhs)
|
||||
: m_p(rhs.object())
|
||||
{
|
||||
Py_XINCREF(object());
|
||||
}
|
||||
#endif
|
||||
|
||||
reference() : m_p(0) {}
|
||||
|
||||
// These are two ways of spelling the same thing, that we need to increment
|
||||
@@ -72,85 +73,140 @@ public:
|
||||
|
||||
template <class T2>
|
||||
explicit reference(T2* x)
|
||||
: m_p(expect_non_null(x)) {}
|
||||
: m_p(expect_non_null(x))
|
||||
{
|
||||
assert(m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, increment_count_t)
|
||||
: m_p(expect_non_null(x)) { Py_INCREF(object()); }
|
||||
: m_p(expect_non_null(x))
|
||||
{
|
||||
assert(m_p->ob_refcnt > 0);
|
||||
Py_INCREF(m_p);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, allow_null)
|
||||
: m_p(x) {}
|
||||
: m_p(x)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, allow_null, increment_count_t)
|
||||
: m_p(x) { Py_XINCREF(object()); }
|
||||
: m_p(x)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(m_p);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, increment_count_t, allow_null)
|
||||
: m_p(x) { Py_XINCREF(object()); }
|
||||
|
||||
#if !defined(BOOST_MSVC6_OR_EARLIER)
|
||||
template <class T2>
|
||||
reference& operator=(const reference<T2>& rhs)
|
||||
: m_p(x)
|
||||
{
|
||||
Py_XDECREF(object());
|
||||
m_p = rhs.m_p;
|
||||
Py_XINCREF(object());
|
||||
return *this;
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(m_p);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
reference& operator=(const reference& rhs)
|
||||
{
|
||||
assert(rhs.m_p == 0 || rhs.m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(static_cast<PyObject*>(rhs.m_p));
|
||||
Py_XDECREF(object());
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = rhs.m_p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~reference()
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
}
|
||||
|
||||
T& operator*() const { return *m_p; }
|
||||
T& operator*() const
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
return *m_p;
|
||||
}
|
||||
|
||||
// MSVC doesn't like boost::dereferencable unless T has a default
|
||||
// constructor, so operator-> must be defined by hand :(
|
||||
T* operator->() const { return &**this; }
|
||||
T* operator->() const
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
return &**this;
|
||||
}
|
||||
|
||||
T* get() const { return m_p; }
|
||||
T* get() const
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
return m_p;
|
||||
}
|
||||
|
||||
T* release()
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
T* p = m_p;
|
||||
m_p = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{ Py_XDECREF(m_p); m_p = 0; }
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = 0;
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x)
|
||||
{ Py_XDECREF(m_p); m_p = expect_non_null(x);}
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = expect_non_null(x);
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, increment_count_t)
|
||||
{ Py_XDECREF(m_p); m_p = expect_non_null(x); Py_INCREF(object()); }
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(x);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = expect_non_null(x);
|
||||
assert(m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, allow_null)
|
||||
{ Py_XDECREF(m_p); m_p = x;}
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = x;
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, allow_null, increment_count_t)
|
||||
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(x);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = x;
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, increment_count_t, allow_null)
|
||||
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(x);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = x;
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
private:
|
||||
@@ -158,18 +214,27 @@ private:
|
||||
#endif
|
||||
|
||||
inline PyObject* object() const
|
||||
{ return as_object(m_p); }
|
||||
{
|
||||
#ifdef BOOST_PYTHON_V2
|
||||
return (PyObject*)(
|
||||
(char*)&m_p->ob_type - offsetof(PyObject,ob_type));
|
||||
#else
|
||||
return as_object(m_p);
|
||||
#endif
|
||||
}
|
||||
|
||||
T* m_p;
|
||||
};
|
||||
|
||||
typedef reference<PyObject> ref;
|
||||
|
||||
#ifndef BOOST_PYTHON_V2
|
||||
template <class T>
|
||||
ref make_ref(const T& x)
|
||||
{
|
||||
return ref(to_python(x));
|
||||
}
|
||||
#endif
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
|
||||
45
include/boost/python/reference_existing_object.hpp
Normal file
45
include/boost/python/reference_existing_object.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef REFERENCE_EXISTING_OBJECT_DWA200222_HPP
|
||||
# define REFERENCE_EXISTING_OBJECT_DWA200222_HPP
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct reference_existing_object_requires_a_pointer_or_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
struct reference_existing_object
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ok = is_pointer<T>::value || is_reference<T>::value);
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
ok
|
||||
, to_python_indirect<T, detail::make_reference_holder>
|
||||
, detail::reference_existing_object_requires_a_pointer_or_reference_return_type<T>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // REFERENCE_EXISTING_OBJECT_DWA200222_HPP
|
||||
62
include/boost/python/reference_from_python.hpp
Normal file
62
include/boost/python/reference_from_python.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef REFERENCE_FROM_PYTHON_DWA2002130_HPP
|
||||
# define REFERENCE_FROM_PYTHON_DWA2002130_HPP
|
||||
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/type_from_python.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Utility which produces a member extractor function on platforms
|
||||
// other than VC6.
|
||||
template <class Class, class Member, Member (Class::*mp)>
|
||||
struct get_member
|
||||
{
|
||||
static Member& execute(Class* c)
|
||||
{
|
||||
return c->*mp;
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
PyTypeObject const* python_type
|
||||
, class Value
|
||||
, class PythonObject
|
||||
, class Extract
|
||||
>
|
||||
struct reference_from_python
|
||||
{
|
||||
typedef type_from_python<python_type> convertible_t;
|
||||
|
||||
reference_from_python()
|
||||
: m_mutable_converter(
|
||||
&convertible_t::convertible, convert_mutable)
|
||||
|
||||
, m_const_converter(
|
||||
&convertible_t::convertible, convert_const)
|
||||
{}
|
||||
|
||||
static Value& convert_mutable(PyObject* op, converter::from_python_data&)
|
||||
{
|
||||
return Extract::execute(*(PythonObject*)op);
|
||||
}
|
||||
|
||||
static Value const& convert_const(PyObject* op, converter::from_python_data&)
|
||||
{
|
||||
return Extract::execute(*(PythonObject*)op);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef converter::from_python_converter<Value&> mutable_converter;
|
||||
typedef converter::from_python_converter<Value const&> const_converter;
|
||||
mutable_converter m_mutable_converter;
|
||||
const_converter m_const_converter;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // REFERENCE_FROM_PYTHON_DWA2002130_HPP
|
||||
49
include/boost/python/return_internal_reference.hpp
Normal file
49
include/boost/python/return_internal_reference.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// 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_INTERNAL_REFERENCE_DWA2002131_HPP
|
||||
# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP
|
||||
|
||||
# include <boost/python/default_call_policies.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/python/reference_existing_object.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
# include <boost/python/with_custodian_and_ward.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct return_internal_reference_requires_a_pointer_or_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
struct internal_reference_to_python_generator
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_object<T>::value
|
||||
, detail::return_internal_reference_requires_a_pointer_or_reference_return_type<T>
|
||||
, to_python_indirect<T, detail::make_reference_holder>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template <std::size_t owner_arg = 1, class Base = default_call_policies>
|
||||
struct return_internal_reference
|
||||
: with_custodian_and_ward_postcall<0, owner_arg, Base>
|
||||
{
|
||||
typedef reference_existing_object result_converter;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // RETURN_INTERNAL_REFERENCE_DWA2002131_HPP
|
||||
20
include/boost/python/return_value_policy.hpp
Normal file
20
include/boost/python/return_value_policy.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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_VALUE_POLICY_DWA2002131_HPP
|
||||
# define RETURN_VALUE_POLICY_DWA2002131_HPP
|
||||
# include <boost/python/default_call_policies.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class Handler, class Base = default_call_policies>
|
||||
struct return_value_policy : Base
|
||||
{
|
||||
typedef Handler result_converter;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // RETURN_VALUE_POLICY_DWA2002131_HPP
|
||||
39
include/boost/python/to_python_converter.hpp
Normal file
39
include/boost/python/to_python_converter.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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_CONVERTER_DWA200221_HPP
|
||||
# define TO_PYTHON_CONVERTER_DWA200221_HPP
|
||||
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/to_python_function.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T, class Derived>
|
||||
struct to_python_converter
|
||||
{
|
||||
to_python_converter();
|
||||
};
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
|
||||
template <class T, class Derived>
|
||||
to_python_converter<T,Derived>::to_python_converter()
|
||||
{
|
||||
typedef converter::as_to_python_value_function<
|
||||
T, Derived
|
||||
> normalized;
|
||||
|
||||
converter::registry::insert(
|
||||
&normalized::convert
|
||||
, converter::undecorated_type_id<T>());
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // TO_PYTHON_CONVERTER_DWA200221_HPP
|
||||
102
include/boost/python/to_python_indirect.hpp
Normal file
102
include/boost/python/to_python_indirect.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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_INDIRECT_DWA200221_HPP
|
||||
# define TO_PYTHON_INDIRECT_DWA200221_HPP
|
||||
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/python/object/pointer_holder.hpp>
|
||||
# include <boost/python/object/class_object.hpp>
|
||||
# include <boost/python/detail/unwind_type.hpp>
|
||||
# include <memory>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T, class HolderGenerator>
|
||||
struct to_python_indirect
|
||||
{
|
||||
static bool convertible();
|
||||
PyObject* operator()(T ptr) const;
|
||||
private:
|
||||
static PyTypeObject* type();
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
struct make_owning_holder
|
||||
{
|
||||
typedef objects::instance_holder* result_type;
|
||||
template <class T>
|
||||
static result_type execute(T* p)
|
||||
{
|
||||
return new objects::pointer_holder<std::auto_ptr<T>, T>(
|
||||
std::auto_ptr<T>(p));
|
||||
}
|
||||
};
|
||||
|
||||
struct make_reference_holder
|
||||
{
|
||||
typedef objects::instance_holder* result_type;
|
||||
template <class T>
|
||||
static result_type execute(T* p)
|
||||
{
|
||||
return new objects::pointer_holder<T*, T>(p);
|
||||
}
|
||||
};
|
||||
|
||||
struct get_pointer_class
|
||||
{
|
||||
typedef PyTypeObject* result_type;
|
||||
template <class T>
|
||||
static result_type execute(T* p)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(is_class<T>::value);
|
||||
return python::objects::class_object<T>::reference;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class T, class HolderGenerator>
|
||||
inline bool to_python_indirect<T,HolderGenerator>::convertible()
|
||||
{
|
||||
return type() != 0;
|
||||
}
|
||||
|
||||
template <class T, class HolderGenerator>
|
||||
inline PyObject* to_python_indirect<T,HolderGenerator>::operator()(T x) const
|
||||
{
|
||||
PyObject* raw_result = type()->tp_alloc(type(), 0);
|
||||
|
||||
if (raw_result == 0)
|
||||
return 0;
|
||||
|
||||
// Everything's OK; Bypass NULL checks but guard against
|
||||
// exceptions.
|
||||
ref result(raw_result, ref::allow_null());
|
||||
|
||||
// Build a value_holder to contain the object using the copy
|
||||
// constructor
|
||||
objects::instance_holder* p =
|
||||
detail::unwind_type<HolderGenerator>(x);
|
||||
|
||||
// Install it in the instance
|
||||
p->install(raw_result);
|
||||
|
||||
// Return the new result
|
||||
return result.release();
|
||||
}
|
||||
|
||||
template <class T, class HolderGenerator>
|
||||
inline PyTypeObject* to_python_indirect<T,HolderGenerator>::type()
|
||||
{
|
||||
return detail::unwind_type<detail::get_pointer_class,T>();
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // TO_PYTHON_INDIRECT_DWA200221_HPP
|
||||
58
include/boost/python/to_python_value.hpp
Normal file
58
include/boost/python/to_python_value.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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_VALUE_DWA200221_HPP
|
||||
# define TO_PYTHON_VALUE_DWA200221_HPP
|
||||
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/to_python_function.hpp>
|
||||
# include <boost/python/converter/builtin_converters.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
struct to_python_value
|
||||
{
|
||||
typedef typename add_reference<
|
||||
typename add_const<T>::type
|
||||
>::type argument_type;
|
||||
|
||||
static bool convertible();
|
||||
PyObject* operator()(argument_type) const;
|
||||
|
||||
private:
|
||||
// Note that this is a pointer to a function pointer
|
||||
static converter::to_python_value_function const* fconvert;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
converter::to_python_value_function const*
|
||||
to_python_value<T>::fconvert
|
||||
= &converter::registry::to_python_function(converter::undecorated_type_id<T>());
|
||||
|
||||
|
||||
template <class T>
|
||||
bool to_python_value<T>::convertible()
|
||||
{
|
||||
// if this assert fires, our static variable hasn't been set up yet.
|
||||
assert(fconvert != 0);
|
||||
return *fconvert != 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* to_python_value<T>::operator()(argument_type x) const
|
||||
{
|
||||
// This might be further optimized on platforms which dynamically
|
||||
// link without specific imports/exports
|
||||
converter::to_python_value_function f = *fconvert;
|
||||
return f(&x);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // TO_PYTHON_VALUE_DWA200221_HPP
|
||||
23
include/boost/python/type_from_python.hpp
Normal file
23
include/boost/python/type_from_python.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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 TYPE_FROM_PYTHON_DWA2002130_HPP
|
||||
# define TYPE_FROM_PYTHON_DWA2002130_HPP
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <PyTypeObject const* python_type>
|
||||
struct type_from_python
|
||||
{
|
||||
static void* convertible(PyObject* op)
|
||||
{
|
||||
return PyObject_TypeCheck(
|
||||
op, const_cast<PyTypeObject*>(python_type)) ? op : 0;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // TYPE_FROM_PYTHON_DWA2002130_HPP
|
||||
73
include/boost/python/value_from_python.hpp
Normal file
73
include/boost/python/value_from_python.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef VALUE_FROM_PYTHON_DWA2002130_HPP
|
||||
# define VALUE_FROM_PYTHON_DWA2002130_HPP
|
||||
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <typename T, class Derived>
|
||||
struct value_from_python
|
||||
{
|
||||
typedef value_from_python<T,Derived> self;
|
||||
typedef converter::from_python_check from_python_check;
|
||||
|
||||
value_from_python(from_python_check convertible)
|
||||
: m_converter(
|
||||
convertible
|
||||
, &Derived::convert
|
||||
|
||||
// Change this to a compile-time check later to avoid
|
||||
// generating destroy function
|
||||
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
value_from_python()
|
||||
: m_converter(
|
||||
&Derived::convertible
|
||||
, &Derived::convert
|
||||
|
||||
// Change this to a compile-time check later to avoid
|
||||
// generating destroy function
|
||||
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
static void* get_storage(converter::from_python_data& data)
|
||||
{
|
||||
return converter::get_storage<T const&>(data);
|
||||
}
|
||||
|
||||
// Mark successful construction
|
||||
static void constructed(converter::from_python_data& data)
|
||||
{
|
||||
data.stage1 = self::get_storage(data);
|
||||
}
|
||||
|
||||
inline static void destroy(converter::from_python_data& data)
|
||||
{
|
||||
// Get the location of the storage for
|
||||
void* storage = self::get_storage(data);
|
||||
|
||||
// Check for successful construction
|
||||
if (data.stage1 == storage)
|
||||
static_cast<T*>(storage)->~T();
|
||||
}
|
||||
|
||||
private:
|
||||
converter::from_python_converter<T const&> m_converter;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // VALUE_FROM_PYTHON_DWA2002130_HPP
|
||||
80
include/boost/python/with_custodian_and_ward.hpp
Normal file
80
include/boost/python/with_custodian_and_ward.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
// 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 WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
|
||||
# define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
|
||||
|
||||
# include <boost/python/default_call_policies.hpp>
|
||||
# include <boost/python/object/life_support.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
enum custodial_timing { pre_call, post_call };
|
||||
|
||||
template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
|
||||
struct with_custodian_and_ward : Base
|
||||
{
|
||||
static bool precall(PyObject* args);
|
||||
};
|
||||
|
||||
template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
|
||||
struct with_custodian_and_ward_postcall : Base
|
||||
{
|
||||
static PyObject* postcall(PyObject* args, PyObject* result);
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <std::size_t custodian, std::size_t ward, class Base>
|
||||
bool with_custodian_and_ward<custodian,ward,Base>::precall(PyObject* args_)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(custodian != ward);
|
||||
BOOST_STATIC_ASSERT(custodian > 0);
|
||||
BOOST_STATIC_ASSERT(ward > 0);
|
||||
|
||||
PyObject* patient = PyTuple_GetItem(args_, ward - 1);
|
||||
if (patient == 0) return false;
|
||||
PyObject* nurse = PyTuple_GetItem(args_, custodian - 1);
|
||||
if (nurse == 0) return false;
|
||||
|
||||
PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient);
|
||||
if (life_support == 0)
|
||||
return false;
|
||||
|
||||
bool result = Base::precall(args_);
|
||||
|
||||
if (!result)
|
||||
Py_XDECREF(life_support);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t custodian, std::size_t ward, class Base>
|
||||
PyObject* with_custodian_and_ward_postcall<custodian,ward,Base>::postcall(PyObject* args_, PyObject* result)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(custodian != ward);
|
||||
|
||||
PyObject* patient = ward > 0 ? PyTuple_GetItem(args_, ward - 1) : result;
|
||||
if (patient == 0) return 0;
|
||||
|
||||
PyObject* nurse = custodian > 0 ? PyTuple_GetItem(args_, custodian - 1) : result;
|
||||
if (nurse == 0) return 0;
|
||||
|
||||
result = Base::postcall(args_, result);
|
||||
if (result == 0)
|
||||
return 0;
|
||||
|
||||
if (python::objects::make_nurse_and_patient(nurse, patient) == 0)
|
||||
{
|
||||
Py_XDECREF(result);
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
|
||||
@@ -645,7 +645,7 @@ PyObject* instance::divmod(PyObject* other)
|
||||
|
||||
PyObject* instance::power(PyObject* exponent, PyObject* modulus)
|
||||
{
|
||||
if (as_object(modulus->ob_type) == Py_None)
|
||||
if (as_object(modulus) == Py_None)
|
||||
return callback<PyObject*>::call_method(this, "__pow__", exponent);
|
||||
else
|
||||
return callback<PyObject*>::call_method(this, "__pow__", exponent, modulus);
|
||||
@@ -999,7 +999,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void adjust_slice_indices(PyObject* obj, int& start, int& finish)
|
||||
BOOST_PYTHON_DECL void adjust_slice_indices(PyObject* obj, int& start, int& finish)
|
||||
{
|
||||
int length = callback<int>::call_method(obj, "__len__");
|
||||
|
||||
|
||||
@@ -16,65 +16,16 @@
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
|
||||
#include <boost/python/conversions.hpp>
|
||||
#include <boost/python/detail/void_adaptor.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <typeinfo>
|
||||
#include <exception>
|
||||
#ifndef BOOST_NO_LIMITS
|
||||
# include <boost/cast.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// IMPORTANT: this function may only be called from within a catch block!
|
||||
PyObject* handle_exception_impl(object_functor_base const& f)
|
||||
{
|
||||
try
|
||||
{
|
||||
return f();
|
||||
}
|
||||
catch(const boost::python::error_already_set&)
|
||||
{
|
||||
// The python error reporting has already been handled.
|
||||
}
|
||||
catch(const std::bad_alloc&)
|
||||
{
|
||||
PyErr_NoMemory();
|
||||
}
|
||||
catch(const std::exception& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, x.what());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handle_exception(void (*f)())
|
||||
{
|
||||
handle_exception(
|
||||
boost::python::detail::make_void_adaptor(f));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
void expect_complex(PyObject* p)
|
||||
{
|
||||
if (!PyComplex_Check(p))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "expected a complex number");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost::python::detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
long from_python(PyObject* p, boost::python::type<long>)
|
||||
BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type<long>)
|
||||
{
|
||||
// Why am I clearing the error here before trying to convert? I know there's a reason...
|
||||
long result;
|
||||
@@ -86,7 +37,7 @@ long from_python(PyObject* p, boost::python::type<long>)
|
||||
return result;
|
||||
}
|
||||
|
||||
double from_python(PyObject* p, boost::python::type<double>)
|
||||
BOOST_PYTHON_DECL double from_python(PyObject* p, boost::python::type<double>)
|
||||
{
|
||||
double result;
|
||||
{
|
||||
@@ -151,48 +102,48 @@ PyObject* integer_to_python(T value)
|
||||
return to_python(value_as_long);
|
||||
}
|
||||
|
||||
int from_python(PyObject* p, boost::python::type<int> type)
|
||||
BOOST_PYTHON_DECL int from_python(PyObject* p, boost::python::type<int> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned int i)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned int i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
unsigned int from_python(PyObject* p, boost::python::type<unsigned int> type)
|
||||
BOOST_PYTHON_DECL unsigned int from_python(PyObject* p, boost::python::type<unsigned int> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
short from_python(PyObject* p, boost::python::type<short> type)
|
||||
BOOST_PYTHON_DECL short from_python(PyObject* p, boost::python::type<short> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
float from_python(PyObject* p, boost::python::type<float>)
|
||||
BOOST_PYTHON_DECL float from_python(PyObject* p, boost::python::type<float>)
|
||||
{
|
||||
return static_cast<float>(from_python(p, boost::python::type<double>()));
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned short i)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned short i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
unsigned short from_python(PyObject* p, boost::python::type<unsigned short> type)
|
||||
BOOST_PYTHON_DECL unsigned short from_python(PyObject* p, boost::python::type<unsigned short> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(char c)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(char c)
|
||||
{
|
||||
if (c == '\0') return PyString_FromString("");
|
||||
return PyString_FromStringAndSize(&c, 1);
|
||||
}
|
||||
|
||||
char from_python(PyObject* p, boost::python::type<char>)
|
||||
BOOST_PYTHON_DECL char from_python(PyObject* p, boost::python::type<char>)
|
||||
{
|
||||
int l = -1;
|
||||
if (PyString_Check(p)) l = PyString_Size(p);
|
||||
@@ -204,37 +155,37 @@ char from_python(PyObject* p, boost::python::type<char>)
|
||||
return PyString_AsString(p)[0];
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned char i)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned char i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
unsigned char from_python(PyObject* p, boost::python::type<unsigned char> type)
|
||||
BOOST_PYTHON_DECL unsigned char from_python(PyObject* p, boost::python::type<unsigned char> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(signed char i)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(signed char i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
signed char from_python(PyObject* p, boost::python::type<signed char> type)
|
||||
BOOST_PYTHON_DECL signed char from_python(PyObject* p, boost::python::type<signed char> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned long x)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned long x)
|
||||
{
|
||||
return integer_to_python(x);
|
||||
}
|
||||
|
||||
unsigned long from_python(PyObject* p, boost::python::type<unsigned long> type)
|
||||
BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type<unsigned long> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
void from_python(PyObject* p, boost::python::type<void>)
|
||||
BOOST_PYTHON_DECL void from_python(PyObject* p, boost::python::type<void>)
|
||||
{
|
||||
if (p != Py_None) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected argument of type None");
|
||||
@@ -242,7 +193,7 @@ void from_python(PyObject* p, boost::python::type<void>)
|
||||
}
|
||||
}
|
||||
|
||||
const char* from_python(PyObject* p, boost::python::type<const char*>)
|
||||
BOOST_PYTHON_DECL const char* from_python(PyObject* p, boost::python::type<const char*>)
|
||||
{
|
||||
const char* s = PyString_AsString(p);
|
||||
if (!s)
|
||||
@@ -250,12 +201,12 @@ const char* from_python(PyObject* p, boost::python::type<const char*>)
|
||||
return s;
|
||||
}
|
||||
|
||||
PyObject* to_python(const std::string& s)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(const std::string& s)
|
||||
{
|
||||
return PyString_FromStringAndSize(s.data(), s.size());
|
||||
}
|
||||
|
||||
std::string from_python(PyObject* p, boost::python::type<std::string>)
|
||||
BOOST_PYTHON_DECL std::string from_python(PyObject* p, boost::python::type<std::string>)
|
||||
{
|
||||
if (! PyString_Check(p)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a string");
|
||||
@@ -264,7 +215,7 @@ std::string from_python(PyObject* p, boost::python::type<std::string>)
|
||||
return std::string(PyString_AsString(p), PyString_Size(p));
|
||||
}
|
||||
|
||||
bool from_python(PyObject* p, boost::python::type<bool>)
|
||||
BOOST_PYTHON_DECL bool from_python(PyObject* p, boost::python::type<bool>)
|
||||
{
|
||||
int value = from_python(p, boost::python::type<int>());
|
||||
if (value == 0)
|
||||
@@ -274,12 +225,12 @@ bool from_python(PyObject* p, boost::python::type<bool>)
|
||||
|
||||
#ifdef BOOST_MSVC6_OR_EARLIER
|
||||
// An optimizer bug prevents these from being inlined.
|
||||
PyObject* to_python(double d)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(double d)
|
||||
{
|
||||
return PyFloat_FromDouble(d);
|
||||
}
|
||||
|
||||
PyObject* to_python(float f)
|
||||
BOOST_PYTHON_DECL PyObject* to_python(float f)
|
||||
{
|
||||
return PyFloat_FromDouble(f);
|
||||
}
|
||||
|
||||
18
src/converter/body.cpp
Normal file
18
src/converter/body.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/converter/body.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// default implementation is a no-op. Most handles will not hold any
|
||||
// data that needs to be managed. Unwrap objects which convert
|
||||
// by-value are an exception. Fortunately, the concrete body subclass
|
||||
// has that knowledge.
|
||||
void body::destroy_handle(handle*) const
|
||||
{
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
227
src/converter/builtin_converters.cpp
Normal file
227
src/converter/builtin_converters.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
// 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/python/detail/config.hpp>
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
#include <boost/python/converter/builtin_converters.hpp>
|
||||
#include <boost/python/converter/target.hpp>
|
||||
#include <boost/python/value_from_python.hpp>
|
||||
#include <boost/python/converter/from_python_data.hpp>
|
||||
#include <boost/python/reference.hpp>
|
||||
#include <boost/cast.hpp>
|
||||
//#include <boost/mpl/type_list.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace
|
||||
{
|
||||
// Only an object which we know is holding a char const* can be
|
||||
// converted to one
|
||||
struct convertible_to_cstring
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
return PyString_Check(obj) ? &obj->ob_type->tp_str : 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct extract_cstring
|
||||
{
|
||||
static char const* execute(PyObject* obj)
|
||||
{
|
||||
return PyString_AsString(obj);
|
||||
}
|
||||
};
|
||||
|
||||
// Any object which can be converted to a Python string can also be
|
||||
// converted to a C++ string, since the latter owns its bytes.
|
||||
struct convertible_to_string
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Transform a function returning a unaryfunc* into one that returns a void*
|
||||
template <class F>
|
||||
struct return_void_ptr
|
||||
{
|
||||
static void* execute(PyObject* p) { return F::execute(p); }
|
||||
};
|
||||
|
||||
template <
|
||||
class T // The target type
|
||||
, class Convertible // returns a pointer to a unaryfunc producing an object
|
||||
, class TExtract // ...from which TExtract extracts T's constructor argument
|
||||
>
|
||||
struct tp_scalar_from_python
|
||||
: from_python_converter<T>
|
||||
{
|
||||
private:
|
||||
typedef return_void_ptr<Convertible> convertible_fn;
|
||||
|
||||
public:
|
||||
tp_scalar_from_python()
|
||||
: from_python_converter<T>(
|
||||
&convertible_fn::execute
|
||||
, convert)
|
||||
{}
|
||||
|
||||
static T convert(PyObject* obj, from_python_data& data)
|
||||
{
|
||||
unaryfunc converter = *(unaryfunc*)data.stage1;
|
||||
ref converted(converter(obj));
|
||||
return TExtract::execute(converted.get());
|
||||
}
|
||||
};
|
||||
|
||||
// Extract a reference to T using the functions in the source
|
||||
// object's type slots
|
||||
template <
|
||||
class T // The target type
|
||||
, class Convertible // returns a pointer to a unaryfunc producing an object
|
||||
, class TExtract // ...from which TExtract extracts T's constructor argument
|
||||
>
|
||||
struct tp_cref_from_python
|
||||
: value_from_python<T, tp_cref_from_python<T,Convertible,TExtract> >
|
||||
{
|
||||
private:
|
||||
typedef tp_cref_from_python<T,Convertible,TExtract> self;
|
||||
typedef value_from_python<T,tp_cref_from_python<T,Convertible,TExtract> > base;
|
||||
|
||||
public:
|
||||
tp_cref_from_python()
|
||||
: base(&return_void_ptr<Convertible>::execute)
|
||||
{}
|
||||
|
||||
static T const& convert(PyObject* obj, from_python_data& data)
|
||||
{
|
||||
unaryfunc converter = *(unaryfunc*)data.stage1;
|
||||
|
||||
void* storage = self::get_storage(data);
|
||||
|
||||
ref converted(converter(obj));
|
||||
|
||||
T* const p = new (storage) T(TExtract::execute(converted.get()));
|
||||
|
||||
// note that construction is successful.
|
||||
data.stage1 = p;
|
||||
|
||||
return *p;
|
||||
}
|
||||
};
|
||||
|
||||
struct convertible_to_int
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
// For floating types, return the float conversion slot to avoid
|
||||
// creating a new object. We'll handle that in
|
||||
// py_int_or_float_as_long, below
|
||||
if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float)
|
||||
return &number_methods->nb_float;
|
||||
|
||||
return number_methods && number_methods->nb_int
|
||||
? &number_methods->nb_int : 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct py_int_or_float_as_long
|
||||
{
|
||||
static long execute(PyObject* obj)
|
||||
{
|
||||
if (PyObject_TypeCheck(obj, &PyFloat_Type))
|
||||
{
|
||||
return numeric_cast<long>(PyFloat_AS_DOUBLE(obj));
|
||||
}
|
||||
else
|
||||
{
|
||||
return PyInt_AS_LONG(obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct convertible_to_double
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
// For integer types, return the tp_int conversion slot to avoid
|
||||
// creating a new object. We'll handle that in
|
||||
// py_float_or_int_as_double, below
|
||||
if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int)
|
||||
return &number_methods->nb_int;
|
||||
|
||||
return number_methods && number_methods->nb_float
|
||||
? &number_methods->nb_float : 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct py_float_or_int_as_double
|
||||
{
|
||||
static double execute(PyObject* obj)
|
||||
{
|
||||
if (PyObject_TypeCheck(obj, &PyInt_Type))
|
||||
{
|
||||
return PyInt_AS_LONG(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PyFloat_AS_DOUBLE(obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Convertible, class Convert>
|
||||
struct scalar_from_python
|
||||
{
|
||||
tp_cref_from_python<T,Convertible,Convert> cref_converter;
|
||||
tp_scalar_from_python<T,Convertible,Convert> value_converter;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void register_int_converters(T* = 0)
|
||||
{
|
||||
static scalar_from_python<T, convertible_to_int, py_int_or_float_as_long> x;
|
||||
}
|
||||
}
|
||||
|
||||
#define REGISTER_INT_CONVERTERS(U) register_int_converters<U>()
|
||||
#define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U)
|
||||
|
||||
void initialize_builtin_converters()
|
||||
{
|
||||
REGISTER_INT_CONVERTERS2(char);
|
||||
REGISTER_INT_CONVERTERS2(short);
|
||||
REGISTER_INT_CONVERTERS2(int);
|
||||
REGISTER_INT_CONVERTERS2(long);
|
||||
|
||||
static scalar_from_python<
|
||||
float,convertible_to_double,py_float_or_int_as_double> float_from_python;
|
||||
|
||||
static scalar_from_python<
|
||||
double,convertible_to_double,py_float_or_int_as_double> double_from_python;
|
||||
|
||||
static scalar_from_python<
|
||||
long double,convertible_to_double,py_float_or_int_as_double> long_double_from_python;
|
||||
|
||||
static scalar_from_python<
|
||||
char const*, convertible_to_cstring, extract_cstring> cstring_from_python;
|
||||
|
||||
static tp_cref_from_python<
|
||||
std::string, convertible_to_string, extract_cstring> string_from_python;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
26
src/converter/from_python.cpp
Normal file
26
src/converter/from_python.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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/python/converter/from_python.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
from_python_converter_base::from_python_converter_base(
|
||||
type_id_t type
|
||||
, from_python_check checker
|
||||
)
|
||||
: body(type)
|
||||
, m_convertible(checker)
|
||||
|
||||
{
|
||||
// Insert this in the converter chain.
|
||||
from_python_converter_base*& head = registry::from_python_chain(type);
|
||||
m_next = head;
|
||||
head = this;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
35
src/converter/handle.cpp
Normal file
35
src/converter/handle.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/converter/handle.hpp>
|
||||
#include <boost/python/converter/body.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
bool handle::convertible() const
|
||||
{
|
||||
for (handle const* p = this; p != 0; p = p->m_next)
|
||||
{
|
||||
if (p->m_body == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void handle::destroy()
|
||||
{
|
||||
// Recurse down the chain releasing from tail to head
|
||||
if (m_next != 0)
|
||||
m_next->destroy();
|
||||
|
||||
// Our body knows how to destroy us. If we never got a body,
|
||||
// there's nothing to do.
|
||||
if (m_body)
|
||||
m_body->destroy_handle(this);
|
||||
}
|
||||
|
||||
// void handle::dummy::nonnull() {}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user