mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 16:32:16 +00:00
Compare commits
129 Commits
boost-1.25
...
boost-1.27
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5e65866d4 | ||
|
|
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 | ||
|
|
d4b215a66b | ||
|
|
1a13387012 | ||
|
|
291c36df05 | ||
|
|
bed2c8a371 | ||
|
|
e65ca4ccac | ||
|
|
f9e6933840 | ||
|
|
5134fb2ec1 | ||
|
|
3a86a69964 | ||
|
|
c6fd3c47a4 | ||
|
|
a365fa6109 | ||
|
|
160451b210 | ||
|
|
2f6e3cc09d | ||
|
|
d05cc7ccec | ||
|
|
ccfd4acbda | ||
|
|
6a6084ed0e | ||
|
|
0dbb780a2f | ||
|
|
e6efa6e13e | ||
|
|
76768120d4 | ||
|
|
7d6ff83760 | ||
|
|
5bec0d2d98 | ||
|
|
aad05325a6 | ||
|
|
6e7f1bc257 | ||
|
|
634d0848c8 | ||
|
|
b7e1059227 | ||
|
|
e7904fa67a | ||
|
|
e38bc7cbce | ||
|
|
b211f8a096 |
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
|
||||
;
|
||||
}
|
||||
207
build/Jamfile
207
build/Jamfile
@@ -54,47 +54,20 @@
|
||||
# PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for
|
||||
# the dvect and ivect tests above.
|
||||
|
||||
|
||||
# declare the location of this subproject relative to the root
|
||||
subproject libs/python/build ;
|
||||
|
||||
# grab variables from command-line or environment.
|
||||
local PYTHON_VERSION = $(PYTHON_VERSION) ;
|
||||
local PYTHON_ROOT = $(PYTHON_ROOT) ;
|
||||
local PYTHON_INCLUDES = $(PYTHON_INCLUDES) ;
|
||||
local PYTHON_LIBS = $(PYTHON_LIBS) ;
|
||||
local PYTHON_LIB_PATH = $(PYTHON_LIB_PATH) ;
|
||||
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) ;
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
# Do some OS-specific setup
|
||||
if $(NT)
|
||||
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_DYNAMIC_LIB ;
|
||||
|
||||
#######################
|
||||
rule bpl-test ( test-name : sources + )
|
||||
{
|
||||
PYTHON_VERSION ?= 2.1 ;
|
||||
PYTHON_ROOT ?= c:/tools/python ;
|
||||
PYTHON_INCLUDES ?= <include>$(PYTHON_ROOT)/include <gcc><*><include>/usr/include/python$(PYTHON_VERSION) ;
|
||||
PYTHON_LIBS ?= c:/cygnus/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).dll.a ;
|
||||
PYTHON_LIB_PATH = $(PYTHON_ROOT)/libs ;
|
||||
|
||||
# common properties required for compiling any Python module.
|
||||
PYTHON_PROPERTIES ?=
|
||||
<gcc><*><define>SIZEOF_LONG=4
|
||||
<gcc><*><define>USE_DL_IMPORT
|
||||
<runtime-link>dynamic
|
||||
;
|
||||
|
||||
boost-python-test $(test-name) : $(sources) <lib>libboost_python ;
|
||||
}
|
||||
else if $(UNIX)
|
||||
{
|
||||
PYTHON_VERSION ?= 1.5 ;
|
||||
PYTHON_INCLUDES ?= <include>/usr/include/python$(PYTHON_VERSION) ;
|
||||
PYTHON_LIBS ?= /usr/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).a ;
|
||||
}
|
||||
|
||||
# how do we invoke python?
|
||||
local PYTHON = $(PYTHON) ;
|
||||
PYTHON ?= python ;
|
||||
PYTHON = [ FAppendSuffix $(PYTHON:G=<executable-grist>) : $(SUFEXE) ] ;
|
||||
SEARCH on $(PYTHON) = $(PATH) ;
|
||||
|
||||
#######################
|
||||
|
||||
@@ -102,148 +75,46 @@ SEARCH on $(PYTHON) = $(PATH) ;
|
||||
# Declare the boost python static link library
|
||||
#
|
||||
|
||||
# standard include requirements for anything using Boost.Python
|
||||
local BOOST_PYTHON_INCLUDES = <include>$(BOOST_ROOT) $(PYTHON_INCLUDES) ;
|
||||
|
||||
# Base names of the source files for libboost_python
|
||||
local CPP_SOURCES =
|
||||
classes conversions extension_class functions
|
||||
init_function module_builder objects types 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) ;
|
||||
|
||||
#######################
|
||||
|
||||
# boost-python name : sources : requirements : default-BUILD
|
||||
#
|
||||
# Declare a boost python module. Return a list of the DLL files generated.
|
||||
rule boost-python
|
||||
{
|
||||
# declare a DLL; add the boost python library to sources
|
||||
dll $(<) : <lib>libboost_python $(>)
|
||||
|
||||
# Requirements
|
||||
: $(3) # caller-specified requirements
|
||||
|
||||
# standard requirements
|
||||
$(BOOST_PYTHON_INCLUDES)
|
||||
<msvc><*><library-path>$(PYTHON_LIB_PATH)
|
||||
<gcc><*><library-file>$(PYTHON_LIBS)
|
||||
$(PYTHON_PROPERTIES)
|
||||
|
||||
: $(4) ; # pass on the default-BUILD, if any
|
||||
}
|
||||
|
||||
# boost-python-test name : sources : requirements : default-BUILD
|
||||
#
|
||||
# Just like boost-python, but the result becomes part of the test pseudotarget
|
||||
# instead of being built by 'all'
|
||||
rule boost-python-test
|
||||
{
|
||||
type-DEPENDS test : $(<) ;
|
||||
|
||||
local gSUPPRESS_FAKE_TARGETS = true ;
|
||||
boost-python $(1) : $(2) : $(3) : $(4) ;
|
||||
}
|
||||
|
||||
#######################
|
||||
|
||||
# boost-python-runtest target : python-script sources : requirements : local-build : args
|
||||
#
|
||||
# declare two python module tests: $(<).test which builds when out-of-date, and
|
||||
# $(<).run which builds unconditionally.
|
||||
rule boost-python-runtest
|
||||
{
|
||||
# tell Jam that the python script is relative to this directory
|
||||
SEARCH on $(>[1]) = $(SEARCH_SOURCE) ;
|
||||
|
||||
# required command-line args can be specified in argument 5
|
||||
# The user can add additional arguments in PYTHON_TEST_ARGS.
|
||||
local gPYTHON_TEST_ARGS = $(5) $(PYTHON_TEST_ARGS) ;
|
||||
|
||||
# declare the two subsidiary tests.
|
||||
declare-local-target $(<:S=.test) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_TEST ;
|
||||
declare-local-target $(<:S=.run) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_RUNTEST ;
|
||||
}
|
||||
|
||||
# special rules for two new target types: PYTHON_TEST and PYTHON_RUNTEST.
|
||||
# These are identical except that PYTHON_TEST runs the test when out-of-date, and
|
||||
# PYTHON_RUNTEST runs the test unconditionally. These are used by boost-python-runtest.
|
||||
SUFPYTHON_TEST = .test ;
|
||||
gGENERATOR_FUNCTION(PYTHON_TEST) = python-test-target ;
|
||||
rule python-test-target # test-target : sources :
|
||||
{
|
||||
python-runtest-aux $(<) : $(>) ;
|
||||
Clean clean : $(<) ; # remove the test-target as part of any clean operation
|
||||
type-DEPENDS test : $(<) ;
|
||||
MakeLocate $(<) : $(LOCATE_TARGET) ;
|
||||
}
|
||||
actions python-test-target bind PYTHON
|
||||
{
|
||||
$(SHELL_SET)PYTHONPATH=$(PYTHONPATH)
|
||||
$(SHELL_EXPORT)PYTHONPATH
|
||||
$(PYTHON) "$(>)" $(ARGS) > "$(<)"
|
||||
}
|
||||
|
||||
SUFPYTHON_RUNTEST = .run ;
|
||||
gGENERATOR_FUNCTION(PYTHON_RUNTEST) = python-runtest-target ;
|
||||
rule python-runtest-target # test-target : sources :
|
||||
{
|
||||
python-runtest-aux $(<) : $(>) ;
|
||||
NOTFILE $(<) ;
|
||||
ALWAYS $(<) ;
|
||||
}
|
||||
actions python-runtest-target bind PYTHON
|
||||
{
|
||||
$(SHELL_SET)PYTHONPATH=$(PYTHONPATH)
|
||||
$(SHELL_EXPORT)PYTHONPATH
|
||||
$(PYTHON) "$(>)" $(ARGS)
|
||||
}
|
||||
|
||||
rule python-runtest-aux # target : sources
|
||||
{
|
||||
DEPENDS $(<) : $(>) ;
|
||||
|
||||
ARGS on $(<) += $(gPYTHON_TEST_ARGS) ;
|
||||
|
||||
# Some tests need an extra command-line arg if built with
|
||||
# msvc. Checking the target grist is a cheap way to
|
||||
# find out.
|
||||
switch $(<)
|
||||
{
|
||||
case <*\\\\msvc\\\\*>* : ARGS on $(<) += --broken-auto-ptr ;
|
||||
}
|
||||
|
||||
# compute the PYTHONPATH environment variable that will allow the test to
|
||||
# find all of the modules on which it depends.
|
||||
PYTHONPATH on $(<) = [ join
|
||||
$(gLOCATE($(>[1]))) # location of python test file
|
||||
$(gRUN_PATH($(<))) # location of module dependencies
|
||||
[ join-path $(TOP) libs python test ] # location of doctest
|
||||
$(PYTHONPATH) # base PYTHONPATH from environment
|
||||
: $(SPLITPATH) ] ; # platform path separator
|
||||
|
||||
PYTHON on $(<) = $(PYTHON) ;
|
||||
DEPENDS $(<) : $(PYTHON) ;
|
||||
}
|
||||
dll libboost_python
|
||||
# $(SUFDLL[1])
|
||||
: ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<runtime-link>dynamic
|
||||
<define>BOOST_PYTHON_HAS_DLL_RUNTIME=1
|
||||
$(PYTHON_PROPERTIES)
|
||||
;
|
||||
|
||||
############# comprehensive module and test ###########
|
||||
boost-python-test boost_python_test : ../test/comprehensive.cpp ;
|
||||
bpl-test boost_python_test
|
||||
: ../test/comprehensive.cpp ;
|
||||
|
||||
boost-python-runtest comprehensive
|
||||
: [ join-path $(DOTDOT) test comprehensive.py ]
|
||||
<lib>boost_python_test ;
|
||||
: ../test/comprehensive.py <lib>boost_python_test <lib>libboost_python ;
|
||||
|
||||
############# simple tests from ../example ############
|
||||
|
||||
rule boost-python-example-runtest
|
||||
rule boost-python-example-runtest ( name )
|
||||
{
|
||||
boost-python-test $(<) : ../example/$(<).cpp ;
|
||||
boost-python-runtest $(<) : [ join-path $(DOTDOT) example test_$(<).py ] <lib>$(<) ;
|
||||
bpl-test $(name)
|
||||
: ../example/$(name).cpp ;
|
||||
|
||||
boost-python-runtest $(name)
|
||||
: ../example/test_$(name).py <lib>$(name) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -257,18 +128,18 @@ boost-python-example-runtest pickle2 ;
|
||||
boost-python-example-runtest pickle3 ;
|
||||
|
||||
|
||||
boost-python-test ivect : ../example/ivect.cpp ;
|
||||
boost-python-test dvect : ../example/dvect.cpp ;
|
||||
boost-python-test noncopyable_export : ../example/noncopyable_export.cpp ;
|
||||
boost-python-test noncopyable_import : ../example/noncopyable_import.cpp ;
|
||||
bpl-test ivect : ../example/ivect.cpp ;
|
||||
bpl-test dvect : ../example/dvect.cpp ;
|
||||
bpl-test noncopyable_export : ../example/noncopyable_export.cpp ;
|
||||
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
|
||||
rule boost-python-multi-example-runtest # test-name : python-file libs
|
||||
rule boost-python-multi-example-runtest ( test-name : modules + )
|
||||
{
|
||||
boost-python-runtest $(<)
|
||||
: ../example/tst_$(<).py <lib>$(>)
|
||||
boost-python-runtest $(test-name)
|
||||
: ../example/tst_$(test-name).py <lib>$(modules) <lib>libboost_python
|
||||
: : : $(PYTHON_VECT_ITERATIONS) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
149
build/win32_mwcc.mak
Executable file
149
build/win32_mwcc.mak
Executable file
@@ -0,0 +1,149 @@
|
||||
# Usage:
|
||||
#
|
||||
# make copy Copy the sources and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make del Remove the sources and tests
|
||||
#
|
||||
# Revision history:
|
||||
# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve)
|
||||
|
||||
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"
|
||||
|
||||
STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB
|
||||
WARNOPTS=-warn on,nounusedexpr,nounused
|
||||
OPTOPTS=-O
|
||||
|
||||
CPP=mwcc
|
||||
CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \
|
||||
$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC)
|
||||
|
||||
LD=mwld
|
||||
LDOPTS=-export dllexport -shared
|
||||
|
||||
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
|
||||
|
||||
.SUFFIXES: .obj .cpp
|
||||
|
||||
all: libboost_python.lib \
|
||||
boost_python_test.pyd \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_convts.pyd \
|
||||
nested.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd \
|
||||
richcmp1.pyd richcmp2.pyd richcmp3.pyd
|
||||
|
||||
libboost_python.lib: $(OBJ)
|
||||
$(LD) -library -o libboost_python.lib $(OBJ)
|
||||
|
||||
boost_python_test.pyd: $(OBJ) comprehensive.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) -o boost_python_test.pyd
|
||||
|
||||
abstract.pyd: $(OBJ) abstract.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) -o abstract.pyd
|
||||
|
||||
getting_started1.pyd: $(OBJ) getting_started1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) -o getting_started1.pyd
|
||||
|
||||
getting_started2.pyd: $(OBJ) getting_started2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) -o getting_started2.pyd
|
||||
|
||||
simple_vector.pyd: $(OBJ) simple_vector.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) -o simple_vector.pyd
|
||||
|
||||
do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) -o do_it_yourself_convts.pyd
|
||||
|
||||
nested.pyd: $(OBJ) nested.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) -o nested.pyd
|
||||
|
||||
pickle1.pyd: $(OBJ) pickle1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) -o pickle1.pyd
|
||||
|
||||
pickle2.pyd: $(OBJ) pickle2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) -o pickle2.pyd
|
||||
|
||||
pickle3.pyd: $(OBJ) pickle3.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) -o pickle3.pyd
|
||||
|
||||
noncopyable_export.pyd: $(OBJ) noncopyable_export.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) -o noncopyable_export.pyd
|
||||
|
||||
noncopyable_import.pyd: $(OBJ) noncopyable_import.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) -o noncopyable_import.pyd
|
||||
|
||||
ivect.pyd: $(OBJ) ivect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) -o ivect.pyd
|
||||
|
||||
dvect.pyd: $(OBJ) dvect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) -o dvect.pyd
|
||||
|
||||
richcmp1.pyd: $(OBJ) richcmp1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) -o richcmp1.pyd
|
||||
|
||||
richcmp2.pyd: $(OBJ) richcmp2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) -o richcmp2.pyd
|
||||
|
||||
richcmp3.pyd: $(OBJ) richcmp3.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) -o richcmp3.pyd
|
||||
|
||||
.cpp.obj:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_convts.py
|
||||
$(PYEXE) test_nested.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
$(PYEXE) test_richcmp1.py
|
||||
$(PYEXE) test_richcmp2.py
|
||||
$(PYEXE) test_richcmp3.py
|
||||
|
||||
clean:
|
||||
-del *.obj
|
||||
-del *.lib
|
||||
-del *.exp
|
||||
-del *.idb
|
||||
-del *.pyd
|
||||
-del *.pyc
|
||||
|
||||
softlinks:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||
|
||||
unlink:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink
|
||||
|
||||
cp:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp
|
||||
|
||||
rm:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm
|
||||
|
||||
copy:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy
|
||||
|
||||
del:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del
|
||||
2
build/win32_mwcc_setup.bat
Executable file
2
build/win32_mwcc_setup.bat
Executable file
@@ -0,0 +1,2 @@
|
||||
call "c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat"
|
||||
set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib
|
||||
@@ -98,6 +98,12 @@ Notes:<ul>
|
||||
|
||||
<li>Any function added to a class whose initial argument matches the class (or
|
||||
any base) will act like a member function in Python.
|
||||
|
||||
<li>To define a nested class, just pass the enclosing
|
||||
<tt>class_builder</tt> (instead of a <tt>module_builder</tt>) as the
|
||||
first argument to the nested <tt>class_builder</tt>'s constructor.
|
||||
|
||||
|
||||
</ul>
|
||||
<p>
|
||||
We can even make a subclass of <code>hello.world</code>:
|
||||
|
||||
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.
|
||||
@@ -287,6 +287,35 @@ bignum_class.def(&rmod, "__rmod__");
|
||||
found first (be it ``<code>int</code>`` or ``<code>float</code>'') will be
|
||||
used for either of the two types.
|
||||
|
||||
<h3><a name="inplace">Inplace Operators</a></h3>
|
||||
<p>
|
||||
Boost.Python can also be used to expose inplace numeric operations
|
||||
(i.e., <code>+=</code> and so forth). These operators must be wrapped
|
||||
manually, as described in the previous section. For example, suppose
|
||||
the class BigNum has an <code>operator+=</code>:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum& operator+= (BigNum const& right);
|
||||
</pre></blockquote>
|
||||
|
||||
This can be exposed by first writing a wrapper function:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum& iadd (BigNum& self, const BigNum& right)
|
||||
{
|
||||
return self += right;
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
and then exposing the wrapper with
|
||||
|
||||
<blockquote><pre>
|
||||
bignum_class.def(&iadd, "__iadd__");
|
||||
</pre></blockquote>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3><a name="coercion">Coercion</a></h3>
|
||||
|
||||
|
||||
|
||||
@@ -107,8 +107,6 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("do_it_yourself_convts");
|
||||
|
||||
@@ -120,9 +118,4 @@ BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts)
|
||||
// Add the member functions.
|
||||
ixset_class.def(&IndexingSet::add, "add");
|
||||
ixset_class.def(&IndexingSet::get, "get");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(dvect)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("dvect");
|
||||
|
||||
python::class_builder<vects::dvect> dvect_class(this_module, "dvect");
|
||||
@@ -47,10 +45,4 @@ BOOST_PYTHON_MODULE_INIT(dvect)
|
||||
|
||||
# include "dvect_defs.cpp"
|
||||
# include "ivect_defs.cpp"
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,32 +16,21 @@ namespace hello {
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
extern "C"
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void inithello()
|
||||
BOOST_PYTHON_MODULE_INIT(hello)
|
||||
{
|
||||
try
|
||||
{
|
||||
// create an object representing this extension module
|
||||
boost::python::module_builder hello("hello");
|
||||
// create an object representing this extension module
|
||||
boost::python::module_builder hello("hello");
|
||||
|
||||
// Create the Python type object for our extension class
|
||||
boost::python::class_builder<hello::world> world_class(hello, "world");
|
||||
// Create the Python type object for our extension class
|
||||
boost::python::class_builder<hello::world> world_class(hello, "world");
|
||||
|
||||
// Add the __init__ function
|
||||
world_class.def(boost::python::constructor<int>());
|
||||
// Add a regular member function
|
||||
world_class.def(&hello::world::get, "get");
|
||||
// Add the __init__ function
|
||||
world_class.def(boost::python::constructor<int>());
|
||||
// Add a regular member function
|
||||
world_class.def(&hello::world::get, "get");
|
||||
|
||||
// Add a regular function to the module
|
||||
hello.def(hello::length, "length");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
// Add a regular function to the module
|
||||
hello.def(hello::length, "length");
|
||||
}
|
||||
|
||||
// Win32 DLL boilerplate
|
||||
|
||||
@@ -16,17 +16,10 @@ namespace python = boost::python;
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started1");
|
||||
|
||||
// Add regular functions to the module.
|
||||
this_module.def(greet, "greet");
|
||||
this_module.def(square, "square");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace python = boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started2");
|
||||
|
||||
@@ -44,9 +42,4 @@ BOOST_PYTHON_MODULE_INIT(getting_started2)
|
||||
|
||||
// Even better, invite() can also be made a member of hello_class!!!
|
||||
hello_class.def(invite, "invite");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(ivect)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("ivect");
|
||||
|
||||
python::class_builder<vects::ivect> ivect_class(this_module, "ivect");
|
||||
@@ -47,10 +45,5 @@ BOOST_PYTHON_MODULE_INIT(ivect)
|
||||
|
||||
# include "dvect_defs.cpp"
|
||||
# include "ivect_defs.cpp"
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,13 +32,6 @@ namespace {
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(nested)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::python::module_builder this_module("nested");
|
||||
this_module.def(show_nested_tuples, "show_nested_tuples");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::python::handle_exception();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(noncopyable_export)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("noncopyable_export");
|
||||
|
||||
python::class_builder<store> store_class(this_module, "store");
|
||||
@@ -27,9 +25,4 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_export)
|
||||
|
||||
store_class.def(python::constructor<int>());
|
||||
store_class.def(&store::recall, "recall");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(noncopyable_import)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("noncopyable_import");
|
||||
|
||||
python::import_converters<store>
|
||||
@@ -44,9 +42,4 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_import)
|
||||
// However, to keep this example simple, we only define a
|
||||
// module-level function.
|
||||
this_module.def(add_stores, "add_stores");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle1");
|
||||
|
||||
@@ -56,9 +54,4 @@ BOOST_PYTHON_MODULE_INIT(pickle1)
|
||||
|
||||
// Support for pickle.
|
||||
world_class.def(world_getinitargs, "__getinitargs__");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,6 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle2");
|
||||
|
||||
@@ -92,9 +90,4 @@ BOOST_PYTHON_MODULE_INIT(pickle2)
|
||||
world_class.def(world_getinitargs, "__getinitargs__");
|
||||
world_class.def(world_getstate, "__getstate__");
|
||||
world_class.def(world_setstate, "__setstate__");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +65,6 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle3)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle3");
|
||||
|
||||
@@ -85,11 +83,6 @@ BOOST_PYTHON_MODULE_INIT(pickle3)
|
||||
world_class.def_raw(world_getstate, "__getstate__");
|
||||
world_class.def_raw(world_setstate, "__setstate__");
|
||||
world_class.getstate_manages_dict();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -77,11 +77,8 @@ namespace {
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(richcmp1)
|
||||
{
|
||||
try {
|
||||
boost::python::module_builder this_module("richcmp1");
|
||||
// The actual work is done in a separate function in order
|
||||
// to suppress a bogus VC60 warning.
|
||||
init_module(this_module);
|
||||
}
|
||||
catch (...) { boost::python::handle_exception(); }
|
||||
}
|
||||
|
||||
@@ -55,11 +55,8 @@ namespace {
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(richcmp2)
|
||||
{
|
||||
try {
|
||||
boost::python::module_builder this_module("richcmp2");
|
||||
// The actual work is done in a separate function in order
|
||||
// to suppress a bogus VC60 warning.
|
||||
init_module(this_module);
|
||||
}
|
||||
catch (...) { boost::python::handle_exception(); }
|
||||
}
|
||||
|
||||
@@ -168,11 +168,8 @@ namespace {
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(richcmp3)
|
||||
{
|
||||
try {
|
||||
boost::python::module_builder this_module("richcmp3");
|
||||
// The actual work is done in a separate function in order
|
||||
// to suppress a bogus VC60 warning.
|
||||
init_module(this_module);
|
||||
}
|
||||
catch (...) { boost::python::handle_exception(); }
|
||||
}
|
||||
|
||||
@@ -13,29 +13,12 @@ namespace python = boost::python;
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
extern "C"
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void initrwgk1()
|
||||
BOOST_PYTHON_MODULE_INIT(rwgk1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("rwgk1");
|
||||
|
||||
// Add regular functions to the module.
|
||||
this_module.def(greet, "greet");
|
||||
this_module.def(square, "square");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
// Win32 DLL boilerplate
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; }
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -85,15 +85,13 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(simple_vector)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("simple_vector");
|
||||
|
||||
python::class_builder<std::vector<double>, vector_double_wrapper>
|
||||
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__");
|
||||
@@ -103,9 +101,4 @@ BOOST_PYTHON_MODULE_INIT(simple_vector)
|
||||
|
||||
this_module.def(foo, "foo");
|
||||
this_module.def(bar, "bar");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -25,6 +25,22 @@ class class_builder
|
||||
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
template <class OtherT, class OtherU>
|
||||
class_builder(class_builder<OtherT, OtherU>& cls, const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
cls.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
template <class OtherT, class OtherU>
|
||||
class_builder(detail::extension_class<OtherT, OtherU>* cls,
|
||||
const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
cls->set_attribute(name,
|
||||
ref(as_object(m_class.get()), ref::increment_count));
|
||||
}
|
||||
|
||||
~class_builder()
|
||||
{}
|
||||
|
||||
|
||||
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:
|
||||
@@ -78,6 +78,19 @@ class instance
|
||||
PyObject* gt(PyObject* other);
|
||||
PyObject* ge(PyObject* other);
|
||||
|
||||
// Inplace operations.
|
||||
PyObject* inplace_add(PyObject* other);
|
||||
PyObject* inplace_subtract(PyObject* other);
|
||||
PyObject* inplace_multiply(PyObject* other);
|
||||
PyObject* inplace_divide(PyObject* other);
|
||||
PyObject* inplace_remainder(PyObject* other);
|
||||
PyObject* inplace_power(PyObject* exponent, PyObject* modulus);
|
||||
PyObject* inplace_lshift(PyObject* other);
|
||||
PyObject* inplace_rshift(PyObject* other);
|
||||
PyObject* inplace_and(PyObject* other);
|
||||
PyObject* inplace_or(PyObject* other);
|
||||
PyObject* inplace_xor(PyObject* other);
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
instance(const instance&);
|
||||
void operator=(const instance&);
|
||||
@@ -92,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);
|
||||
@@ -115,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;
|
||||
@@ -128,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);
|
||||
@@ -178,6 +196,18 @@ class class_t
|
||||
PyObject* instance_number_oct(PyObject*) const;
|
||||
PyObject* instance_number_hex(PyObject*) const;
|
||||
|
||||
PyObject* instance_number_inplace_add(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_and(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_or(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const;
|
||||
|
||||
private: // Implement rich comparisons
|
||||
PyObject* instance_lt(PyObject*, PyObject*) const;
|
||||
PyObject* instance_le(PyObject*, PyObject*) const;
|
||||
@@ -193,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<
|
||||
@@ -239,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
|
||||
{
|
||||
@@ -319,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
|
||||
@@ -493,6 +524,72 @@ PyObject* class_t<T>::instance_number_hex(PyObject* obj) const
|
||||
return downcast<T>(obj)->hex();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_add(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_add(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_subtract(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_subtract(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_multiply(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_multiply(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_divide(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_divide(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_remainder(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_remainder(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_power(exponent, modulus);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_lshift(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_lshift(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_rshift(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_rshift(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_and(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_and(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_or(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_or(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_xor(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_xor(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_lt(PyObject* obj, PyObject* other) 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>
|
||||
|
||||
@@ -74,17 +74,17 @@ inline void xdecref_impl(PyObject* p) { Py_XDECREF(p); }
|
||||
template <class T>
|
||||
inline void decref(T* p)
|
||||
{
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
decref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
decref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void xdecref(T* p)
|
||||
{
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
@@ -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)
|
||||
@@ -294,22 +301,22 @@ inline PyObject* to_python(float f)
|
||||
|
||||
inline PyObject* to_python(long l)
|
||||
{
|
||||
return PyInt_FromLong(l);
|
||||
return PyInt_FromLong(l);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(int x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(short x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(bool b)
|
||||
{
|
||||
return PyInt_FromLong(b);
|
||||
return PyInt_FromLong(b);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(void)
|
||||
@@ -319,7 +326,7 @@ inline PyObject* to_python(void)
|
||||
|
||||
inline PyObject* to_python(const char* s)
|
||||
{
|
||||
return PyString_FromString(s);
|
||||
return PyString_FromString(s);
|
||||
}
|
||||
|
||||
inline std::string from_python(PyObject* p, boost::python::type<const std::string&>)
|
||||
|
||||
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 {
|
||||
@@ -169,6 +171,9 @@ struct export_converter_object_noncopyable : export_converter_object_base<T>
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"to_python(const T&) converter not exported");
|
||||
throw import_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual T* from_python_Ts(PyObject* p, boost::python::type<T*> t) {
|
||||
@@ -229,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
|
||||
@@ -57,10 +57,113 @@
|
||||
# define BOOST_CSTD_ std
|
||||
# endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name()
|
||||
# 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()
|
||||
# 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()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Set up dll import/export options:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
// backwards compatibility:
|
||||
#ifdef BOOST_PYTHON_STATIC_LIB
|
||||
# define BOOST_PYTHON_STATIC_LINK
|
||||
#endif
|
||||
|
||||
#if defined(__MWERKS__) \
|
||||
|| (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730)
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|
||||
#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
|
||||
# else
|
||||
# define BOOST_PYTHON_DECL __declspec(dllimport)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_DECL
|
||||
# define BOOST_PYTHON_DECL
|
||||
#endif
|
||||
|
||||
#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_MODULE_INIT(name) extern "C" void init##name()
|
||||
# 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)
|
||||
// problems with std::basic_string and dll RTL:
|
||||
# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)
|
||||
# ifdef BOOST_PYTHON_BUILD_DLL
|
||||
# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL
|
||||
# else
|
||||
# pragma warn defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!
|
||||
# endif
|
||||
# endif
|
||||
# ifndef _RTLDLL
|
||||
// this is harmless for a static link:
|
||||
# define _RWSTD_COMPILE_INSTANTIATE
|
||||
# endif
|
||||
# endif
|
||||
//
|
||||
// VCL support:
|
||||
// if we're building a console app then there can't be any VCL (can there?)
|
||||
# if !defined(__CONSOLE__) && !defined(_NO_VCL)
|
||||
# define BOOST_PYTHON_USE_VCL
|
||||
# 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,26 +38,51 @@ 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;
|
||||
|
||||
meta_class<extension_instance>* extension_meta_class();
|
||||
extension_instance* get_extension_instance(PyObject* p);
|
||||
void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
void report_missing_class_object(const std::type_info&);
|
||||
void report_released_smart_pointer(const std::type_info&);
|
||||
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&);
|
||||
BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&);
|
||||
BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&);
|
||||
|
||||
template <class T>
|
||||
T* check_non_null(T* p)
|
||||
@@ -71,7 +96,7 @@ template <class Held> class held_instance;
|
||||
|
||||
typedef void* (*conversion_function_ptr)(void*);
|
||||
|
||||
struct base_class_info
|
||||
struct BOOST_PYTHON_DECL base_class_info
|
||||
{
|
||||
base_class_info(extension_class_base* t, conversion_function_ptr f)
|
||||
:class_object(t), convert(f)
|
||||
@@ -85,7 +110,7 @@ typedef base_class_info derived_class_info;
|
||||
|
||||
struct add_operator_base;
|
||||
|
||||
class extension_class_base : public class_t<extension_instance>
|
||||
class BOOST_PYTHON_DECL extension_class_base : public class_t<extension_instance>
|
||||
{
|
||||
public:
|
||||
extension_class_base(const char* name);
|
||||
@@ -233,6 +258,9 @@ class python_extension_class_converters
|
||||
}
|
||||
boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::python::argument_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Convert to T*
|
||||
@@ -261,6 +289,9 @@ class python_extension_class_converters
|
||||
}
|
||||
boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::python::argument_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return *(PtrType*)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Extract from obj a reference to the PtrType object which is holding a
|
||||
@@ -372,7 +403,7 @@ namespace detail {
|
||||
|
||||
template <class T> class instance_holder;
|
||||
|
||||
class read_only_setattr_function : public function
|
||||
class BOOST_PYTHON_DECL read_only_setattr_function : public function
|
||||
{
|
||||
public:
|
||||
read_only_setattr_function(const char* name);
|
||||
@@ -696,30 +727,85 @@ 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
|
||||
// instance_holder<>, below.
|
||||
class instance_holder_base
|
||||
class BOOST_PYTHON_DECL instance_holder_base
|
||||
{
|
||||
public:
|
||||
virtual ~instance_holder_base() {}
|
||||
@@ -807,21 +893,6 @@ class instance_ptr_holder : public instance_holder<HeldType>
|
||||
PtrType m_ptr;
|
||||
};
|
||||
|
||||
class 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
|
||||
//
|
||||
|
||||
@@ -29,7 +29,7 @@ class extension_instance;
|
||||
// function --
|
||||
// the common base class for all overloadable function and method objects
|
||||
// supplied by the library.
|
||||
class function : public python_object
|
||||
class BOOST_PYTHON_DECL function : public python_object
|
||||
{
|
||||
public:
|
||||
function();
|
||||
@@ -59,13 +59,13 @@ class function : public python_object
|
||||
template <class R, class F>
|
||||
struct wrapped_function_pointer : function
|
||||
{
|
||||
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
|
||||
|
||||
wrapped_function_pointer(ptr_fun pf)
|
||||
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
|
||||
|
||||
wrapped_function_pointer(ptr_fun pf)
|
||||
: m_pf(pf) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
// This is where the boundary between the uniform Python function
|
||||
// interface and the statically-checked C++ function interface is
|
||||
@@ -77,7 +77,7 @@ struct wrapped_function_pointer : function
|
||||
{ return typeid(F).name(); }
|
||||
|
||||
private:
|
||||
const ptr_fun m_pf;
|
||||
const ptr_fun m_pf;
|
||||
};
|
||||
|
||||
// raw_arguments_function
|
||||
@@ -87,13 +87,13 @@ struct wrapped_function_pointer : function
|
||||
template <class Ret, class Args, class Keywords>
|
||||
struct raw_arguments_function : function
|
||||
{
|
||||
typedef Ret (*ptr_fun)(Args, Keywords);
|
||||
|
||||
raw_arguments_function(ptr_fun pf)
|
||||
typedef Ret (*ptr_fun)(Args, Keywords);
|
||||
|
||||
raw_arguments_function(ptr_fun pf)
|
||||
: m_pf(pf) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
ref dict(keywords ?
|
||||
ref(keywords, ref::increment_count) :
|
||||
@@ -108,7 +108,7 @@ struct raw_arguments_function : function
|
||||
{ return typeid(ptr_fun).name(); }
|
||||
|
||||
private:
|
||||
const ptr_fun m_pf;
|
||||
const ptr_fun m_pf;
|
||||
};
|
||||
|
||||
// virtual_function<> --
|
||||
@@ -127,19 +127,19 @@ template <class T, class R, class V, class D>
|
||||
class virtual_function : public function
|
||||
{
|
||||
public:
|
||||
virtual_function(V virtual_function_ptr, D default_implementation)
|
||||
virtual_function(V virtual_function_ptr, D default_implementation)
|
||||
: m_virtual_function_ptr(virtual_function_ptr),
|
||||
m_default_implementation(default_implementation)
|
||||
{}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(V).name(); }
|
||||
|
||||
private:
|
||||
const V m_virtual_function_ptr;
|
||||
const V m_virtual_function_ptr;
|
||||
const D m_default_implementation;
|
||||
};
|
||||
|
||||
@@ -160,7 +160,7 @@ template <class F>
|
||||
inline function* new_wrapped_function(F pmf)
|
||||
{
|
||||
// Deduce the return type and pass it off to the helper function above
|
||||
return new_wrapped_function_aux(return_value(pmf), pmf);
|
||||
return new_wrapped_function_aux(return_value(pmf), pmf);
|
||||
}
|
||||
|
||||
template <class R, class Args, class keywords>
|
||||
@@ -201,7 +201,7 @@ inline function* new_virtual_function(
|
||||
// the expression a.b where a is an instance or extension_instance object and b
|
||||
// is a callable object not found in the obj namespace but on its class or
|
||||
// a base class.
|
||||
class bound_function : public python_object
|
||||
class BOOST_PYTHON_DECL bound_function : public python_object
|
||||
{
|
||||
public:
|
||||
static bound_function* create(const ref& target, const ref& fn);
|
||||
@@ -220,7 +220,7 @@ class bound_function : public python_object
|
||||
private: // data members for allocation/deallocation optimization
|
||||
bound_function* m_free_list_link;
|
||||
|
||||
static bound_function* free_list;
|
||||
static bound_function* free_list;
|
||||
};
|
||||
|
||||
// Special functions designed to access data members of a wrapped C++ object.
|
||||
|
||||
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;
|
||||
|
||||
@@ -230,7 +278,7 @@ struct init_function
|
||||
}
|
||||
};
|
||||
|
||||
class init : public function
|
||||
class BOOST_PYTHON_DECL init : public function
|
||||
{
|
||||
private: // override function hook
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
|
||||
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
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace boost { namespace python {
|
||||
namespace detail {
|
||||
// A stand-in for the built-in void. This one can be passed to functions and
|
||||
// (under MSVC, which has a bug, be used as a default template type parameter).
|
||||
struct void_t {};
|
||||
struct BOOST_PYTHON_DECL void_t {};
|
||||
}
|
||||
|
||||
// An envelope in which type information can be delivered for the purposes
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct empty {};
|
||||
struct BOOST_PYTHON_DECL empty {};
|
||||
template <class Derived, class Base = empty>
|
||||
struct singleton : Base
|
||||
{
|
||||
|
||||
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,13 +31,9 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class string;
|
||||
|
||||
namespace detail {
|
||||
|
||||
class instance_holder_base;
|
||||
|
||||
class type_object_base : public python_type
|
||||
class BOOST_PYTHON_DECL type_object_base : public python_type
|
||||
{
|
||||
public:
|
||||
explicit type_object_base(PyTypeObject* type_type);
|
||||
@@ -57,7 +53,11 @@ class type_object_base : public python_type
|
||||
number_positive, number_absolute, number_nonzero, number_invert,
|
||||
number_lshift, number_rshift, number_and, number_xor, number_or,
|
||||
number_coerce, number_int, number_long, number_float, number_oct,
|
||||
number_hex
|
||||
number_hex, number_inplace_add, number_inplace_subtract,
|
||||
number_inplace_multiply, number_inplace_divide,
|
||||
number_inplace_remainder, number_inplace_power,
|
||||
number_inplace_lshift, number_inplace_rshift,
|
||||
number_inplace_and, number_inplace_or, number_inplace_xor
|
||||
};
|
||||
|
||||
void enable(capability);
|
||||
@@ -116,6 +116,18 @@ class type_object_base : public python_type
|
||||
virtual PyObject* instance_number_oct(PyObject*) const;
|
||||
virtual PyObject* instance_number_hex(PyObject*) const;
|
||||
|
||||
virtual PyObject* instance_number_inplace_add(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_and(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_or(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const;
|
||||
|
||||
public: // Callbacks for rich comparisons
|
||||
virtual PyObject* instance_lt(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_le(PyObject*, PyObject*) const;
|
||||
@@ -311,7 +323,7 @@ PyObject* reprable<Base>::instance_repr(PyObject* obj) const
|
||||
// memory. Reference counting is used to free unused memory.
|
||||
// This is useful because method tables of related extension classes tend
|
||||
// to be identical, so less memory is needed for them.
|
||||
class shared_pod_manager
|
||||
class BOOST_PYTHON_DECL shared_pod_manager
|
||||
{
|
||||
typedef std::pair<char*, std::size_t> holder;
|
||||
typedef std::vector<holder> storage;
|
||||
@@ -378,7 +390,7 @@ PyObject* reprable<Base>::instance_repr(PyObject* obj) const
|
||||
};
|
||||
|
||||
|
||||
void add_capability(type_object_base::capability capability,
|
||||
BOOST_PYTHON_DECL void add_capability(type_object_base::capability capability,
|
||||
PyTypeObject* dest);
|
||||
|
||||
// This macro gets the length of an array as a compile-time constant, and will
|
||||
|
||||
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
|
||||
39
include/boost/python/detail/void_adaptor.hpp
Normal file
39
include/boost/python/detail/void_adaptor.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// (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.
|
||||
|
||||
#ifndef VOID_ADAPTOR_DWA20011112_HPP
|
||||
# define VOID_ADAPTOR_DWA20011112_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
extern BOOST_PYTHON_DECL PyObject arbitrary_object;
|
||||
|
||||
template <class T>
|
||||
struct void_adaptor
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
|
||||
void_adaptor(T const& f)
|
||||
: m_f(f)
|
||||
{}
|
||||
|
||||
PyObject* operator()() const
|
||||
{
|
||||
m_f();
|
||||
return &arbitrary_object;
|
||||
}
|
||||
private:
|
||||
T m_f;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void_adaptor<T> make_void_adaptor(T const& f)
|
||||
{
|
||||
return void_adaptor<T>(f);
|
||||
}
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // VOID_ADAPTOR_DWA20011112_HPP
|
||||
|
||||
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,35 +34,38 @@
|
||||
// Some things we need in order to get Python.h to work with compilers other
|
||||
// than MSVC on Win32
|
||||
//
|
||||
#if defined(_WIN32)
|
||||
# ifdef __GNUC__
|
||||
|
||||
#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 !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
|
||||
# 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_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
|
||||
# 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
|
||||
# define HAVE_LONG_LONG 1
|
||||
# define LONG_LONG long long
|
||||
# endif
|
||||
|
||||
# elif defined(__MWERKS__)
|
||||
|
||||
@@ -71,8 +74,25 @@ typedef int pid_t;
|
||||
# define _MSC_VER 900
|
||||
# endif
|
||||
|
||||
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
|
||||
# include <config.h>
|
||||
# else
|
||||
# include <pyconfig.h>
|
||||
# endif
|
||||
# undef hypot // undo the evil #define left by Python.
|
||||
|
||||
# elif defined(__BORLANDC__)
|
||||
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
|
||||
# include <config.h>
|
||||
# else
|
||||
# include <pyconfig.h>
|
||||
# endif
|
||||
# undef HAVE_HYPOT
|
||||
# define HAVE_HYPOT 1
|
||||
# elif defined(_MSC_VER)
|
||||
# include <limits> // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX
|
||||
# ifdef __cplusplus
|
||||
# include <limits> // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif // _WIN32
|
||||
@@ -90,5 +110,11 @@ typedef int pid_t;
|
||||
|
||||
#if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2
|
||||
# define PyObject_INIT(op, typeobj) \
|
||||
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
|
||||
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
# pragma warn_possunwant off
|
||||
#elif _MSC_VER
|
||||
# pragma warning(disable:4786)
|
||||
#endif
|
||||
|
||||
@@ -9,20 +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 {};
|
||||
|
||||
// Handles exceptions caught just before returning to Python code.
|
||||
void handle_exception();
|
||||
// Returns true iff an exception was caught.
|
||||
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>);
|
||||
|
||||
template <class T>
|
||||
bool handle_exception(T f)
|
||||
{
|
||||
return handle_exception_impl(function0<void>(boost::ref(f)));
|
||||
}
|
||||
|
||||
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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user