mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
Compare commits
10 Commits
boost-1.21
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dcb0b1996 | ||
|
|
de57613c7e | ||
|
|
ade195b9ac | ||
|
|
daf0865cdf | ||
|
|
2fa4bb7410 | ||
|
|
6db04861ed | ||
|
|
dac8e861c8 | ||
|
|
f0a0e9ec02 | ||
|
|
4d3079293d | ||
|
|
9261e2a3d9 |
@@ -1,10 +1,12 @@
|
||||
# Revision History:
|
||||
# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) UNTESTED!
|
||||
# 06 Mar 01 Fixed typo in use of "PYTHON_LIB" (Dave Abrahams)
|
||||
# 04 Mar 01 Changed library name to libboost_python.a (David Abrahams)
|
||||
|
||||
LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
@@ -34,11 +36,12 @@ endif
|
||||
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
example1: example1.o libboost_python.a
|
||||
como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYTHON_LIB) example1.o -L. -lboost_python
|
||||
python ../example/test_example1.py
|
||||
getting_started1: getting_started1.o libboost_python.a
|
||||
como-dyn-link -o ../example/getting_started1.$(MODULE_EXTENSION) $(PYTHON_LIB) getting_started1.o -L. -lboost_python
|
||||
ln -s ../test/doctest.py ../example
|
||||
python ../example/test_getting_started1.py
|
||||
|
||||
example1.o: ../example/example1.cpp
|
||||
getting_started1.o: ../example/getting_started1.cpp
|
||||
como --pic $(INC) -o $*.o -c $<
|
||||
|
||||
clean:
|
||||
|
||||
132
build/filemgr.py
Normal file
132
build/filemgr.py
Normal file
@@ -0,0 +1,132 @@
|
||||
# Revision history:
|
||||
# 12 Apr 01 use os.path, shutil
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
bpl_src = "/libs/python/src"
|
||||
bpl_tst = "/libs/python/test"
|
||||
bpl_exa = "/libs/python/example"
|
||||
files = (
|
||||
bpl_src + "/classes.cpp",
|
||||
bpl_src + "/conversions.cpp",
|
||||
bpl_src + "/extension_class.cpp",
|
||||
bpl_src + "/functions.cpp",
|
||||
bpl_src + "/init_function.cpp",
|
||||
bpl_src + "/module_builder.cpp",
|
||||
bpl_src + "/objects.cpp",
|
||||
bpl_src + "/types.cpp",
|
||||
bpl_src + "/cross_module.cpp",
|
||||
bpl_tst + "/comprehensive.cpp",
|
||||
bpl_tst + "/comprehensive.hpp",
|
||||
bpl_tst + "/comprehensive.py",
|
||||
bpl_tst + "/doctest.py",
|
||||
bpl_exa + "/abstract.cpp",
|
||||
bpl_exa + "/getting_started1.cpp",
|
||||
bpl_exa + "/getting_started2.cpp",
|
||||
bpl_exa + "/simple_vector.cpp",
|
||||
bpl_exa + "/do_it_yourself_converters.cpp",
|
||||
bpl_exa + "/pickle1.cpp",
|
||||
bpl_exa + "/pickle2.cpp",
|
||||
bpl_exa + "/pickle3.cpp",
|
||||
bpl_exa + "/test_abstract.py",
|
||||
bpl_exa + "/test_getting_started1.py",
|
||||
bpl_exa + "/test_getting_started2.py",
|
||||
bpl_exa + "/test_simple_vector.py",
|
||||
bpl_exa + "/test_do_it_yourself_converters.py",
|
||||
bpl_exa + "/test_pickle1.py",
|
||||
bpl_exa + "/test_pickle2.py",
|
||||
bpl_exa + "/test_pickle3.py",
|
||||
bpl_exa + "/noncopyable.h",
|
||||
bpl_exa + "/noncopyable_export.cpp",
|
||||
bpl_exa + "/noncopyable_import.cpp",
|
||||
bpl_exa + "/dvect.h",
|
||||
bpl_exa + "/dvect.cpp",
|
||||
bpl_exa + "/dvect_conversions.cpp",
|
||||
bpl_exa + "/dvect_defs.cpp",
|
||||
bpl_exa + "/ivect.h",
|
||||
bpl_exa + "/ivect.cpp",
|
||||
bpl_exa + "/ivect_conversions.cpp",
|
||||
bpl_exa + "/ivect_defs.cpp",
|
||||
bpl_exa + "/tst_noncopyable.py",
|
||||
bpl_exa + "/tst_dvect1.py",
|
||||
bpl_exa + "/tst_dvect2.py",
|
||||
bpl_exa + "/tst_ivect1.py",
|
||||
bpl_exa + "/tst_ivect2.py",
|
||||
bpl_exa + "/test_cross_module.py",
|
||||
)
|
||||
|
||||
defs = (
|
||||
"boost_python_test",
|
||||
"abstract",
|
||||
"getting_started1",
|
||||
"getting_started2",
|
||||
"simple_vector",
|
||||
"do_it_yourself_converters",
|
||||
"pickle1",
|
||||
"pickle2",
|
||||
"pickle3",
|
||||
"noncopyable_export",
|
||||
"noncopyable_import",
|
||||
"ivect",
|
||||
"dvect",
|
||||
)
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
|
||||
import sys, os, shutil
|
||||
|
||||
path = sys.argv[1]
|
||||
mode = sys.argv[2]
|
||||
if (not mode in ("softlinks", "unlink", "cp", "rm", "copy", "del")):
|
||||
raise RuntimeError, \
|
||||
"usage: python filemgr.py path <softlinks|unlink|cp|rm|copy|del>"
|
||||
|
||||
if (mode in ("cp", "copy")):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
print "Copying: " + f
|
||||
shutil.copy(path + fn, ".")
|
||||
|
||||
elif (mode == "softlinks"):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
if (os.path.exists(f)):
|
||||
print "File exists: " + f
|
||||
else:
|
||||
print "Linking: " + f
|
||||
os.symlink(path + fn, f)
|
||||
|
||||
elif (mode in ("rm", "del")):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
if (os.path.exists(f)):
|
||||
print "Removing: " + f
|
||||
try: os.unlink(f)
|
||||
except: pass
|
||||
|
||||
elif (mode == "unlink"):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
if (os.path.exists(f)):
|
||||
if (os.path.islink(f)):
|
||||
print "Unlinking: " + f
|
||||
try: os.unlink(f)
|
||||
except: pass
|
||||
else:
|
||||
print "Not a softlink: " + f
|
||||
|
||||
if (mode in ("softlinks", "cp", "copy")):
|
||||
for d in defs:
|
||||
fn = d + ".def"
|
||||
print "Creating: " + fn
|
||||
f = open(fn, "w")
|
||||
f.write("EXPORTS\n")
|
||||
f.write("\tinit" + d + "\n")
|
||||
f.close()
|
||||
|
||||
if (mode in ("unlink", "rm", "del")):
|
||||
for d in defs:
|
||||
fn = d + ".def"
|
||||
if (os.path.exists(fn)):
|
||||
print "Removing: " + fn
|
||||
try: os.unlink(fn)
|
||||
except: pass
|
||||
@@ -1,5 +1,7 @@
|
||||
# Revision History
|
||||
|
||||
# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve)
|
||||
# 17 Apr 01 build shared library (patch provided by Dan Nuffer)
|
||||
# 04 Mar 01 Changed library name to libboost_python.a, various cleanups,
|
||||
# attempted Cygwin compatibility. Still needs testing on Linux
|
||||
# (David Abrahams)
|
||||
@@ -8,6 +10,7 @@
|
||||
LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
@@ -18,7 +21,7 @@ LIBSRC = \
|
||||
LIBOBJ = $(LIBSRC:.cpp=.o)
|
||||
OBJ = $(LIBOBJ)
|
||||
|
||||
PYTHON_INC=$(ROOT)/usr/local/include/python2.0
|
||||
LIBNAME = libboost_python
|
||||
# libpython2.0.dll
|
||||
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
@@ -26,13 +29,18 @@ ROOT=c:/cygnus
|
||||
INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -I$(PYTHON_INC)
|
||||
MODULE_EXTENSION=dll
|
||||
PYTHON_LIB=c:/cygnus/usr/local/lib/python2.0/config/libpython2.0.dll.a
|
||||
SHARED_LIB = $(LIBNAME).dll
|
||||
else
|
||||
INC = -I$(PYTHON_INC)
|
||||
PYTHON_INC=$(ROOT)/usr/local/Python-2.0/include/python2.0
|
||||
BOOST_INC=../../..
|
||||
INC = -I$(BOOST_INC) -I$(PYTHON_INC)
|
||||
MODULE_EXTENSION=so
|
||||
VERSION=1
|
||||
SHARED_LIB = $(LIBNAME).so.$(VERSION)
|
||||
endif
|
||||
|
||||
%.o: ../src/%.cpp
|
||||
g++ -fPIC -Wall -W $(INC) -o $*.o -c $<
|
||||
g++ -fPIC -Wall -W $(INC) $(CXXFLAGS) -o $*.o -c $<
|
||||
|
||||
%.d: ../src/%.cpp
|
||||
@echo creating $@
|
||||
@@ -43,7 +51,9 @@ endif
|
||||
|
||||
PYTHON = python
|
||||
|
||||
test: comprehensive.o libboost_python.a
|
||||
all: test $(SHARED_LIB) getting_started1
|
||||
|
||||
test: comprehensive.o $(LIBNAME).a $(SHARED_LIB)
|
||||
g++ $(CXXFLAGS) -shared -o ../test/boost_python_test.$(MODULE_EXTENSION) comprehensive.o -L. -lboost_python $(PYTHON_LIB)
|
||||
$(PYTHON) ../test/comprehensive.py
|
||||
|
||||
@@ -51,20 +61,24 @@ comprehensive.o: ../test/comprehensive.cpp
|
||||
g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $<
|
||||
|
||||
|
||||
example1: example1.o libboost_python.a
|
||||
g++ $(CXXFLAGS) -shared -o ../example/hellomodule.$(MODULE_EXTENSION) example1.o -L. -lboost_python $(PYTHON_LIB)
|
||||
$(PYTHON) ../example/test_example1.py
|
||||
getting_started1: getting_started1.o $(LIBNAME).a
|
||||
g++ $(CXXFLAGS) -shared -o ../example/getting_started1.$(MODULE_EXTENSION) getting_started1.o -L. -lboost_python $(PYTHON_LIB)
|
||||
ln -s ../test/doctest.py ../example
|
||||
$(PYTHON) ../example/test_getting_started1.py
|
||||
|
||||
example1.o: ../example/example1.cpp
|
||||
getting_started1.o: ../example/getting_started1.cpp
|
||||
g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out
|
||||
|
||||
libboost_python.a: $(LIBOBJ)
|
||||
rm -f libboost_python.a
|
||||
ar cq libboost_python.a $(LIBOBJ)
|
||||
$(LIBNAME).a: $(LIBOBJ)
|
||||
rm -f $@
|
||||
ar cqs $@ $(LIBOBJ)
|
||||
|
||||
$(SHARED_LIB): $(LIBOBJ)
|
||||
g++ $(CXXFLAGS) -shared -o $@ -Wl,--soname=$(LIBNAME).$(MODULE_EXTENSION)
|
||||
|
||||
DEP = $(OBJ:.o=.d)
|
||||
|
||||
|
||||
160
build/irix_CC.mak
Normal file
160
build/irix_CC.mak
Normal file
@@ -0,0 +1,160 @@
|
||||
# Usage:
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Adjust the pathnames below.
|
||||
#
|
||||
# make softlinks Create softlinks to source code and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make unlink Remove softlinks
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
||||
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
|
||||
|
||||
STDOPTS=
|
||||
WARNOPTS=-woff 1001,1234,1682
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP=CC -LANG:std -n32 -mips4
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
MAKEDEP=-M
|
||||
|
||||
LD=CC -LANG:std -n32 -mips4
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
comprehensive.o \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a \
|
||||
boost_python_test.so \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
$(CPP) -ar -o libboost_python.a $(OBJ)
|
||||
|
||||
boost_python_test.so: $(OBJ) comprehensive.o
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm
|
||||
|
||||
abstract.so: $(OBJ) abstract.o
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so
|
||||
|
||||
getting_started1.so: $(OBJ) getting_started1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so
|
||||
|
||||
getting_started2.so: $(OBJ) getting_started2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so
|
||||
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so
|
||||
|
||||
pickle1.so: $(OBJ) pickle1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so
|
||||
|
||||
pickle2.so: $(OBJ) pickle2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so
|
||||
|
||||
pickle3.so: $(OBJ) pickle3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so
|
||||
|
||||
noncopyable_export.so: $(OBJ) noncopyable_export.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_export.o -o noncopyable_export.so
|
||||
|
||||
noncopyable_import.so: $(OBJ) noncopyable_import.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_import.o -o noncopyable_import.so
|
||||
|
||||
ivect.so: $(OBJ) ivect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so
|
||||
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
.cpp.o:
|
||||
$(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_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
rm -f comprehensive.o boost_python_test.so
|
||||
rm -f abstract.o abstract.so
|
||||
rm -f getting_started1.o getting_started1.so
|
||||
rm -f getting_started2.o getting_started2.so
|
||||
rm -f simple_vector.o simple_vector.so
|
||||
rm -f do_it_yourself_converters.o do_it_yourself_converters.so
|
||||
rm -f pickle1.o pickle1.so
|
||||
rm -f pickle2.o pickle2.so
|
||||
rm -f pickle3.o pickle3.so
|
||||
rm -f noncopyable_export.o noncopyable_export.so
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf ii_files
|
||||
|
||||
softlinks:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks
|
||||
|
||||
unlink:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink
|
||||
|
||||
cp:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp
|
||||
|
||||
rm:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm
|
||||
|
||||
depend:
|
||||
@ cat Makefile.nodepend; \
|
||||
for obj in $(DEPOBJ); \
|
||||
do \
|
||||
bn=`echo "$$obj" | cut -d. -f1`; \
|
||||
$(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \
|
||||
done
|
||||
|
||||
@@ -2,110 +2,64 @@
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Set the BOOST pathname below.
|
||||
# Adjust the pathnames below.
|
||||
#
|
||||
# make softlinks Create softlinks to source code and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make unlink Remove softlinks
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
BOOST= /net/cci/rwgk/boost
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE= /usr/local/Python-1.5.2/bin/python
|
||||
PYINC= -I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE= /usr/local/Python-2.0/bin/python
|
||||
#PYINC= -I/usr/local/Python-2.0/include/python2.0
|
||||
#STLPORTINC= -I/usr/local/STLport-4.1b3/stlport
|
||||
#STLPORTOPTS= \
|
||||
# -D__USE_STD_IOSTREAM \
|
||||
# -D__STL_NO_SGI_IOSTREAMS \
|
||||
# -D__STL_USE_NATIVE_STRING \
|
||||
# -D__STL_NO_NEW_C_HEADERS \
|
||||
# -D_RWSTD_COMPILE_INSTANTIATE=1
|
||||
#STLPORTINC= -I/usr/local/STLport-4.1b4/stlport
|
||||
#STLPORTOPTS= -D__NO_USE_STD_IOSTREAM -D__STL_NO_SGI_IOSTREAMS
|
||||
#STLPORTINC= -I/net/cci/xp/C++_C_headers
|
||||
PYEXE=PYTHONPATH=. /usr/bin/python
|
||||
PYINC=-I/usr/include/python1.5
|
||||
#PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
||||
|
||||
STDOPTS= -ftemplate-depth-21
|
||||
STDOPTS=-ftemplate-depth-21 -fPIC
|
||||
WARNOPTS=
|
||||
# use -msg_display_number to obtain integer tags for -msg_disable
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP= g++
|
||||
CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) -g
|
||||
MAKEDEP= -M
|
||||
CPP=g++
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
MAKEDEP=-M
|
||||
|
||||
LD= g++
|
||||
LDOPTS= -shared
|
||||
LD=$(CPP)
|
||||
LDOPTS=-shared
|
||||
|
||||
#HIDDEN= -hidden
|
||||
|
||||
BPL_SRC = $(BOOST)/libs/python/src
|
||||
BPL_TST = $(BOOST)/libs/python/test
|
||||
BPL_EXA = $(BOOST)/libs/python/example
|
||||
SOFTLINKS = \
|
||||
$(BPL_SRC)/classes.cpp \
|
||||
$(BPL_SRC)/conversions.cpp \
|
||||
$(BPL_SRC)/extension_class.cpp \
|
||||
$(BPL_SRC)/functions.cpp \
|
||||
$(BPL_SRC)/init_function.cpp \
|
||||
$(BPL_SRC)/module_builder.cpp \
|
||||
$(BPL_SRC)/objects.cpp \
|
||||
$(BPL_SRC)/types.cpp \
|
||||
$(BPL_TST)/comprehensive.cpp \
|
||||
$(BPL_TST)/comprehensive.hpp \
|
||||
$(BPL_TST)/comprehensive.py \
|
||||
$(BPL_TST)/doctest.py \
|
||||
$(BPL_EXA)/abstract.cpp \
|
||||
$(BPL_EXA)/getting_started1.cpp \
|
||||
$(BPL_EXA)/getting_started2.cpp \
|
||||
$(BPL_EXA)/getting_started3.cpp \
|
||||
$(BPL_EXA)/getting_started4.cpp \
|
||||
$(BPL_EXA)/getting_started5.cpp \
|
||||
$(BPL_EXA)/test_abstract.py \
|
||||
$(BPL_EXA)/test_getting_started1.py \
|
||||
$(BPL_EXA)/test_getting_started2.py \
|
||||
$(BPL_EXA)/test_getting_started3.py \
|
||||
$(BPL_EXA)/test_getting_started4.py \
|
||||
$(BPL_EXA)/test_getting_started5.py
|
||||
|
||||
OBJ = classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o
|
||||
DEPOBJ= $(OBJ) comprehensive.o abstract.o \
|
||||
getting_started1.o getting_started2.o getting_started3.o \
|
||||
getting_started4.o getting_started5.o
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
comprehensive.o \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a boost_python_test.so abstract.so \
|
||||
getting_started1.so getting_started2.so getting_started3.so \
|
||||
getting_started4.so getting_started5.so
|
||||
|
||||
softlinks:
|
||||
@ for pn in $(SOFTLINKS); \
|
||||
do \
|
||||
bn=`basename "$$pn"`; \
|
||||
if [ ! -e "$$bn" ]; then \
|
||||
echo "ln -s $$pn ."; \
|
||||
ln -s "$$pn" .; \
|
||||
else \
|
||||
echo "info: no softlink created (file exists): $$bn"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
unlink:
|
||||
@ for pn in $(SOFTLINKS); \
|
||||
do \
|
||||
bn=`basename "$$pn"`; \
|
||||
if [ -L "$$bn" ]; then \
|
||||
echo "rm $$bn"; \
|
||||
rm "$$bn"; \
|
||||
elif [ -e "$$bn" ]; then \
|
||||
echo "info: not a softlink: $$bn"; \
|
||||
fi; \
|
||||
done
|
||||
all: libboost_python.a \
|
||||
boost_python_test.so \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
@@ -123,14 +77,34 @@ getting_started1.so: $(OBJ) getting_started1.o
|
||||
getting_started2.so: $(OBJ) getting_started2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so
|
||||
|
||||
getting_started3.so: $(OBJ) getting_started3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
getting_started4.so: $(OBJ) getting_started4.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started4.o -o getting_started4.so
|
||||
do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so
|
||||
|
||||
getting_started5.so: $(OBJ) getting_started5.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started5.o -o getting_started5.so
|
||||
pickle1.so: $(OBJ) pickle1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so
|
||||
|
||||
pickle2.so: $(OBJ) pickle2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so
|
||||
|
||||
pickle3.so: $(OBJ) pickle3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so
|
||||
|
||||
noncopyable_export.so: $(OBJ) noncopyable_export.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_export.o -o noncopyable_export.so
|
||||
|
||||
noncopyable_import.so: $(OBJ) noncopyable_import.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_import.o -o noncopyable_import.so
|
||||
|
||||
ivect.so: $(OBJ) ivect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so
|
||||
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
@@ -140,9 +114,12 @@ test:
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_getting_started3.py
|
||||
$(PYEXE) test_getting_started4.py
|
||||
$(PYEXE) test_getting_started5.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
@@ -150,11 +127,28 @@ clean:
|
||||
rm -f abstract.o abstract.so
|
||||
rm -f getting_started1.o getting_started1.so
|
||||
rm -f getting_started2.o getting_started2.so
|
||||
rm -f getting_started3.o getting_started3.so
|
||||
rm -f getting_started4.o getting_started4.so
|
||||
rm -f getting_started5.o getting_started5.so
|
||||
rm -f simple_vector.o simple_vector.so
|
||||
rm -f do_it_yourself_converters.o do_it_yourself_converters.so
|
||||
rm -f pickle1.o pickle1.so
|
||||
rm -f pickle2.o pickle2.so
|
||||
rm -f pickle3.o pickle3.so
|
||||
rm -f noncopyable_export.o noncopyable_export.so
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf cxx_repository
|
||||
|
||||
softlinks:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks
|
||||
|
||||
unlink:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink
|
||||
|
||||
cp:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp
|
||||
|
||||
rm:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm
|
||||
|
||||
depend:
|
||||
@ cat Makefile.nodepend; \
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
# Usage:
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Set the BOOST_* pathnames below.
|
||||
# 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
|
||||
#
|
||||
# The idea is that the build directory is on a Unix filesystem that
|
||||
# is mounted on a PC using SAMBA. Use this makefile under both Unix
|
||||
# and Windows:
|
||||
#
|
||||
# Unix: make softlinks Create softlinks to source code and tests
|
||||
# Win: make Compile all sources
|
||||
# Win: make test Run doctest tests
|
||||
# Unix: make clean Remove all object files
|
||||
# Unix: make unlink Remove softlinks
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
# To install mingw32, follow instructions at:
|
||||
# http://starship.python.net/crew/kernr/mingw32/Notes.html
|
||||
@@ -31,117 +27,49 @@
|
||||
# Could this be fixed with compiler options?
|
||||
# -fhuge-objects looks interesting, but requires recompiling the C++ library.
|
||||
# (what exactly does that mean?)
|
||||
# -fvtable-thunks eliminates the compiler warning,
|
||||
# but "import boost_python_test" still causes a crash.
|
||||
# -fvtable-thunks eliminates the compiler warning, but
|
||||
# "import boost_python_test" still causes a crash.
|
||||
|
||||
BOOST_UNIX= /net/cci/rwgk/boost
|
||||
BOOST_WIN= "L:\boost"
|
||||
ROOT=L:
|
||||
BOOST_WIN="$(ROOT)\boost"
|
||||
BOOST_UNIX=$(HOME)/boost
|
||||
|
||||
PYEXE= "C:\Program files\Python\python.exe"
|
||||
PYINC= -I"C:\usr\include\python1.5"
|
||||
PYLIB= "C:\usr\lib\libpython15.a"
|
||||
PYEXE="C:\Program files\Python\python.exe"
|
||||
PYINC=-I"C:\usr\include\python1.5"
|
||||
PYLIB="C:\usr\lib\libpython15.a"
|
||||
|
||||
STDOPTS= -ftemplate-depth-21
|
||||
STDOPTS=-ftemplate-depth-21
|
||||
WARNOPTS=
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP= g++
|
||||
CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) -g
|
||||
CPP=g++
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
|
||||
LD= g++
|
||||
LDOPTS= -shared
|
||||
LD=g++
|
||||
LDOPTS=-shared
|
||||
|
||||
BPL_SRC = $(BOOST_UNIX)/libs/python/src
|
||||
BPL_TST = $(BOOST_UNIX)/libs/python/test
|
||||
BPL_EXA = $(BOOST_UNIX)/libs/python/example
|
||||
SOFTLINKS = \
|
||||
$(BPL_SRC)/classes.cpp \
|
||||
$(BPL_SRC)/conversions.cpp \
|
||||
$(BPL_SRC)/extension_class.cpp \
|
||||
$(BPL_SRC)/functions.cpp \
|
||||
$(BPL_SRC)/init_function.cpp \
|
||||
$(BPL_SRC)/module_builder.cpp \
|
||||
$(BPL_SRC)/objects.cpp \
|
||||
$(BPL_SRC)/types.cpp \
|
||||
$(BPL_TST)/comprehensive.cpp \
|
||||
$(BPL_TST)/comprehensive.hpp \
|
||||
$(BPL_TST)/comprehensive.py \
|
||||
$(BPL_TST)/doctest.py \
|
||||
$(BPL_EXA)/abstract.cpp \
|
||||
$(BPL_EXA)/getting_started1.cpp \
|
||||
$(BPL_EXA)/getting_started2.cpp \
|
||||
$(BPL_EXA)/getting_started3.cpp \
|
||||
$(BPL_EXA)/getting_started4.cpp \
|
||||
$(BPL_EXA)/getting_started5.cpp \
|
||||
$(BPL_EXA)/passing_char.cpp \
|
||||
$(BPL_EXA)/test_abstract.py \
|
||||
$(BPL_EXA)/test_getting_started1.py \
|
||||
$(BPL_EXA)/test_getting_started2.py \
|
||||
$(BPL_EXA)/test_getting_started3.py \
|
||||
$(BPL_EXA)/test_getting_started4.py \
|
||||
$(BPL_EXA)/test_getting_started5.py
|
||||
|
||||
DEFS= \
|
||||
boost_python_test \
|
||||
abstract \
|
||||
getting_started1 \
|
||||
getting_started2 \
|
||||
getting_started3 \
|
||||
getting_started4 \
|
||||
getting_started5
|
||||
|
||||
OBJ = classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a boost_python_test.pyd abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd getting_started3.pyd \
|
||||
getting_started4.pyd getting_started5.pyd
|
||||
|
||||
softlinks: defs
|
||||
@ for pn in $(SOFTLINKS); \
|
||||
do \
|
||||
bn=`basename "$$pn"`; \
|
||||
if [ ! -e "$$bn" ]; then \
|
||||
echo "ln -s $$pn ."; \
|
||||
ln -s "$$pn" .; \
|
||||
else \
|
||||
echo "info: no softlink created (file exists): $$bn"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
unlink: rmdefs
|
||||
@ for pn in $(SOFTLINKS); \
|
||||
do \
|
||||
bn=`basename "$$pn"`; \
|
||||
if [ -L "$$bn" ]; then \
|
||||
echo "rm $$bn"; \
|
||||
rm "$$bn"; \
|
||||
elif [ -e "$$bn" ]; then \
|
||||
echo "info: not a softlink: $$bn"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
defs:
|
||||
@ for def in $(DEFS); \
|
||||
do \
|
||||
echo "EXPORTS\n\tinit$$def" > $$def.def; \
|
||||
done
|
||||
|
||||
rmdefs:
|
||||
@ for def in $(DEFS); \
|
||||
do \
|
||||
rm $$def.def; \
|
||||
done
|
||||
all: libboost_python.a \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_converters.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
del libboost_python.a
|
||||
ar r libboost_python.a $(OBJ)
|
||||
|
||||
DLLWRAPOPTS= -s --driver-name g++ -s
|
||||
--entry _DllMainCRTStartup@12 --target=i386-mingw32
|
||||
DLLWRAPOPTS=-s --driver-name g++ -s \
|
||||
--entry _DllMainCRTStartup@12 --target=i386-mingw32
|
||||
|
||||
boost_python_test.pyd: $(OBJ) comprehensive.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
@@ -167,44 +95,95 @@ getting_started2.pyd: $(OBJ) getting_started2.o
|
||||
--def getting_started2.def \
|
||||
$(OBJ) getting_started2.o $(PYLIB)
|
||||
|
||||
getting_started3.pyd: $(OBJ) getting_started3.o
|
||||
simple_vector.pyd: $(OBJ) simple_vector.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname getting_started3.pyd \
|
||||
--def getting_started3.def \
|
||||
$(OBJ) getting_started3.o $(PYLIB)
|
||||
--dllname simple_vector.pyd \
|
||||
--def simple_vector.def \
|
||||
$(OBJ) simple_vector.o $(PYLIB)
|
||||
|
||||
getting_started4.pyd: $(OBJ) getting_started4.o
|
||||
do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname getting_started4.pyd \
|
||||
--def getting_started4.def \
|
||||
$(OBJ) getting_started4.o $(PYLIB)
|
||||
--dllname do_it_yourself_converters.pyd \
|
||||
--def do_it_yourself_converters.def \
|
||||
$(OBJ) do_it_yourself_converters.o $(PYLIB)
|
||||
|
||||
getting_started5.pyd: $(OBJ) getting_started5.o
|
||||
pickle1.pyd: $(OBJ) pickle1.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname getting_started5.pyd \
|
||||
--def getting_started5.def \
|
||||
$(OBJ) getting_started5.o $(PYLIB)
|
||||
--dllname pickle1.pyd \
|
||||
--def pickle1.def \
|
||||
$(OBJ) pickle1.o $(PYLIB)
|
||||
|
||||
pickle2.pyd: $(OBJ) pickle2.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname pickle2.pyd \
|
||||
--def pickle2.def \
|
||||
$(OBJ) pickle2.o $(PYLIB)
|
||||
|
||||
pickle3.pyd: $(OBJ) pickle3.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname pickle3.pyd \
|
||||
--def pickle3.def \
|
||||
$(OBJ) pickle3.o $(PYLIB)
|
||||
|
||||
noncopyable_export.pyd: $(OBJ) noncopyable_export.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname noncopyable_export.pyd \
|
||||
--def noncopyable_export.def \
|
||||
$(OBJ) noncopyable_export.o $(PYLIB)
|
||||
|
||||
noncopyable_import.pyd: $(OBJ) noncopyable_import.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname noncopyable_import.pyd \
|
||||
--def noncopyable_import.def \
|
||||
$(OBJ) noncopyable_import.o $(PYLIB)
|
||||
|
||||
ivect.pyd: $(OBJ) ivect.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname ivect.pyd \
|
||||
--def ivect.def \
|
||||
$(OBJ) ivect.o $(PYLIB)
|
||||
|
||||
dvect.pyd: $(OBJ) dvect.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname dvect.pyd \
|
||||
--def dvect.def \
|
||||
$(OBJ) dvect.o $(PYLIB)
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py
|
||||
# $(PYEXE) comprehensive.py
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_getting_started3.py
|
||||
$(PYEXE) test_getting_started4.py
|
||||
$(PYEXE) test_getting_started5.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
rm -f comprehensive.o boost_python_test.pyd
|
||||
rm -f abstract.o abstract.pyd
|
||||
rm -f getting_started1.o getting_started1.pyd
|
||||
rm -f getting_started2.o getting_started2.pyd
|
||||
rm -f getting_started3.o getting_started3.pyd
|
||||
rm -f getting_started4.o getting_started4.pyd
|
||||
rm -f getting_started5.o getting_started5.pyd
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf cxx_repository
|
||||
del *.o
|
||||
del *.a
|
||||
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,110 +2,74 @@
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Set the BOOST pathname below.
|
||||
# Adjust the pathnames below.
|
||||
#
|
||||
# make softlinks Create softlinks to source code and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make unlink Remove softlinks
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
BOOST= /net/cci/rwgk/boost
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE= /usr/local/Python-1.5.2/bin/python
|
||||
PYINC= -I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE= /usr/local/Python-2.0/bin/python
|
||||
#PYINC= -I/usr/local/Python-2.0/include/python2.0
|
||||
#STLPORTINC= -I/usr/local/STLport-4.1b3/stlport
|
||||
PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
||||
#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport
|
||||
#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport
|
||||
#STLPORTOPTS= \
|
||||
# -D__USE_STD_IOSTREAM \
|
||||
# -D__STL_NO_SGI_IOSTREAMS \
|
||||
# -D__STL_USE_NATIVE_STRING \
|
||||
# -D__STL_NO_NEW_C_HEADERS \
|
||||
# -D_RWSTD_COMPILE_INSTANTIATE=1
|
||||
#STLPORTINC= -I/usr/local/STLport-4.1b4/stlport
|
||||
#STLPORTOPTS= -D__NO_USE_STD_IOSTREAM -D__STL_NO_SGI_IOSTREAMS
|
||||
STLPORTINC= -I/net/cci/xp/C++_C_headers
|
||||
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
|
||||
|
||||
STDOPTS= -std strict_ansi
|
||||
WARNOPTS= -msg_disable 186,450,1115
|
||||
STDOPTS=-std strict_ansi
|
||||
# use -msg_display_number to obtain integer tags for -msg_disable
|
||||
WARNOPTS=-msg_disable 186,450,1115
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP= cxx
|
||||
CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) -g
|
||||
MAKEDEP= -Em
|
||||
CPP=cxx
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
MAKEDEP=-Em
|
||||
|
||||
LD= cxx
|
||||
LDOPTS= -shared -expect_unresolved 'Py*' -expect_unresolved '_Py*'
|
||||
LD=cxx
|
||||
LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*'
|
||||
|
||||
#HIDDEN= -hidden
|
||||
#HIDDEN=-hidden
|
||||
|
||||
BPL_SRC = $(BOOST)/libs/python/src
|
||||
BPL_TST = $(BOOST)/libs/python/test
|
||||
BPL_EXA = $(BOOST)/libs/python/example
|
||||
SOFTLINKS = \
|
||||
$(BPL_SRC)/classes.cpp \
|
||||
$(BPL_SRC)/conversions.cpp \
|
||||
$(BPL_SRC)/extension_class.cpp \
|
||||
$(BPL_SRC)/functions.cpp \
|
||||
$(BPL_SRC)/init_function.cpp \
|
||||
$(BPL_SRC)/module_builder.cpp \
|
||||
$(BPL_SRC)/objects.cpp \
|
||||
$(BPL_SRC)/types.cpp \
|
||||
$(BPL_TST)/comprehensive.cpp \
|
||||
$(BPL_TST)/comprehensive.hpp \
|
||||
$(BPL_TST)/comprehensive.py \
|
||||
$(BPL_TST)/doctest.py \
|
||||
$(BPL_EXA)/abstract.cpp \
|
||||
$(BPL_EXA)/getting_started1.cpp \
|
||||
$(BPL_EXA)/getting_started2.cpp \
|
||||
$(BPL_EXA)/getting_started3.cpp \
|
||||
$(BPL_EXA)/getting_started4.cpp \
|
||||
$(BPL_EXA)/getting_started5.cpp \
|
||||
$(BPL_EXA)/test_abstract.py \
|
||||
$(BPL_EXA)/test_getting_started1.py \
|
||||
$(BPL_EXA)/test_getting_started2.py \
|
||||
$(BPL_EXA)/test_getting_started3.py \
|
||||
$(BPL_EXA)/test_getting_started4.py \
|
||||
$(BPL_EXA)/test_getting_started5.py
|
||||
|
||||
OBJ = classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o
|
||||
DEPOBJ= $(OBJ) comprehensive.o abstract.o \
|
||||
getting_started1.o getting_started2.o getting_started3.o \
|
||||
getting_started4.o getting_started5.o
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
comprehensive.o \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a boost_python_test.so abstract.so \
|
||||
getting_started1.so getting_started2.so getting_started3.so \
|
||||
getting_started4.so getting_started5.so
|
||||
|
||||
softlinks:
|
||||
@ for pn in $(SOFTLINKS); \
|
||||
do \
|
||||
bn=`basename "$$pn"`; \
|
||||
if [ ! -e "$$bn" ]; then \
|
||||
echo "ln -s $$pn ."; \
|
||||
ln -s "$$pn" .; \
|
||||
else \
|
||||
echo "info: no softlink created (file exists): $$bn"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
unlink:
|
||||
@ for pn in $(SOFTLINKS); \
|
||||
do \
|
||||
bn=`basename "$$pn"`; \
|
||||
if [ -L "$$bn" ]; then \
|
||||
echo "rm $$bn"; \
|
||||
rm "$$bn"; \
|
||||
elif [ -e "$$bn" ]; then \
|
||||
echo "info: not a softlink: $$bn"; \
|
||||
fi; \
|
||||
done
|
||||
all: libboost_python.a \
|
||||
boost_python_test.so \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
@@ -127,14 +91,34 @@ getting_started1.so: $(OBJ) getting_started1.o
|
||||
getting_started2.so: $(OBJ) getting_started2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so
|
||||
|
||||
getting_started3.so: $(OBJ) getting_started3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
getting_started4.so: $(OBJ) getting_started4.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started4.o -o getting_started4.so
|
||||
do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so
|
||||
|
||||
getting_started5.so: $(OBJ) getting_started5.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started5.o -o getting_started5.so
|
||||
pickle1.so: $(OBJ) pickle1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so
|
||||
|
||||
pickle2.so: $(OBJ) pickle2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so
|
||||
|
||||
pickle3.so: $(OBJ) pickle3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so
|
||||
|
||||
noncopyable_export.so: $(OBJ) noncopyable_export.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_export.o -o noncopyable_export.so
|
||||
|
||||
noncopyable_import.so: $(OBJ) noncopyable_import.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_import.o -o noncopyable_import.so
|
||||
|
||||
ivect.so: $(OBJ) ivect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so
|
||||
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
@@ -144,9 +128,12 @@ test:
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_getting_started3.py
|
||||
$(PYEXE) test_getting_started4.py
|
||||
$(PYEXE) test_getting_started5.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
@@ -154,12 +141,30 @@ clean:
|
||||
rm -f abstract.o abstract.so
|
||||
rm -f getting_started1.o getting_started1.so
|
||||
rm -f getting_started2.o getting_started2.so
|
||||
rm -f getting_started3.o getting_started3.so
|
||||
rm -f getting_started4.o getting_started4.so
|
||||
rm -f getting_started5.o getting_started5.so
|
||||
rm -f simple_vector.o simple_vector.so
|
||||
rm -f do_it_yourself_converters.o do_it_yourself_converters.so
|
||||
rm -f pickle1.o pickle1.so
|
||||
rm -f pickle2.o pickle2.so
|
||||
rm -f pickle3.o pickle3.so
|
||||
rm -f noncopyable_export.o noncopyable_export.so
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf cxx_repository
|
||||
|
||||
softlinks:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks
|
||||
|
||||
unlink:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink
|
||||
|
||||
cp:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp
|
||||
|
||||
rm:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm
|
||||
|
||||
depend:
|
||||
@ cat Makefile.nodepend; \
|
||||
for obj in $(DEPOBJ); \
|
||||
|
||||
129
build/vc60.mak
Normal file
129
build/vc60.mak
Normal file
@@ -0,0 +1,129 @@
|
||||
# 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:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
ROOT=L:
|
||||
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"
|
||||
|
||||
STDOPTS=/nologo /MD /GR /GX /Zm200
|
||||
WARNOPTS=
|
||||
OPTOPTS=
|
||||
|
||||
CPP=cl.exe
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
|
||||
LD=link.exe
|
||||
LDOPTS=/nologo /dll /incremental:no
|
||||
|
||||
OBJ=classes.obj conversions.obj extension_class.obj functions.obj \
|
||||
init_function.obj module_builder.obj \
|
||||
objects.obj types.obj cross_module.obj
|
||||
|
||||
.SUFFIXES: .obj .cpp
|
||||
|
||||
all: boost_python.lib \
|
||||
boost_python_test.pyd \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_converters.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd
|
||||
|
||||
boost_python.lib: $(OBJ)
|
||||
$(LD) -lib /nologo /out:boost_python.lib $(OBJ)
|
||||
|
||||
boost_python_test.pyd: $(OBJ) comprehensive.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) /export:initboost_python_test /out:"boost_python_test.pyd"
|
||||
|
||||
abstract.pyd: $(OBJ) abstract.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) /export:initabstract /out:"abstract.pyd"
|
||||
|
||||
getting_started1.pyd: $(OBJ) getting_started1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) /export:initgetting_started1 /out:"getting_started1.pyd"
|
||||
|
||||
getting_started2.pyd: $(OBJ) getting_started2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd"
|
||||
|
||||
simple_vector.pyd: $(OBJ) simple_vector.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd"
|
||||
|
||||
do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.obj $(PYLIB) /export:initdo_it_yourself_converters /out:"do_it_yourself_converters.pyd"
|
||||
|
||||
pickle1.pyd: $(OBJ) pickle1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd"
|
||||
|
||||
pickle2.pyd: $(OBJ) pickle2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) /export:initpickle2 /out:"pickle2.pyd"
|
||||
|
||||
pickle3.pyd: $(OBJ) pickle3.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) /export:initpickle3 /out:"pickle3.pyd"
|
||||
|
||||
noncopyable_export.pyd: $(OBJ) noncopyable_export.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) /export:initnoncopyable_export /out:"noncopyable_export.pyd"
|
||||
|
||||
noncopyable_import.pyd: $(OBJ) noncopyable_import.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) /export:initnoncopyable_import /out:"noncopyable_import.pyd"
|
||||
|
||||
ivect.pyd: $(OBJ) ivect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) /export:initivect /out:"ivect.pyd"
|
||||
|
||||
dvect.pyd: $(OBJ) dvect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd"
|
||||
|
||||
.cpp.obj:
|
||||
$(CPP) $(CPPOPTS) /c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py --broken-auto-ptr
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py --broken-auto-ptr
|
||||
|
||||
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
|
||||
@@ -5,153 +5,176 @@
|
||||
<title>Building an Extension Module</title>
|
||||
|
||||
<div>
|
||||
<h1><img width="277" height="86" id="_x0000_i1025" align="center" src=
|
||||
<h1><img width="277" height="86" align="center" src=
|
||||
"../../../c++boost.gif" alt="c++boost.gif (8819 bytes)">Building an
|
||||
Extension Module</h1>
|
||||
|
||||
<p>The build process for Boost is currently undergoing some evolution,
|
||||
and, it is to be hoped, improvement. The following facts may help:
|
||||
|
||||
<hr>
|
||||
Makefiles for various platforms and a Visual Studio project
|
||||
reside in the Boost subdirectory <tt>libs/python/build</tt>.
|
||||
Build targets include:
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Makefiles for various platforms reside in the Boost subdirectory
|
||||
<tt>libs/python/build</tt>:
|
||||
<li>The <tt>boost_python</tt> library for static linking with your
|
||||
extension module. On the various Unices, this library will be
|
||||
called <tt>libboost_python.a</tt>. When using Visual C++, the
|
||||
library will be called <tt>boost_python.lib</tt>.
|
||||
|
||||
<ul>
|
||||
<li><a href="../build/como.mak">como.mak</a> (Comeau C++ on Linux)
|
||||
<p>
|
||||
<li>A comprehensive test of Boost.Python features. This test builds
|
||||
a Boost.Python extension module, then runs Python to import the
|
||||
module, and runs a series of tests on it using <tt><a href=
|
||||
"../test/doctest.py">doctest</a></tt>. Source code for the module
|
||||
and tests is available in the Boost subdirectory
|
||||
<tt>libs/python/test</tt>.
|
||||
|
||||
<li><a href="../build/linux_gcc.mak">linux_gcc.mak</a> (GCC on
|
||||
Linux/Unix)
|
||||
<p>
|
||||
<li>Various examples from the Boost subdirectory
|
||||
<tt>libs/python/example</tt>.
|
||||
All these examples include a doctest modeled
|
||||
on the comprehensive test above.
|
||||
|
||||
<li><a href="../build/gcc.mak">gcc.mak</a> (older makefile for GCC
|
||||
on Linux/Unix. Deprecated.)
|
||||
|
||||
<li><a href="../build/mingw32.mak">mingw32.mak</a>
|
||||
(highly-specialized makefile for mingw32 (Win32-targeted) GCC. Read
|
||||
the header comment).
|
||||
|
||||
<li><a href="../build/tru64_cxx.mak">tru64_cxx.mak</a> (Compaq
|
||||
Alpha).
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<li>
|
||||
A project workspace for Microsoft Visual Studio is provided at <tt><a
|
||||
href="../build/build.dsw">libs/python/build/build.dsw</a></tt>. The
|
||||
include paths for this project may need to be changed for your
|
||||
installation. They currently assume that python has been installed at
|
||||
<tt>c:\tools\python</tt>. Three configurations of all targets are
|
||||
supported:
|
||||
|
||||
<ul>
|
||||
<li>Release (optimization, <tt>-DNDEBUG</tt>)
|
||||
|
||||
<li>Debug (no optimization <tt>-D_DEBUG</tt>)
|
||||
|
||||
<li>DebugPython (no optimization, <tt>-D_DEBUG
|
||||
-DBOOST_DEBUG_PYTHON</tt>)
|
||||
</ul>
|
||||
|
||||
<p>When extension modules are built with Visual C++ using
|
||||
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> linking with a
|
||||
special debugging version of the Python DLL. Since this debug DLL
|
||||
isn't supplied with the default Python installation for Windows,
|
||||
Boost.Python uses <tt><a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
|
||||
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
|
||||
<tt>#include</tt>d.
|
||||
|
||||
<p>If you want the extra runtime checks available with the debugging
|
||||
version of the library, <tt>#define BOOST_DEBUG_PYTHON</tt> to
|
||||
re-enable library forcing, and link with the DebugPython version of
|
||||
<tt>boost_python.lib</tt>. You'll need to get the debugging version
|
||||
of the Python executable (<tt>python_d.exe</tt>) and DLL
|
||||
(<tt>python20_d.dll</tt> or <tt>python15_d.dll</tt>). The Python
|
||||
sources include project files for building these. If you <a href=
|
||||
"http://www.python.org">download</a> them, change the name of the
|
||||
top-level directory to <tt>src</tt>, and install it under
|
||||
<tt>c:\tools\python</tt>, the workspace supplied by Boost.Python will
|
||||
be able to use it without modification. Just open
|
||||
<tt>c:\tools\python\src\pcbuild\pcbuild.dsw</tt> and invoke "build
|
||||
all" to generate all the debugging targets.
|
||||
|
||||
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that
|
||||
any source files <tt>#include <<a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>></tt>
|
||||
instead of the usual <tt>Python.h</tt>, or you will have link
|
||||
incompatibilities.<br>
|
||||
<br>
|
||||
|
||||
|
||||
<li>
|
||||
The makefiles and Visual Studio project can all build at least the
|
||||
following:
|
||||
|
||||
<ul>
|
||||
<li>The <tt>boost_python</tt> library for static linking with your
|
||||
extension module. On the various Unices, this library will be
|
||||
called <tt>libboost_python.a</tt>. On Win32 platforms, the library
|
||||
will be called <tt>boost_python.lib</tt>.
|
||||
|
||||
<li>A comprehensive test of Boost.Python features. This test builds
|
||||
a Boost.Python extension module, then runs Python to import the
|
||||
module, and runs a series of tests on it using <tt><a href=
|
||||
"../test/doctest.py">doctest</a></tt>. Source code for the module
|
||||
and tests is available in the Boost subdirectory
|
||||
<tt>libs/python/test</tt>.<br>
|
||||
|
||||
|
||||
<li>Various examples from the Boost subdirectory
|
||||
<tt>libs/python/example</tt>. Which examples are built currently
|
||||
depends on the platform. The most up-to-date examples are
|
||||
<tt>getting_started</tt><i>n</i><tt>.cpp</tt> from <a href=
|
||||
"http://cci.lbl.gov/staff/ralf_grosse-kunstleve.html">Ralf W.
|
||||
Grosse-Kunstleve</a>. All these examples include a doctest modeled
|
||||
on the comprehensive test above.<br>
|
||||
<br>
|
||||
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
If your platform isn't directly supported, you can build a static
|
||||
library from the following source files (in the Boost subdirectory
|
||||
<tt>libs/python/src</tt>), or compile them directly and link the
|
||||
resulting objects into your extension module:
|
||||
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../../../libs/python/src/extension_class.cpp">extension_class.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/functions.cpp">functions.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/init_function.cpp">init_function.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/module_builder.cpp">module_builder.cpp</a>
|
||||
|
||||
<li><a href="../../../libs/python/src/types.cpp">types.cpp</a>
|
||||
|
||||
<li><a href="../../../libs/python/src/objects.cpp">objects.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/conversions.cpp">conversions.cpp</a>
|
||||
|
||||
<li><a href="../../../libs/python/src/classes.cpp">classes.cpp</a>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<p>Next: <a href="enums.html">Wrapping Enums</a> Previous: <a href=
|
||||
<hr>
|
||||
There is a group of makefiles with support for simultaneous
|
||||
compilation on multiple platforms and a consistent set of
|
||||
features that build the <tt>boost_python</tt> library for static
|
||||
linking, the comprehensive test, and all examples in
|
||||
<tt>libs/python/example</tt>:
|
||||
|
||||
<ul>
|
||||
<li><a href="../build/vc60.mak">vc60.mak</a>:
|
||||
Visual C++ 6.0 Service Pack 4
|
||||
|
||||
<li><a href="../build/mingw32.mak">mingw32.mak</a>:
|
||||
mingw32 (Win32-targeted) gcc 2.95.2
|
||||
|
||||
<li><a href="../build/linux_gcc.mak">linux_gcc.mak</a>:
|
||||
gcc 2.95.2 on Linux/Unix
|
||||
|
||||
<li><a href="../build/tru64_cxx.mak">tru64_cxx.mak</a>:
|
||||
Compaq Alpha using the Compaq cxx compiler
|
||||
|
||||
<li><a href="../build/irix_CC.mak">irix_CC.mak</a>:
|
||||
Silicon Graphics IRIX 6.5 CC compiler
|
||||
|
||||
</ul>
|
||||
<a href="http://cctbx.sourceforge.net/page_installation_adv.html#installation_boost_python"
|
||||
>Usage of these makefiles is described here.</a>
|
||||
|
||||
<hr>
|
||||
There is another group of makefiles for GNU make.
|
||||
These makefiles are less redundant than the makefiles
|
||||
in the group above,
|
||||
but the list of compilation targets is not as complete
|
||||
and there is no support for simultaneous compilation
|
||||
on multiple platforms.
|
||||
|
||||
<ul>
|
||||
<li><a href="../build/como.mak">como.mak</a>:
|
||||
Comeau C++ on Linux
|
||||
|
||||
<li><a href="../build/gcc.mak">gcc.mak</a>:
|
||||
GCC on Linux/Unix.
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
A project workspace for Microsoft Visual Studio is provided at <tt><a
|
||||
href="../build/build.dsw">libs/python/build/build.dsw</a></tt>. The
|
||||
include paths for this project may need to be changed for your
|
||||
installation. They currently assume that python has been installed at
|
||||
<tt>c:\tools\python</tt>. Three configurations of all targets are
|
||||
supported:
|
||||
|
||||
<ul>
|
||||
<li>Release (optimization, <tt>-DNDEBUG</tt>)
|
||||
|
||||
<li>Debug (no optimization <tt>-D_DEBUG</tt>)
|
||||
|
||||
<li>DebugPython (no optimization, <tt>-D_DEBUG
|
||||
-DBOOST_DEBUG_PYTHON</tt>)
|
||||
</ul>
|
||||
|
||||
<p>When extension modules are built with Visual C++ using
|
||||
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> linking with a
|
||||
special debugging version of the Python DLL. Since this debug DLL
|
||||
isn't supplied with the default Python installation for Windows,
|
||||
Boost.Python uses <tt><a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
|
||||
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
|
||||
<tt>#include</tt>d.
|
||||
|
||||
<p>If you want the extra runtime checks available with the debugging
|
||||
version of the library, <tt>#define BOOST_DEBUG_PYTHON</tt> to
|
||||
re-enable library forcing, and link with the DebugPython version of
|
||||
<tt>boost_python.lib</tt>. You'll need to get the debugging version
|
||||
of the Python executable (<tt>python_d.exe</tt>) and DLL
|
||||
(<tt>python20_d.dll</tt> or <tt>python15_d.dll</tt>). The Python
|
||||
sources include project files for building these. If you <a href=
|
||||
"http://www.python.org">download</a> them, change the name of the
|
||||
top-level directory to <tt>src</tt>, and install it under
|
||||
<tt>c:\tools\python</tt>, the workspace supplied by Boost.Python will
|
||||
be able to use it without modification. Just open
|
||||
<tt>c:\tools\python\src\pcbuild\pcbuild.dsw</tt> and invoke "build
|
||||
all" to generate all the debugging targets.
|
||||
|
||||
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that
|
||||
any source files <tt>#include <<a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>></tt>
|
||||
instead of the usual <tt>Python.h</tt>, or you will have link
|
||||
incompatibilities.<br>
|
||||
|
||||
<hr>
|
||||
If your platform isn't directly supported, you can build a static
|
||||
library from the following source files (in the Boost subdirectory
|
||||
<tt>libs/python/src</tt>), or compile them directly and link the
|
||||
resulting objects into your extension module:
|
||||
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../../../libs/python/src/classes.cpp">classes.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/conversions.cpp">conversions.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/cross_module.cpp">cross_module.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/extension_class.cpp">extension_class.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/functions.cpp">functions.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/init_function.cpp">init_function.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/module_builder.cpp">module_builder.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/objects.cpp">objects.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/types.cpp">types.cpp</a>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
Next: <a href="enums.html">Wrapping Enums</a> Previous: <a href=
|
||||
"under-the-hood.html">A Peek Under the Hood</a> Up: <a href=
|
||||
"index.html">Top</a>
|
||||
|
||||
<hr>
|
||||
<p>© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as is'' without
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
|
||||
<p>Updated: Mar 6, 2001
|
||||
<p>Updated: Apr 17, 2001 (R.W. Grosse-Kunstleve)
|
||||
</div>
|
||||
|
||||
|
||||
336
doc/cross_module.html
Normal file
336
doc/cross_module.html
Normal file
@@ -0,0 +1,336 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
|
||||
<title>Cross-extension-module dependencies</title>
|
||||
|
||||
<div>
|
||||
|
||||
<img src="../../../c++boost.gif"
|
||||
alt="c++boost.gif (8819 bytes)"
|
||||
align="center"
|
||||
width="277" height="86">
|
||||
|
||||
<hr>
|
||||
<h1>Cross-extension-module dependencies</h1>
|
||||
|
||||
It is good programming practice to organize large projects as modules
|
||||
that interact with each other via well defined interfaces. With
|
||||
Boost.Python it is possible to reflect this organization at the C++
|
||||
level at the Python level. This is, each logical C++ module can be
|
||||
organized as a separate Python extension module.
|
||||
|
||||
<p>
|
||||
At first sight this might seem natural and straightforward. However, it
|
||||
is a fairly complex problem to establish cross-extension-module
|
||||
dependencies while maintaining the same ease of use Boost.Python
|
||||
provides for classes that are wrapped in the same extension module. To
|
||||
a large extent this complexity can be hidden from the author of a
|
||||
Boost.Python extension module, but not entirely.
|
||||
|
||||
<hr>
|
||||
<h2>The recipe</h2>
|
||||
|
||||
Suppose there is an extension module that exposes certain instances of
|
||||
the C++ <tt>std::vector</tt> template library such that it can be used
|
||||
from Python in the following manner:
|
||||
|
||||
<pre>
|
||||
import std_vector
|
||||
v = std_vector.double([1, 2, 3, 4])
|
||||
v.push_back(5)
|
||||
v.size()
|
||||
</pre>
|
||||
|
||||
Suppose the <tt>std_vector</tt> module is done well and reflects all
|
||||
C++ functions that are useful at the Python level, for all C++ built-in
|
||||
data types (<tt>std_vector.int</tt>, <tt>std_vector.long</tt>, etc.).
|
||||
|
||||
<p>
|
||||
Suppose further that there is statistic module with a C++ class that
|
||||
has constructors or member functions that use or return a
|
||||
<tt>std::vector</tt>. For example:
|
||||
|
||||
<pre>
|
||||
class xy {
|
||||
public:
|
||||
xy(const std::vector<double>& x, const std::vector<double>& y) : m_x(x), m_y(y) {}
|
||||
const std::vector<double>& x() const { return m_x; }
|
||||
const std::vector<double>& y() const { return m_y; }
|
||||
double correlation();
|
||||
private:
|
||||
std::vector<double> m_x;
|
||||
std::vector<double> m_y;
|
||||
}
|
||||
</pre>
|
||||
|
||||
What is more natural than reusing the <tt>std_vector</tt> extension
|
||||
module to expose these constructors or functions to Python?
|
||||
|
||||
<p>
|
||||
Unfortunately, what seems natural needs a little work in both the
|
||||
<tt>std_vector</tt> and the <tt>statistics</tt> module.
|
||||
|
||||
<p>
|
||||
In the <tt>std_vector</tt> extension module,
|
||||
<tt>std::vector<double></tt> is exposed to Python in the usual
|
||||
way with the <tt>class_builder<></tt> template. To also enable the
|
||||
automatic conversion of <tt>std::vector<double></tt> function
|
||||
arguments or return values in other Boost.Python C++ modules, the
|
||||
converters that convert a <tt>std::vector<double></tt> C++ object
|
||||
to a Python object and vice versa (i.e. the <tt>to_python()</tt> and
|
||||
<tt>from_python()</tt> template functions) have to be exported. For
|
||||
example:
|
||||
|
||||
<pre>
|
||||
#include <boost/python/cross_module.hpp>
|
||||
//...
|
||||
class_builder<std::vector<double> > v_double(std_vector_module, "double");
|
||||
export_converters(v_double);
|
||||
</pre>
|
||||
|
||||
In the extension module that wraps <tt>class xy</tt> we can now import
|
||||
these converters with the <tt>import_converters<></tt> template.
|
||||
For example:
|
||||
|
||||
<pre>
|
||||
#include <boost/python/cross_module.hpp>
|
||||
//...
|
||||
import_converters<std::vector<double> > v_double_converters("std_vector", "double");
|
||||
</pre>
|
||||
|
||||
That is all. All the attributes that are defined for
|
||||
<tt>std_vector.double</tt> in the <tt>std_vector</tt> Boost.Python
|
||||
module will be available for the returned objects of <tt>xy.x()</tt>
|
||||
and <tt>xy.y()</tt>. Similarly, the constructor for <tt>xy</tt> will
|
||||
accept objects that were created by the <tt>std_vector</tt>module.
|
||||
|
||||
<hr>
|
||||
<h2>Placement of <tt>import_converters<></tt> template instantiations</h2>
|
||||
|
||||
<tt>import_converts<></tt> can be viewed as a drop-in replacement
|
||||
for <tt>class_wrapper<></tt>, and the recommendations for the
|
||||
placement of <tt>class_wrapper<></tt> template instantiations
|
||||
also apply to to <tt>import_converts<></tt>. In particular, it is
|
||||
important that an instantiation of <tt>class_wrapper<></tt> is
|
||||
visible to any code which wraps a C++ function with a <tt>T</tt>,
|
||||
<tt>T*</tt>, const <tt>T&</tt>, etc. parameter or return value.
|
||||
Therefore you may want to group all <tt>class_wrapper<></tt> and
|
||||
<tt>import_converts<></tt> instantiations at the top of your
|
||||
module's init function, then <tt>def()</tt> the member functions later
|
||||
to avoid problems with inter-class dependencies.
|
||||
|
||||
<hr>
|
||||
<h2>Non-copyable types</h2>
|
||||
|
||||
<tt>export_converters()</tt> instantiates C++ template functions that
|
||||
invoke the copy constructor of the wrapped type. For a type that is
|
||||
non-copyable this will result in compile-time error messages. In such a
|
||||
case, <tt>export_converters_noncopyable()</tt> can be used to export
|
||||
the converters that do not involve the copy constructor of the wrapped
|
||||
type. For example:
|
||||
|
||||
<pre>
|
||||
class_builder<store> py_store(your_module, "store");
|
||||
export_converters_noncopyable(py_store);
|
||||
</pre>
|
||||
|
||||
The corresponding <tt>import_converters<></tt> statement does not
|
||||
need any special attention:
|
||||
|
||||
<pre>
|
||||
import_converters<store> py_store("noncopyable_export", "store");
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
<h2>Python module search path</h2>
|
||||
|
||||
The <tt>std_vector</tt> and <tt>statistics</tt> modules can now be used
|
||||
in the following way:
|
||||
|
||||
<pre>
|
||||
import std_vector
|
||||
import statistics
|
||||
x = std_vector.double([1, 2, 3, 4])
|
||||
y = std_vector.double([2, 4, 6, 8])
|
||||
xy = statistics.xy(x, y)
|
||||
xy.correlation()
|
||||
</pre>
|
||||
|
||||
In this example it is clear that Python has to be able to find both the
|
||||
<tt>std_vector</tt> and the <tt>statistics</tt> extension module. In
|
||||
other words, both extension modules need to be in the Python module
|
||||
search path (<tt>sys.path</tt>).
|
||||
|
||||
<p>
|
||||
The situation is not always this obvious. Suppose the
|
||||
<tt>statistics</tt> module has a <tt>random()</tt> function that
|
||||
returns a vector of random numbers with a given length:
|
||||
|
||||
<pre>
|
||||
import statistics
|
||||
x = statistics.random(5)
|
||||
y = statistics.random(5)
|
||||
xy = statistics.xy(x, y)
|
||||
xy.correlation()
|
||||
</pre>
|
||||
|
||||
A naive user will not easily anticipate that the <tt>std_vector</tt>
|
||||
module is used to pass the <tt>x</tt> and <tt>y</tt> vectors around. If
|
||||
the <tt>std_vector</tt> module is in the Python module search path,
|
||||
this form of ignorance is of no harm. On the contrary, we are glad
|
||||
that we do not have to bother the user with details like this.
|
||||
|
||||
<p>
|
||||
If the <tt>std_vector</tt> module is not in the Python module search
|
||||
path, a Python exception will be raised:
|
||||
|
||||
<pre>
|
||||
Traceback (innermost last):
|
||||
File "foo.py", line 2, in ?
|
||||
x = statistics.random(5)
|
||||
ImportError: No module named std_vector
|
||||
</pre>
|
||||
|
||||
As is the case with any system of a non-trivial complexity, it is
|
||||
important that the setup is consistent and complete.
|
||||
|
||||
<hr>
|
||||
<h2>Two-way module dependencies</h2>
|
||||
|
||||
Boost.Python supports two-way module dependencies. This is best
|
||||
illustrated by a simple example.
|
||||
|
||||
<p>
|
||||
Suppose there is a module <tt>ivect</tt> that implements vectors of
|
||||
integers, and a similar module <tt>dvect</tt> that implements vectors
|
||||
of doubles. We want to be able do convert an integer vector to a double
|
||||
vector and vice versa. For example:
|
||||
|
||||
<pre>
|
||||
import ivect
|
||||
iv = ivect.ivect((1,2,3,4,5))
|
||||
dv = iv.as_dvect()
|
||||
</pre>
|
||||
|
||||
The last expression will implicitly import the <tt>dvect</tt> module in
|
||||
order to enable the conversion of the C++ representation of
|
||||
<tt>dvect</tt> to a Python object. The analogous is possible for a
|
||||
<tt>dvect</tt>:
|
||||
|
||||
<pre>
|
||||
import dvect
|
||||
dv = dvect.dvect((1,2,3,4,5))
|
||||
iv = dv.as_ivect()
|
||||
</pre>
|
||||
|
||||
Now the <tt>ivect</tt> module is imported implicitly.
|
||||
|
||||
<p>
|
||||
Note that the two-way dependencies are possible because the
|
||||
dependencies are resolved only when needed. This is, the initialization
|
||||
of the <tt>ivect</tt> module does not rely on the <tt>dvect</tt>
|
||||
module, and vice versa. Only if <tt>as_dvect()</tt> or
|
||||
<tt>as_ivect()</tt> is actually invoked will the corresponding module
|
||||
be implicitly imported. This also means that, for example, the
|
||||
<tt>dvect</tt> module does not have to be available at all if
|
||||
<tt>as_dvect()</tt> is never used.
|
||||
|
||||
<hr>
|
||||
<h2>Clarification of compile-time and link-time dependencies</h2>
|
||||
|
||||
Boost.Python's support for resolving cross-module dependencies at
|
||||
runtime does not imply that compile-time dependencies are eliminated.
|
||||
For example, the statistics extension module in the example above will
|
||||
need to <tt>#include <vector></tt>. This is immediately obvious
|
||||
from the definition of <tt>class xy</tt>.
|
||||
|
||||
<p>
|
||||
If a library is wrapped that consists of both header files and compiled
|
||||
components (e.g. <tt>libdvect.a</tt>, <tt>dvect.lib</tt>, etc.), both
|
||||
the Boost.Python extension module with the
|
||||
<tt>export_converters()</tt> statement and the module with the
|
||||
<tt>import_converters<></tt> statement need to be linked against
|
||||
the object library. Ideally one would build a shared library (e.g.
|
||||
<tt>libdvect.so</tt>, <tt>dvect.dll</tt>, etc.). However, this
|
||||
introduces the issue of having to configure the search path for the
|
||||
dynamic loading correctly. For small libraries it is therefore often
|
||||
more convenient to ignore the fact that the object files are loaded
|
||||
into memory more than once.
|
||||
|
||||
<hr>
|
||||
<h2>Summary of motivation for cross-module support</h2>
|
||||
|
||||
The main purpose of Boost.Python's cross-module support is to allow for
|
||||
a modular system layout. With this support it is straightforward to
|
||||
reflect C++ code organization at the Python level. Without the
|
||||
cross-module support, a multi-purpose module like <tt>std_vector</tt>
|
||||
would be impractical because the entire wrapper code would somehow have
|
||||
to be duplicated in all extension modules that use it, making them
|
||||
harder to maintain and harder to build.
|
||||
|
||||
<p>
|
||||
Another motivation for the cross-module support is that two extension
|
||||
modules that wrap the same class cannot both be imported into Python.
|
||||
For example, if there are two modules <tt>A</tt> and <tt>B</tt> that
|
||||
both wrap a given <tt>class X</tt>, this will work:
|
||||
|
||||
<pre>
|
||||
import A
|
||||
x = A.X()
|
||||
</pre>
|
||||
|
||||
This will also work:
|
||||
|
||||
<pre>
|
||||
import B
|
||||
x = B.X()
|
||||
</pre>
|
||||
|
||||
However, this will fail:
|
||||
|
||||
<pre>
|
||||
import A
|
||||
import B
|
||||
python: /net/cci/rwgk/boost/boost/python/detail/extension_class.hpp:866:
|
||||
static void boost::python::detail::class_registry<X>::register_class(boost::python::detail::extension_class_base *):
|
||||
Assertion `static_class_object == 0' failed.
|
||||
Abort
|
||||
</pre>
|
||||
|
||||
A good solution is to wrap <tt>class X</tt> only once. Depending on the
|
||||
situation, this could be done by module <tt>A</tt> or <tt>B</tt>, or an
|
||||
additional small extension module that only wraps and exports
|
||||
<tt>class X</tt>.
|
||||
|
||||
<p>
|
||||
Finally, there can be important psychological or political reasons for
|
||||
using the cross-module support. If a group of classes is lumped
|
||||
together with many others in a huge module, the authors will have
|
||||
difficulties in being identified with their work. The situation is
|
||||
much more transparent if the work is represented by a module with a
|
||||
recognizable name. This is not just a question of strong egos, but also
|
||||
of getting credit and funding.
|
||||
|
||||
<hr>
|
||||
<h2>Why not use <tt>export_converters()</tt> universally?</h2>
|
||||
|
||||
There is some overhead associated with the Boost.Python cross-module
|
||||
support. Depending on the platform, the size of the code generated by
|
||||
<tt>export_converters()</tt> is roughly 10%-20% of that generated
|
||||
by <tt>class_builder<></tt>. For a large extension module with
|
||||
many wrapped classes, this could mean a significant difference.
|
||||
Therefore the general recommendation is to use
|
||||
<tt>export_converters()</tt> only for classes that are likely to
|
||||
be used as function arguments or return values in other modules.
|
||||
|
||||
<hr>
|
||||
© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy,
|
||||
use, modify, sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided "as
|
||||
is" without express or implied warranty, and with no claim as to its
|
||||
suitability for any purpose.
|
||||
|
||||
<p>
|
||||
Updated: April 2001
|
||||
|
||||
</div>
|
||||
@@ -75,7 +75,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
from_python(x, boost::python::type<long>()));
|
||||
}
|
||||
|
||||
PyObject* to_python(MyEnumType x)
|
||||
PyObject* to_python(boost::python::semantics, MyEnumType x)
|
||||
{
|
||||
return to_python(static_cast<long>(x));
|
||||
}
|
||||
@@ -91,8 +91,8 @@ initialization. These bind the corresponding enum values to the appropriate
|
||||
names so they can be used from Python:
|
||||
|
||||
<blockquote><pre>
|
||||
mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1");
|
||||
mymodule.add(boost::python::to_python(enum_value_2), "enum_value_2");
|
||||
mymodule.add(boost::python::to_python(boost::python::search_namespace, enum_value_1), "enum_value_1");
|
||||
mymodule.add(boost::python::to_python(boost::python::search_namespace, enum_value_2), "enum_value_2");
|
||||
...
|
||||
</pre></blockquote>
|
||||
|
||||
@@ -100,8 +100,8 @@ You can also add these to an extension class definition, if your enum happens to
|
||||
be local to a class and you want the analogous interface in Python:
|
||||
|
||||
<blockquote><pre>
|
||||
my_class_builder.add(boost::python::to_python(enum_value_1), "enum_value_1");
|
||||
my_class_builder.add(boost::python::to_python(enum_value_2), "enum_value_2");
|
||||
my_class_builder.add(boost::python::to_python(boost::python::search_namespace, enum_value_1), "enum_value_1");
|
||||
my_class_builder.add(boost::python::to_python(boost::python::search_namespace, enum_value_2), "enum_value_2");
|
||||
...
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>
|
||||
The Boost Python Library (Boost.Python)
|
||||
</title>
|
||||
@@ -134,6 +133,8 @@ among others.
|
||||
|
||||
<li><a href="pickle.html">Pickle Support</a>
|
||||
|
||||
<li><a href="cross_module.html">Cross-Extension-Module Dependencies</a>
|
||||
|
||||
<li><a href="enums.html">Wrapping Enums</a>
|
||||
|
||||
<li><a href="pointers.html">Pointers and Smart Pointers</a>
|
||||
@@ -152,7 +153,7 @@ among others.
|
||||
|
||||
<p>
|
||||
Questions should be directed to <a href=
|
||||
"http://www.egroups.com/list/boost">the boost mailing list</a>.
|
||||
"http://www.yahoogroups.com/list/boost">the boost mailing list</a>.
|
||||
|
||||
<p>
|
||||
© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||
|
||||
@@ -47,17 +47,17 @@ class hello
|
||||
<code>PyObject*</code> argument. The initial argument should be stored in the <tt>self</tt> data
|
||||
member described above.
|
||||
|
||||
<li>If the class being wrapped is ever returned <i>by
|
||||
<li><a name="derived_3">If</a> the class being wrapped is ever returned <i>by
|
||||
value</i> from a wrapped function, be sure you do the same for the
|
||||
<tt>T</tt>'s copy constructor: you'll need a constructor taking arguments
|
||||
<tt>(PyObject*, const T&)</tt>.
|
||||
|
||||
<li><a name="derived_3">An</a> implementation of each virtual function you may
|
||||
<li><a name="derived_4">An</a> implementation of each virtual function you may
|
||||
wish to override in Python which uses
|
||||
<tt>callback<</tt><i>return-type</i><tt>>::call_method(self, "</tt><i>name</i><tt>", </tt><i>args...</i><tt>)</tt> to call
|
||||
the Python override.
|
||||
|
||||
<li><a name="derived_4">For</a> each non-pure virtual function meant to be
|
||||
<li><a name="derived_5">For</a> each non-pure virtual function meant to be
|
||||
overridable from Python, a static member function (or a free function) taking
|
||||
a reference or pointer to the <tt>T</tt> as the first parameter and which
|
||||
forwards any additional parameters neccessary to the <i>default</i>
|
||||
@@ -211,5 +211,5 @@ href="http://cs.calvin.edu/c++/C++Standard-Nov97/basic.html#basic.def.odr">ODR</
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2001
|
||||
Updated: Mar 21, 2001
|
||||
|
||||
|
||||
@@ -227,11 +227,38 @@ Both <tt>__getinitargs__</tt> and <tt>__getstate__</tt> are not defined.
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<h2>Example</h2>
|
||||
<h2>Examples</h2>
|
||||
|
||||
An example that shows how to configure pickle support is available in the
|
||||
<tt>boost/lib/python/example</tt> directory
|
||||
(<tt>getting_started3.cpp</tt>).
|
||||
There are three files in <tt>boost/libs/python/example</tt> that
|
||||
show how so provide pickle support.
|
||||
|
||||
<h3><a href="../example/pickle1.cpp"><tt>pickle1.cpp</tt></a></h3>
|
||||
|
||||
The C++ class in this example can be fully restored by passing the
|
||||
appropriate argument to the constructor. Therefore it is sufficient
|
||||
to define the pickle interface method <tt>__getinitargs__</tt>.
|
||||
|
||||
<h3><a href="../example/pickle2.cpp"><tt>pickle2.cpp</tt></a></h3>
|
||||
|
||||
The C++ class in this example contains member data that cannot be
|
||||
restored by any of the constructors. Therefore it is necessary to
|
||||
provide the <tt>__getstate__</tt>/<tt>__setstate__</tt> pair of
|
||||
pickle interface methods.
|
||||
|
||||
<p>
|
||||
For simplicity, the <tt>__dict__</tt> is not included in the result
|
||||
of <tt>__getstate__</tt>. This is not generally recommended, but a
|
||||
valid approach if it is anticipated that the object's
|
||||
<tt>__dict__</tt> will always be empty. Note that the safety guards
|
||||
will catch the cases where this assumption is violated.
|
||||
|
||||
<h3><a href="../example/pickle3.cpp"><tt>pickle3.cpp</tt></a></h3>
|
||||
|
||||
This example is similar to <a
|
||||
href="../example/pickle2.cpp"><tt>pickle2.cpp</tt></a>. However, the
|
||||
object's <tt>__dict__</tt> is included in the result of
|
||||
<tt>__getstate__</tt>. This requires more code but is unavoidable
|
||||
if the object's <tt>__dict__</tt> is not always empty.
|
||||
|
||||
<hr>
|
||||
© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy,
|
||||
@@ -241,5 +268,5 @@ is" without express or implied warranty, and with no claim as to its
|
||||
suitability for any purpose.
|
||||
|
||||
<p>
|
||||
Updated: March 10, 2001
|
||||
Updated: March 21, 2001
|
||||
</div>
|
||||
|
||||
@@ -65,9 +65,9 @@ wrapped <code>T</code>, you may want to provide an automatic
|
||||
thin wrappers. You can do this simply as follows:
|
||||
|
||||
<blockquote><pre>
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
PyObject* to_python(const Foo* p) {
|
||||
return to_python(*p); // convert const Foo* in terms of const Foo&
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is an MSVC / gcc 2.95.2 bug workaround
|
||||
PyObject* to_python(boost::python::semantics, const Foo* p) {
|
||||
return to_python(boost::python::search_namespace, *p); // convert const Foo* in terms of const Foo&
|
||||
}
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
</pre></blockquote>
|
||||
@@ -83,12 +83,12 @@ code before the last Python reference to it disappears:
|
||||
|
||||
<blockquote><pre>
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
PyObject* to_python(Foo* p)
|
||||
PyObject* to_python(boost::python::semantics, Foo* p)
|
||||
{
|
||||
return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p);
|
||||
}
|
||||
|
||||
PyObject* to_python(const Foo* p)
|
||||
PyObject* to_python(boost::python::semantics, const Foo* p)
|
||||
{
|
||||
return to_python(const_cast<Foo*>(p));
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ void throw_key_error_if_end(
|
||||
{
|
||||
if (p == m.end())
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, boost::python::converters::to_python(key));
|
||||
PyErr_SetObject(PyExc_KeyError, to_python(boost::python::search_namespace, key));
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
The Title Of This Page
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">The Title Of This
|
||||
Page
|
||||
</h1>
|
||||
<p>
|
||||
<p>
|
||||
Prev: <a href="prev.html">Previous</a>
|
||||
Next: <a href="next.html">Next</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
<p>
|
||||
Updated: Nov 26, 2000
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<a href="example1.html#Constructor_example">provide an argument list</a>
|
||||
because they can't be named in C++). Then, it calls the appropriate
|
||||
overloaded functions <code>PyObject*
|
||||
to_python(</code><em>S</em><code>)</code> and <em>
|
||||
to_python(boost::python::semantics, </code><em>S</em><code>)</code> and <em>
|
||||
S'</em><code>from_python(PyObject*,
|
||||
type<</code><em>S</em><code>>)</code> which convert between any C++
|
||||
type <em>S</em> and a <code>PyObject*</code>, the type which represents a
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
To get started with the Boost Python Library, use the examples
|
||||
getting_started?.cpp and abstract.cpp.
|
||||
getting_started1.cpp and getting_started2.cpp.
|
||||
|
||||
Examples for providing pickle support can be found in:
|
||||
pickle1.cpp
|
||||
pickle2.cpp
|
||||
pickle3.cpp
|
||||
See also: libs/python/doc/pickle.html
|
||||
|
||||
Other advanced concepts are introduced by:
|
||||
abstract.cpp
|
||||
simple_vector.cpp
|
||||
do_it_yourself_converters.cpp
|
||||
|
||||
Examples for the cross-module support are provided by:
|
||||
noncopyable_export.cpp
|
||||
noncopyable_import.cpp
|
||||
dvect.cpp
|
||||
ivect.cpp
|
||||
See also: libs/python/doc/cross_module.html
|
||||
|
||||
The files example1.cpp and rwgk1.cpp are obsolete. They are only
|
||||
included because the makefiles in the build directory still refer to
|
||||
them. This will be fixed later.
|
||||
included because the Visual Studio project in the build directory still
|
||||
refers to them.
|
||||
|
||||
@@ -21,9 +21,7 @@ struct Abstract_callback: Abstract
|
||||
PyObject * m_self;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
DL_EXPORT(void)
|
||||
initabstract()
|
||||
BOOST_PYTHON_MODULE_INIT(abstract)
|
||||
{
|
||||
boost::python::module_builder a("abstract");
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
/*
|
||||
|
||||
This example shows how to convert a class from and to native
|
||||
Python objects, such as tuples.
|
||||
|
||||
@@ -60,7 +62,7 @@ namespace { // Avoid cluttering the global namespace.
|
||||
std::vector<MillerIndex> VMIx;
|
||||
public:
|
||||
void add(const MillerIndex& MIx) { VMIx.push_back(MIx); }
|
||||
MillerIndex get(const std::size_t i) const { return VMIx[i]; }
|
||||
MillerIndex get(std::size_t i) const { return VMIx[i]; }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -93,22 +95,22 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
// Convert a MillerIndex object to a Python tuple.
|
||||
//
|
||||
PyObject* to_python(const MillerIndex& hkl)
|
||||
PyObject* to_python(const MillerIndex& hkl, python::lookup_tag)
|
||||
{
|
||||
python::tuple result(3);
|
||||
for (int i = 0; i < 3; i++)
|
||||
result.set_item(i, python::ref(to_python(hkl.v[i])));
|
||||
result.set_item(i, hkl.v[i]);
|
||||
return result.reference().release();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started5)
|
||||
BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started5");
|
||||
python::module_builder this_module("do_it_yourself_converters");
|
||||
|
||||
// Create the Python type object for our extension class.
|
||||
python::class_builder<IndexingSet> ixset_class(this_module, "IndexingSet");
|
||||
45
example/dvect.cpp
Normal file
45
example/dvect.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
// See root/libs/python/doc/cross_module.html for an introduction.
|
||||
|
||||
#include "dvect.h"
|
||||
#include "ivect.h"
|
||||
#include <boost/python/cross_module.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
namespace {
|
||||
|
||||
# include "dvect_conversions.cpp"
|
||||
# include "ivect_conversions.cpp"
|
||||
|
||||
vects::ivect dvect_as_ivect(const vects::dvect& dv)
|
||||
{
|
||||
vects::ivect iv(dv.size());
|
||||
vects::ivect::iterator iviter = iv.begin();
|
||||
for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast<int>(dv[i]);
|
||||
return iv;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(dvect)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("dvect");
|
||||
|
||||
python::class_builder<vects::dvect> dvect_class(this_module, "dvect");
|
||||
python::export_converters(dvect_class);
|
||||
|
||||
python::import_converters<vects::ivect> ivect_converters("ivect", "ivect");
|
||||
|
||||
dvect_class.def(python::constructor<python::tuple>());
|
||||
dvect_class.def(&vects::dvect::as_tuple, "as_tuple");
|
||||
dvect_class.def(dvect_as_ivect, "as_ivect");
|
||||
|
||||
# include "dvect_defs.cpp"
|
||||
# include "ivect_defs.cpp"
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
30
example/dvect.h
Normal file
30
example/dvect.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef DVECT_H
|
||||
#define DVECT_H
|
||||
|
||||
#include <vector>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace vects {
|
||||
|
||||
struct dvect : public std::vector<double>
|
||||
{
|
||||
dvect() : std::vector<double>() {}
|
||||
dvect(size_t n) : std::vector<double>(n) {}
|
||||
dvect(boost::python::tuple tuple) : std::vector<double>(tuple.size())
|
||||
{
|
||||
std::vector<double>::iterator v_it = begin();
|
||||
for (int i = 0; i < tuple.size(); i++)
|
||||
v_it[i] = from_python(tuple[i].get(), boost::python::type<double>());
|
||||
}
|
||||
|
||||
boost::python::tuple as_tuple() const
|
||||
{
|
||||
boost::python::tuple t(size());
|
||||
for (int i = 0; i < size(); i++)
|
||||
t.set_item(i, (*this)[i]);
|
||||
return t;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DVECT_H
|
||||
51
example/dvect_conversions.cpp
Normal file
51
example/dvect_conversions.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// basics first: const reference converters
|
||||
boost::python::tuple const_dvect_reference_as_tuple(const vects::dvect& dv)
|
||||
{
|
||||
return dv.as_tuple();
|
||||
}
|
||||
|
||||
// to_python smart pointer conversions
|
||||
std::auto_ptr<vects::dvect> dvect_as_auto_ptr(const vects::dvect& dv)
|
||||
{
|
||||
return std::auto_ptr<vects::dvect>(new vects::dvect(dv));
|
||||
}
|
||||
boost::shared_ptr<vects::dvect> dvect_as_shared_ptr(const vects::dvect& dv)
|
||||
{
|
||||
return boost::shared_ptr<vects::dvect>(new vects::dvect(dv));
|
||||
}
|
||||
|
||||
// smart pointers passed by value
|
||||
boost::python::ref auto_ptr_value_dvect_as_tuple(std::auto_ptr<vects::dvect> dv)
|
||||
{
|
||||
if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return dv->as_tuple().reference();
|
||||
}
|
||||
boost::python::ref shared_ptr_value_dvect_as_tuple(boost::shared_ptr<vects::dvect> dv)
|
||||
{
|
||||
if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return dv->as_tuple().reference();
|
||||
}
|
||||
|
||||
// smart pointers passed by reference
|
||||
boost::python::ref auto_ptr_reference_dvect_as_tuple(std::auto_ptr<vects::dvect>& dv)
|
||||
{
|
||||
if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return dv->as_tuple().reference();
|
||||
}
|
||||
boost::python::ref shared_ptr_reference_dvect_as_tuple(boost::shared_ptr<vects::dvect>& dv)
|
||||
{
|
||||
if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return dv->as_tuple().reference();
|
||||
}
|
||||
|
||||
// smart pointers passed by const reference
|
||||
boost::python::ref auto_ptr_const_reference_dvect_as_tuple(const std::auto_ptr<vects::dvect>& dv)
|
||||
{
|
||||
if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return dv->as_tuple().reference();
|
||||
}
|
||||
boost::python::ref shared_ptr_const_reference_dvect_as_tuple(const boost::shared_ptr<vects::dvect>& dv)
|
||||
{
|
||||
if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return dv->as_tuple().reference();
|
||||
}
|
||||
13
example/dvect_defs.cpp
Normal file
13
example/dvect_defs.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
this_module.def(dvect_as_auto_ptr, "dvect_as_auto_ptr");
|
||||
this_module.def(dvect_as_shared_ptr, "dvect_as_shared_ptr");
|
||||
|
||||
this_module.def(const_dvect_reference_as_tuple, "const_dvect_reference_as_tuple");
|
||||
|
||||
this_module.def(auto_ptr_value_dvect_as_tuple, "auto_ptr_value_dvect_as_tuple");
|
||||
this_module.def(shared_ptr_value_dvect_as_tuple, "shared_ptr_value_dvect_as_tuple");
|
||||
|
||||
this_module.def(auto_ptr_reference_dvect_as_tuple, "auto_ptr_reference_dvect_as_tuple");
|
||||
this_module.def(shared_ptr_reference_dvect_as_tuple, "shared_ptr_reference_dvect_as_tuple");
|
||||
|
||||
this_module.def(auto_ptr_const_reference_dvect_as_tuple, "auto_ptr_const_reference_dvect_as_tuple");
|
||||
this_module.def(shared_ptr_const_reference_dvect_as_tuple, "shared_ptr_const_reference_dvect_as_tuple");
|
||||
@@ -1,3 +1,5 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
This example shows how to make an Extension Class "pickleable".
|
||||
|
||||
Python's pickle module implements a basic but powerful algorithm
|
||||
for "pickling" (a.k.a. serializing, marshalling or flattening)
|
||||
nearly arbitrary Python objects.
|
||||
|
||||
The user can influence how an Extension Class instance is pickled
|
||||
by defining three special methods: __getinitargs__(),
|
||||
__getstate__(), and __setstate(). This interface is similar to
|
||||
that for regular Python classes as described in detail in the
|
||||
Python Library Reference for pickle:
|
||||
|
||||
http://www.python.org/doc/current/lib/module-pickle.html
|
||||
|
||||
When an Extension Class instance is pickled, __getinitargs__() is
|
||||
called, if implemented. This method should return a tuple
|
||||
containing the arguments to be passed to the class constructor when
|
||||
the object is restored.
|
||||
|
||||
If there is no __getstate__() method, the instance's __dict__ is
|
||||
pickled if it is not empty. If __getstate__() is defined, it should
|
||||
return an object representing the state of the instance.
|
||||
|
||||
If there is no __setstate__() method, __getstate__() must return a
|
||||
dictionary. When the instance is restored, the items in this dictionary
|
||||
are added to the instance's __dict__.
|
||||
|
||||
If the Extension Class defines __setstate__(), the pickle loader
|
||||
calls it with the result of __getstate__() as arguments. In this
|
||||
case, the state object need not be a dictionary. The
|
||||
__getstate__() and __setstate__() methods can do what they want.
|
||||
|
||||
If both __getinitargs__() and __getstate__() are defined, the
|
||||
instance is restored by first calling the constructor with
|
||||
the result of __getinitargs__() as argument. After the instance
|
||||
is reconstructed, the __dict__ is updated or __setstate__() is
|
||||
called if implemented.
|
||||
|
||||
The mechanism described here is an exact replication of that one
|
||||
implemented by Jim Fulton's ExtensionClass (included in Zope 2.2.2).
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
private:
|
||||
std::string country;
|
||||
int secret_number;
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
void set_secret_number(int number) { secret_number = number; }
|
||||
int get_secret_number() const { return secret_number; }
|
||||
};
|
||||
|
||||
// Support for pickle.
|
||||
python::tuple world_getinitargs(const world& w) {
|
||||
python::tuple result(1);
|
||||
result.set_item(0, w.get_country());
|
||||
return result;
|
||||
}
|
||||
|
||||
python::tuple world_getstate(const world& w) {
|
||||
python::tuple result(1);
|
||||
result.set_item(0, w.get_secret_number());
|
||||
return result;
|
||||
}
|
||||
|
||||
void world_setstate(world& w, python::tuple state) {
|
||||
if (state.size() != 1) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Unexpected argument in call to __setstate__.");
|
||||
throw python::error_already_set();
|
||||
}
|
||||
int number = BOOST_PYTHON_CONVERSION::from_python(state[0].get(),
|
||||
python::type<int>());
|
||||
if (number != 42)
|
||||
w.set_secret_number(number);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started3)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started3");
|
||||
|
||||
// Create the Python type object for our extension class.
|
||||
python::class_builder<world> world_class(this_module, "world");
|
||||
|
||||
// Add the __init__ function.
|
||||
world_class.def(python::constructor<std::string>());
|
||||
// Add a regular member function.
|
||||
world_class.def(&world::greet, "greet");
|
||||
world_class.def(&world::get_secret_number, "get_secret_number");
|
||||
world_class.def(&world::set_secret_number, "set_secret_number");
|
||||
|
||||
// Support for pickle.
|
||||
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
|
||||
}
|
||||
}
|
||||
45
example/ivect.cpp
Normal file
45
example/ivect.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
// See root/libs/python/doc/cross_module.html for an introduction.
|
||||
|
||||
#include "dvect.h"
|
||||
#include "ivect.h"
|
||||
#include <boost/python/cross_module.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
namespace {
|
||||
|
||||
# include "dvect_conversions.cpp"
|
||||
# include "ivect_conversions.cpp"
|
||||
|
||||
vects::dvect ivect_as_dvect(const vects::ivect& iv)
|
||||
{
|
||||
vects::dvect dv(iv.size());
|
||||
vects::dvect::iterator dviter = dv.begin();
|
||||
for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast<double>(iv[i]);
|
||||
return dv;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(ivect)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("ivect");
|
||||
|
||||
python::class_builder<vects::ivect> ivect_class(this_module, "ivect");
|
||||
python::export_converters(ivect_class);
|
||||
|
||||
python::import_converters<vects::dvect> dvect_converters("dvect", "dvect");
|
||||
|
||||
ivect_class.def(python::constructor<python::tuple>());
|
||||
ivect_class.def(&vects::ivect::as_tuple, "as_tuple");
|
||||
ivect_class.def(ivect_as_dvect, "as_dvect");
|
||||
|
||||
# include "dvect_defs.cpp"
|
||||
# include "ivect_defs.cpp"
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
30
example/ivect.h
Normal file
30
example/ivect.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef IVECT_H
|
||||
#define IVECT_H
|
||||
|
||||
#include <vector>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace vects {
|
||||
|
||||
struct ivect : public std::vector<int>
|
||||
{
|
||||
ivect() : std::vector<int>() {}
|
||||
ivect(size_t n) : std::vector<int>(n) {}
|
||||
ivect(boost::python::tuple tuple) : std::vector<int>(tuple.size())
|
||||
{
|
||||
std::vector<int>::iterator v_it = begin();
|
||||
for (int i = 0; i < tuple.size(); i++)
|
||||
v_it[i] = from_python(tuple[i].get(), boost::python::type<int>());
|
||||
}
|
||||
|
||||
boost::python::tuple as_tuple() const
|
||||
{
|
||||
boost::python::tuple t(size());
|
||||
for (int i = 0; i < size(); i++)
|
||||
t.set_item(i, (*this)[i]);
|
||||
return t;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // IVECT_H
|
||||
51
example/ivect_conversions.cpp
Normal file
51
example/ivect_conversions.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// basics first: const reference converters
|
||||
boost::python::tuple const_ivect_reference_as_tuple(const vects::ivect& iv)
|
||||
{
|
||||
return iv.as_tuple();
|
||||
}
|
||||
|
||||
// to_python smart pointer conversions
|
||||
std::auto_ptr<vects::ivect> ivect_as_auto_ptr(const vects::ivect& iv)
|
||||
{
|
||||
return std::auto_ptr<vects::ivect>(new vects::ivect(iv));
|
||||
}
|
||||
boost::shared_ptr<vects::ivect> ivect_as_shared_ptr(const vects::ivect& iv)
|
||||
{
|
||||
return boost::shared_ptr<vects::ivect>(new vects::ivect(iv));
|
||||
}
|
||||
|
||||
// smart pointers passed by value
|
||||
boost::python::ref auto_ptr_value_ivect_as_tuple(std::auto_ptr<vects::ivect> iv)
|
||||
{
|
||||
if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return iv->as_tuple().reference();
|
||||
}
|
||||
boost::python::ref shared_ptr_value_ivect_as_tuple(boost::shared_ptr<vects::ivect> iv)
|
||||
{
|
||||
if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return iv->as_tuple().reference();
|
||||
}
|
||||
|
||||
// smart pointers passed by reference
|
||||
boost::python::ref auto_ptr_reference_ivect_as_tuple(std::auto_ptr<vects::ivect>& iv)
|
||||
{
|
||||
if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return iv->as_tuple().reference();
|
||||
}
|
||||
boost::python::ref shared_ptr_reference_ivect_as_tuple(boost::shared_ptr<vects::ivect>& iv)
|
||||
{
|
||||
if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return iv->as_tuple().reference();
|
||||
}
|
||||
|
||||
// smart pointers passed by const reference
|
||||
boost::python::ref auto_ptr_const_reference_ivect_as_tuple(const std::auto_ptr<vects::ivect>& iv)
|
||||
{
|
||||
if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return iv->as_tuple().reference();
|
||||
}
|
||||
boost::python::ref shared_ptr_const_reference_ivect_as_tuple(const boost::shared_ptr<vects::ivect>& iv)
|
||||
{
|
||||
if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count);
|
||||
return iv->as_tuple().reference();
|
||||
}
|
||||
13
example/ivect_defs.cpp
Normal file
13
example/ivect_defs.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
this_module.def(ivect_as_auto_ptr, "ivect_as_auto_ptr");
|
||||
this_module.def(ivect_as_shared_ptr, "ivect_as_shared_ptr");
|
||||
|
||||
this_module.def(const_ivect_reference_as_tuple, "const_ivect_reference_as_tuple");
|
||||
|
||||
this_module.def(auto_ptr_value_ivect_as_tuple, "auto_ptr_value_ivect_as_tuple");
|
||||
this_module.def(shared_ptr_value_ivect_as_tuple, "shared_ptr_value_ivect_as_tuple");
|
||||
|
||||
this_module.def(auto_ptr_reference_ivect_as_tuple, "auto_ptr_reference_ivect_as_tuple");
|
||||
this_module.def(shared_ptr_reference_ivect_as_tuple, "shared_ptr_reference_ivect_as_tuple");
|
||||
|
||||
this_module.def(auto_ptr_const_reference_ivect_as_tuple, "auto_ptr_const_reference_ivect_as_tuple");
|
||||
this_module.def(shared_ptr_const_reference_ivect_as_tuple, "shared_ptr_const_reference_ivect_as_tuple");
|
||||
14
example/noncopyable.h
Normal file
14
example/noncopyable.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef NONCOPYABLE_H
|
||||
#define NONCOPYABLE_H
|
||||
|
||||
class store
|
||||
{
|
||||
private:
|
||||
store(const store&) { } // Disable the copy constructor.
|
||||
int number;
|
||||
public:
|
||||
store(const int i) : number(i) { }
|
||||
int recall() const { return number; }
|
||||
};
|
||||
|
||||
#endif // NONCOPYABLE_H
|
||||
25
example/noncopyable_export.cpp
Normal file
25
example/noncopyable_export.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
// See root/libs/python/doc/cross_module.html for an introduction.
|
||||
|
||||
#include <boost/python/cross_module.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
#include "noncopyable.h"
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(noncopyable_export)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("noncopyable_export");
|
||||
|
||||
python::class_builder<store> store_class(this_module, "store");
|
||||
python::export_converters_noncopyable(store_class);
|
||||
|
||||
store_class.def(python::constructor<int>());
|
||||
store_class.def(&store::recall, "recall");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
42
example/noncopyable_import.cpp
Normal file
42
example/noncopyable_import.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
// See root/libs/python/doc/cross_module.html for an introduction.
|
||||
|
||||
#include <boost/python/cross_module.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
#include "noncopyable.h"
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A function with store objects as both input and output parameters.
|
||||
// Because the copy constructor is disabled, we cannot pass a store
|
||||
// object by value. Instead, we pass a smart pointer.
|
||||
std::auto_ptr<store> add_stores(const store& s1, const store& s2)
|
||||
{
|
||||
int sum = s1.recall() + s2.recall();
|
||||
std::auto_ptr<store> ss = std::auto_ptr<store>(new store(sum));
|
||||
return ss;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(noncopyable_import)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("noncopyable_import");
|
||||
|
||||
python::import_converters<store>
|
||||
dvect_converters("noncopyable_export", "store");
|
||||
|
||||
// Imagine all the additional classes with member functions
|
||||
// that have store objects as input and output parameters.
|
||||
// Lots and lots of them.
|
||||
// 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
|
||||
}
|
||||
}
|
||||
64
example/pickle1.cpp
Normal file
64
example/pickle1.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
/*
|
||||
This example shows how to make an Extension Class "pickleable".
|
||||
|
||||
The world class below can be fully restored by passing the
|
||||
appropriate argument to the constructor. Therefore it is sufficient
|
||||
to define the pickle interface method __getinitargs__.
|
||||
|
||||
For more information refer to boost/libs/python/doc/pickle.html.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
private:
|
||||
std::string country;
|
||||
int secret_number;
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
};
|
||||
|
||||
// Support for pickle.
|
||||
python::ref world_getinitargs(const world& w) {
|
||||
python::tuple result(1);
|
||||
result.set_item(0, w.get_country());
|
||||
return result.reference();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle1");
|
||||
|
||||
// Create the Python type object for our extension class.
|
||||
python::class_builder<world> world_class(this_module, "world");
|
||||
|
||||
// Add the __init__ function.
|
||||
world_class.def(python::constructor<std::string>());
|
||||
// Add a regular member function.
|
||||
world_class.def(&world::greet, "greet");
|
||||
|
||||
// Support for pickle.
|
||||
world_class.def(world_getinitargs, "__getinitargs__");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
98
example/pickle2.cpp
Normal file
98
example/pickle2.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
/*
|
||||
This example shows how to make an Extension Class "pickleable".
|
||||
|
||||
The world class below contains member data (secret_number) that
|
||||
cannot be restored by any of the constructors. Therefore it is
|
||||
necessary to provide the __getstate__/__setstate__ pair of pickle
|
||||
interface methods.
|
||||
|
||||
For simplicity, the __dict__ is not included in the result of
|
||||
__getstate__. This is not generally recommended, but a valid
|
||||
approach if it is anticipated that the object's __dict__ will
|
||||
always be empty. Note that safety guard are provided to catch the
|
||||
cases where this assumption is not true.
|
||||
|
||||
pickle3.cpp shows how to include the object's __dict__ in the
|
||||
result of __getstate__.
|
||||
|
||||
For more information refer to boost/libs/python/doc/pickle.html.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
void set_secret_number(int number) { secret_number = number; }
|
||||
int get_secret_number() const { return secret_number; }
|
||||
private:
|
||||
std::string country;
|
||||
int secret_number;
|
||||
};
|
||||
|
||||
// Support for pickle.
|
||||
|
||||
python::ref world_getinitargs(const world& w) {
|
||||
python::tuple result(1);
|
||||
result.set_item(0, w.get_country());
|
||||
return result.reference(); // returning the reference avoids the copying.
|
||||
}
|
||||
|
||||
python::ref world_getstate(const world& w) {
|
||||
python::tuple result(1);
|
||||
result.set_item(0, w.get_secret_number());
|
||||
return result.reference(); // returning the reference avoids the copying.
|
||||
}
|
||||
|
||||
void world_setstate(world& w, python::tuple state) {
|
||||
if (state.size() != 1) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Unexpected argument in call to __setstate__.");
|
||||
throw python::error_already_set();
|
||||
}
|
||||
int number = from_python(state[0].get(), python::type<int>());
|
||||
if (number != 42)
|
||||
w.set_secret_number(number);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle2");
|
||||
|
||||
// Create the Python type object for our extension class.
|
||||
python::class_builder<world> world_class(this_module, "world");
|
||||
|
||||
// Add the __init__ function.
|
||||
world_class.def(python::constructor<std::string>());
|
||||
// Add a regular member function.
|
||||
world_class.def(&world::greet, "greet");
|
||||
world_class.def(&world::get_secret_number, "get_secret_number");
|
||||
world_class.def(&world::set_secret_number, "set_secret_number");
|
||||
|
||||
// Support for pickle.
|
||||
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
|
||||
}
|
||||
}
|
||||
149
example/pickle3.cpp
Normal file
149
example/pickle3.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
/*
|
||||
This example shows how to make an Extension Class "pickleable".
|
||||
|
||||
The world class below contains member data (secret_number) that
|
||||
cannot be restored by any of the constructors. Therefore it is
|
||||
necessary to provide the __getstate__/__setstate__ pair of pickle
|
||||
interface methods.
|
||||
|
||||
The object's __dict__ is included in the result of __getstate__.
|
||||
This requires more code (compare with pickle2.cpp), but is
|
||||
unavoidable if the object's __dict__ is not always empty.
|
||||
|
||||
For more information refer to boost/libs/python/doc/pickle.html.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
ref getattr(PyObject* o, const std::string& attr_name) {
|
||||
return ref(PyObject_GetAttrString(o, const_cast<char*>(attr_name.c_str())));
|
||||
}
|
||||
ref getattr(const ref& r, const std::string& attr_name) {
|
||||
return getattr(r.get(), attr_name);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
void set_secret_number(int number) { secret_number = number; }
|
||||
int get_secret_number() const { return secret_number; }
|
||||
private:
|
||||
std::string country;
|
||||
int secret_number;
|
||||
};
|
||||
|
||||
// Support for pickle.
|
||||
python::ref world_getinitargs(const world& w) {
|
||||
python::tuple result(1);
|
||||
result.set_item(0, w.get_country());
|
||||
return result.reference(); // returning the reference avoids the copying.
|
||||
}
|
||||
|
||||
python::ref world_getstate(python::tuple const & args,
|
||||
python::dictionary const & keywords);
|
||||
|
||||
PyObject* world_setstate(python::tuple const & args,
|
||||
python::dictionary const & keywords);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle3)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle3");
|
||||
|
||||
// Create the Python type object for our extension class.
|
||||
python::class_builder<world> world_class(this_module, "world");
|
||||
|
||||
// Add the __init__ function.
|
||||
world_class.def(python::constructor<std::string>());
|
||||
// Add a regular member function.
|
||||
world_class.def(&world::greet, "greet");
|
||||
world_class.def(&world::get_secret_number, "get_secret_number");
|
||||
world_class.def(&world::set_secret_number, "set_secret_number");
|
||||
|
||||
// Support for pickle.
|
||||
world_class.def(world_getinitargs, "__getinitargs__");
|
||||
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 {
|
||||
|
||||
using boost::python::type;
|
||||
using boost::python::ref;
|
||||
using boost::python::tuple;
|
||||
using boost::python::list;
|
||||
using boost::python::dictionary;
|
||||
using boost::python::getattr;
|
||||
|
||||
ref world_getstate(tuple const & args, dictionary const & keywords)
|
||||
{
|
||||
if(args.size() != 1 || keywords.size() != 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
const world& w = from_python(args[0].get(), type<const world&>());
|
||||
ref mydict = getattr(args[0], "__dict__");
|
||||
tuple result(2);
|
||||
// store the object's __dict__
|
||||
result.set_item(0, mydict);
|
||||
// store the internal state of the C++ object
|
||||
result.set_item(1, w.get_secret_number());
|
||||
return result.reference(); // returning the reference avoids the copying.
|
||||
}
|
||||
|
||||
PyObject* world_setstate(tuple const & args, dictionary const & keywords)
|
||||
{
|
||||
if(args.size() != 2 || keywords.size() != 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
world& w = from_python(args[0].get(), type<world&>());
|
||||
ref mydict = getattr(args[0], "__dict__");
|
||||
tuple state = from_python(args[1].get(), type<tuple>());
|
||||
if (state.size() != 2) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Unexpected argument in call to __setstate__.");
|
||||
throw python::error_already_set();
|
||||
}
|
||||
// restore the object's __dict__
|
||||
dictionary odict = from_python(mydict.get(), type<dictionary>());
|
||||
const dictionary& pdict = from_python(state[0].get(), type<const dictionary&>());
|
||||
list pkeys(pdict.keys());
|
||||
for (int i = 0; i < pkeys.size(); i++) {
|
||||
ref k(pkeys[i]);
|
||||
//odict[k] = pdict[k]; // XXX memory leak!
|
||||
odict[k] = pdict.get_item(k); // this does not leak.
|
||||
}
|
||||
// restore the internal state of the C++ object
|
||||
int number = from_python(state[1].get(), type<int>());
|
||||
if (number != 42)
|
||||
w.set_secret_number(number);
|
||||
return python::detail::none();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
@@ -15,7 +17,7 @@ namespace { // Avoid cluttering the global namespace.
|
||||
vector_double_wrapper(PyObject* self)
|
||||
: std::vector<double>() {}
|
||||
|
||||
vector_double_wrapper(PyObject* self, const int n)
|
||||
vector_double_wrapper(PyObject* self, int n)
|
||||
: std::vector<double>(n) {}
|
||||
|
||||
vector_double_wrapper(PyObject* self, python::tuple tuple)
|
||||
@@ -23,24 +25,30 @@ namespace { // Avoid cluttering the global namespace.
|
||||
{
|
||||
std::vector<double>::iterator vd = begin();
|
||||
for (int i = 0; i < tuple.size(); i++)
|
||||
vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(),
|
||||
python::type<double>());
|
||||
vd[i] = from_python(tuple[i].get(), python::type<double>());
|
||||
}
|
||||
};
|
||||
|
||||
double getitem(const std::vector<double>& vd, const std::size_t key) {
|
||||
void raise_vector_IndexError() {
|
||||
PyErr_SetString(PyExc_IndexError, "vector index out of range");
|
||||
throw python::error_already_set();
|
||||
}
|
||||
|
||||
double getitem(const std::vector<double>& vd, std::size_t key) {
|
||||
if (key >= vd.size()) raise_vector_IndexError();
|
||||
return vd[key];
|
||||
}
|
||||
|
||||
void setitem(std::vector<double>& vd, const std::size_t key,
|
||||
const double &d) {
|
||||
void setitem(std::vector<double>& vd, std::size_t key, double d) {
|
||||
if (key >= vd.size()) raise_vector_IndexError();
|
||||
std::vector<double>::iterator vditer = vd.begin();
|
||||
vditer[key] = d;
|
||||
}
|
||||
|
||||
void delitem(std::vector<double>& vd, const std::size_t key) {
|
||||
void delitem(std::vector<double>& vd, std::size_t key) {
|
||||
if (key >= vd.size()) raise_vector_IndexError();
|
||||
std::vector<double>::iterator vditer = vd.begin();
|
||||
vd.erase(&vditer[key]);
|
||||
vd.erase(vditer + key);
|
||||
}
|
||||
|
||||
// Convert vector_double to a regular Python tuple.
|
||||
@@ -48,14 +56,14 @@ namespace { // Avoid cluttering the global namespace.
|
||||
python::tuple as_tuple(const std::vector<double>& vd)
|
||||
{
|
||||
python::tuple t(vd.size());
|
||||
for (int i = 0; i < vd.size(); i++) t.set_item(i,
|
||||
python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i])));
|
||||
for (int i = 0; i < vd.size(); i++)
|
||||
t.set_item(i, vd[i]);
|
||||
return t;
|
||||
}
|
||||
|
||||
// Function returning a vector_double object to Python.
|
||||
//
|
||||
std::vector<double> foo(const int n)
|
||||
std::vector<double> foo(int n)
|
||||
{
|
||||
std::vector<double> vd(n);
|
||||
std::vector<double>::iterator vditer = vd.begin();
|
||||
@@ -65,7 +73,7 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// Same as foo(), but avoid copying on return.
|
||||
//
|
||||
std::auto_ptr<std::vector<double> > bar(const int n)
|
||||
std::auto_ptr<std::vector<double> > bar(int n)
|
||||
{
|
||||
std::auto_ptr<std::vector<double> > vdptr(new std::vector<double>(n));
|
||||
std::vector<double>::iterator vditer = vdptr->begin();
|
||||
@@ -74,11 +82,11 @@ namespace { // Avoid cluttering the global namespace.
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started4)
|
||||
BOOST_PYTHON_MODULE_INIT(simple_vector)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("getting_started4");
|
||||
python::module_builder this_module("simple_vector");
|
||||
|
||||
python::class_builder<std::vector<double>, vector_double_wrapper>
|
||||
vector_double(this_module, "vector_double");
|
||||
139
example/test_cross_module.py
Normal file
139
example/test_cross_module.py
Normal file
@@ -0,0 +1,139 @@
|
||||
r'''>>> import tst_noncopyable
|
||||
>>> tst_noncopyable.f()
|
||||
1
|
||||
2
|
||||
3
|
||||
>>> import tst_dvect1
|
||||
>>> tst_dvect1.f()
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
(1, 2, 3, 4, 5)
|
||||
(1, 2, 3, 4, 5)
|
||||
(1, 2, 3, 4, 5)
|
||||
(1, 2, 3, 4, 5)
|
||||
(1, 2, 3, 4, 5)
|
||||
(1, 2, 3, 4, 5)
|
||||
>>> import tst_ivect1
|
||||
>>> tst_ivect1.f()
|
||||
(1, 2, 3, 4, 5)
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
>>> import sys
|
||||
>>> if ("--broken-auto-ptr" in sys.argv):
|
||||
... broken_auto_ptr = 1
|
||||
... else:
|
||||
... broken_auto_ptr = 0
|
||||
>>> import tst_dvect2
|
||||
>>> tst_dvect2.f(broken_auto_ptr)
|
||||
1. auto_ptr_value_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. auto_ptr_value_ivect_as_tuple
|
||||
None
|
||||
1. auto_ptr_value_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. auto_ptr_value_dvect_as_tuple
|
||||
None
|
||||
1. shared_ptr_value_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. shared_ptr_value_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. shared_ptr_value_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. shared_ptr_value_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. auto_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. auto_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. auto_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. auto_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. shared_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. shared_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. shared_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. shared_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. auto_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. auto_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. auto_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. auto_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. shared_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. shared_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. shared_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. shared_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
>>> import tst_ivect2
|
||||
>>> tst_ivect2.f(broken_auto_ptr)
|
||||
1. auto_ptr_value_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. auto_ptr_value_dvect_as_tuple
|
||||
None
|
||||
1. auto_ptr_value_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. auto_ptr_value_ivect_as_tuple
|
||||
None
|
||||
1. shared_ptr_value_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. shared_ptr_value_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. shared_ptr_value_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. shared_ptr_value_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. auto_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. auto_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. auto_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. auto_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. shared_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. shared_ptr_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. shared_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. shared_ptr_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. auto_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. auto_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. auto_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. auto_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
1. shared_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
2. shared_ptr_const_reference_dvect_as_tuple
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0)
|
||||
1. shared_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
2. shared_ptr_const_reference_ivect_as_tuple
|
||||
(1, 2, 3, 4, 5)
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_cross_module
|
||||
doctest.testmod(test_cross_module)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
@@ -1,5 +1,5 @@
|
||||
r'''>>> import getting_started5
|
||||
>>> ixset = getting_started5.IndexingSet()
|
||||
r'''>>> import do_it_yourself_converters
|
||||
>>> ixset = do_it_yourself_converters.IndexingSet()
|
||||
>>> ixset.add((1,2,3))
|
||||
>>> ixset.add((4,5,6))
|
||||
>>> ixset.add((7,8,9))
|
||||
@@ -15,8 +15,8 @@ def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started5
|
||||
doctest.testmod(test_getting_started5)
|
||||
import doctest, test_do_it_yourself_converters
|
||||
doctest.testmod(test_do_it_yourself_converters)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
@@ -1,56 +0,0 @@
|
||||
r'''>>> import getting_started3
|
||||
>>> import re
|
||||
>>> import pickle
|
||||
>>> getting_started3.world.__module__
|
||||
'getting_started3'
|
||||
>>> getting_started3.world.__safe_for_unpickling__
|
||||
1
|
||||
>>> getting_started3.world.__reduce__()
|
||||
'world'
|
||||
>>> assert re.match(
|
||||
... "\(<extension class getting_started3.world at [0-9a-fA-FxX]+>, \('Hello',\), \(0,\)\)",
|
||||
... repr(getting_started3.world('Hello').__reduce__()))
|
||||
>>>
|
||||
>>> for number in (24, 42):
|
||||
... wd = getting_started3.world('California')
|
||||
... wd.set_secret_number(number)
|
||||
... pstr = pickle.dumps(wd)
|
||||
... print pstr
|
||||
... wl = pickle.loads(pstr)
|
||||
... print wd.greet(), wd.get_secret_number()
|
||||
... print wl.greet(), wl.get_secret_number()
|
||||
cgetting_started3
|
||||
world
|
||||
p0
|
||||
(S'California'
|
||||
p1
|
||||
tp2
|
||||
R(I24
|
||||
tp3
|
||||
bp4
|
||||
.
|
||||
Hello from California! 24
|
||||
Hello from California! 24
|
||||
cgetting_started3
|
||||
world
|
||||
p0
|
||||
(S'California'
|
||||
p1
|
||||
tp2
|
||||
R(I42
|
||||
tp3
|
||||
bp4
|
||||
.
|
||||
Hello from California! 42
|
||||
Hello from California! 0
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started3
|
||||
doctest.testmod(test_getting_started3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
31
example/test_pickle1.py
Normal file
31
example/test_pickle1.py
Normal file
@@ -0,0 +1,31 @@
|
||||
r'''>>> import pickle1
|
||||
>>> import re
|
||||
>>> import pickle
|
||||
>>> pickle1.world.__module__
|
||||
'pickle1'
|
||||
>>> pickle1.world.__safe_for_unpickling__
|
||||
1
|
||||
>>> pickle1.world.__reduce__()
|
||||
'world'
|
||||
>>> assert re.match(
|
||||
... "\(<extension class pickle1.world at [0-9a-fA-FxX]+>, \('Hello',\)\)",
|
||||
... repr(pickle1.world('Hello').__reduce__()))
|
||||
>>>
|
||||
>>> wd = pickle1.world('California')
|
||||
>>> pstr = pickle.dumps(wd)
|
||||
>>> wl = pickle.loads(pstr)
|
||||
>>> print wd.greet()
|
||||
Hello from California!
|
||||
>>> print wl.greet()
|
||||
Hello from California!
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_pickle1
|
||||
doctest.testmod(test_pickle1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
45
example/test_pickle2.py
Normal file
45
example/test_pickle2.py
Normal file
@@ -0,0 +1,45 @@
|
||||
r'''>>> import pickle2
|
||||
>>> import re
|
||||
>>> import pickle
|
||||
>>> pickle2.world.__module__
|
||||
'pickle2'
|
||||
>>> pickle2.world.__safe_for_unpickling__
|
||||
1
|
||||
>>> pickle2.world.__reduce__()
|
||||
'world'
|
||||
>>> assert re.match(
|
||||
... "\(<extension class pickle2.world at [0-9a-fA-FxX]+>, \('Hello',\), \(0,\)\)",
|
||||
... repr(pickle2.world('Hello').__reduce__()))
|
||||
>>>
|
||||
>>> for number in (24, 42):
|
||||
... wd = pickle2.world('California')
|
||||
... wd.set_secret_number(number)
|
||||
... pstr = pickle.dumps(wd)
|
||||
... wl = pickle.loads(pstr)
|
||||
... print wd.greet(), wd.get_secret_number()
|
||||
... print wl.greet(), wl.get_secret_number()
|
||||
Hello from California! 24
|
||||
Hello from California! 24
|
||||
Hello from California! 42
|
||||
Hello from California! 0
|
||||
|
||||
# Now show that the __dict__ is not taken care of.
|
||||
>>> wd = pickle2.world('California')
|
||||
>>> wd.x = 1
|
||||
>>> wd.__dict__
|
||||
{'x': 1}
|
||||
>>> try: pstr = pickle.dumps(wd)
|
||||
... except RuntimeError, err: print err[0]
|
||||
...
|
||||
Incomplete pickle support (__getstate_manages_dict__ not set)
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_pickle2
|
||||
doctest.testmod(test_pickle2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
38
example/test_pickle3.py
Normal file
38
example/test_pickle3.py
Normal file
@@ -0,0 +1,38 @@
|
||||
r'''>>> import pickle3
|
||||
>>> import re
|
||||
>>> import pickle
|
||||
>>> pickle3.world.__module__
|
||||
'pickle3'
|
||||
>>> pickle3.world.__safe_for_unpickling__
|
||||
1
|
||||
>>> pickle3.world.__reduce__()
|
||||
'world'
|
||||
>>> assert re.match(
|
||||
... "\(<extension class pickle3.world at [0-9a-fA-FxX]+>, \('Hello',\), \(\{\}, 0\)\)",
|
||||
... repr(pickle3.world('Hello').__reduce__()))
|
||||
>>>
|
||||
>>> for number in (24, 42):
|
||||
... wd = pickle3.world('California')
|
||||
... wd.set_secret_number(number)
|
||||
... wd.x = 2 * number
|
||||
... wd.y = 'y' * number
|
||||
... wd.z = 3. * number
|
||||
... pstr = pickle.dumps(wd)
|
||||
... wl = pickle.loads(pstr)
|
||||
... print wd.greet(), wd.get_secret_number(), wd.__dict__
|
||||
... print wl.greet(), wl.get_secret_number(), wl.__dict__
|
||||
Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'}
|
||||
Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'}
|
||||
Hello from California! 42 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'}
|
||||
Hello from California! 0 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'}
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_pickle3
|
||||
doctest.testmod(test_pickle3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
@@ -1,13 +1,13 @@
|
||||
r'''>>> import getting_started4
|
||||
>>> v=getting_started4.vector_double()
|
||||
r'''>>> import simple_vector
|
||||
>>> v=simple_vector.vector_double()
|
||||
>>> print v.as_tuple()
|
||||
()
|
||||
>>> v=getting_started4.vector_double(5)
|
||||
>>> v=simple_vector.vector_double(5)
|
||||
>>> print v.as_tuple()
|
||||
(0.0, 0.0, 0.0, 0.0, 0.0)
|
||||
>>> print len(v)
|
||||
5
|
||||
>>> v=getting_started4.vector_double((3,4,5))
|
||||
>>> v=simple_vector.vector_double((3,4,5))
|
||||
>>> print v.as_tuple()
|
||||
(3.0, 4.0, 5.0)
|
||||
>>> print v[1]
|
||||
@@ -15,12 +15,17 @@ r'''>>> import getting_started4
|
||||
>>> v[1] = 40
|
||||
>>> print v.as_tuple()
|
||||
(3.0, 40.0, 5.0)
|
||||
>>> for e in v:
|
||||
... print e
|
||||
3.0
|
||||
40.0
|
||||
5.0
|
||||
>>> del v[1]
|
||||
>>> print v.as_tuple()
|
||||
(3.0, 5.0)
|
||||
>>> print getting_started4.foo(11).as_tuple()
|
||||
>>> print simple_vector.foo(11).as_tuple()
|
||||
(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0)
|
||||
>>> print getting_started4.bar(12).as_tuple()
|
||||
>>> print simple_vector.bar(12).as_tuple()
|
||||
(0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0)
|
||||
'''
|
||||
|
||||
@@ -28,8 +33,8 @@ def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started4
|
||||
doctest.testmod(test_getting_started4)
|
||||
import doctest, test_simple_vector
|
||||
doctest.testmod(test_simple_vector)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
20
example/tst_dvect1.py
Normal file
20
example/tst_dvect1.py
Normal file
@@ -0,0 +1,20 @@
|
||||
def f():
|
||||
import dvect
|
||||
dv = dvect.dvect((1,2,3,4,5))
|
||||
print dv.as_tuple()
|
||||
iv = dv.as_ivect()
|
||||
print iv.as_tuple()
|
||||
print dvect.const_ivect_reference_as_tuple(iv)
|
||||
aiv = dvect.ivect_as_auto_ptr(iv)
|
||||
print dvect.const_ivect_reference_as_tuple(aiv)
|
||||
siv = dvect.ivect_as_shared_ptr(iv)
|
||||
print dvect.const_ivect_reference_as_tuple(siv)
|
||||
print aiv.as_tuple()
|
||||
print siv.as_tuple()
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
import sys, string
|
||||
n = 1
|
||||
if (len(sys.argv) > 1): n = string.atoi(sys.argv[1])
|
||||
for i in xrange(n):
|
||||
f()
|
||||
98
example/tst_dvect2.py
Normal file
98
example/tst_dvect2.py
Normal file
@@ -0,0 +1,98 @@
|
||||
def f(broken_auto_ptr):
|
||||
import dvect
|
||||
import ivect
|
||||
#
|
||||
dv = dvect.dvect((1,2,3,4,5))
|
||||
iv = dv.as_ivect()
|
||||
#
|
||||
aiv = dvect.ivect_as_auto_ptr(iv)
|
||||
print '1. auto_ptr_value_ivect_as_tuple'
|
||||
print ivect.auto_ptr_value_ivect_as_tuple(aiv)
|
||||
print '2. auto_ptr_value_ivect_as_tuple'
|
||||
if (not broken_auto_ptr):
|
||||
print ivect.auto_ptr_value_ivect_as_tuple(aiv)
|
||||
else:
|
||||
print None
|
||||
#
|
||||
adv = dvect.dvect_as_auto_ptr(dv)
|
||||
print '1. auto_ptr_value_dvect_as_tuple'
|
||||
print ivect.auto_ptr_value_dvect_as_tuple(adv)
|
||||
print '2. auto_ptr_value_dvect_as_tuple'
|
||||
if (not broken_auto_ptr):
|
||||
print ivect.auto_ptr_value_dvect_as_tuple(adv)
|
||||
else:
|
||||
print None
|
||||
#
|
||||
siv = dvect.ivect_as_shared_ptr(iv)
|
||||
print '1. shared_ptr_value_ivect_as_tuple'
|
||||
print ivect.shared_ptr_value_ivect_as_tuple(siv)
|
||||
print '2. shared_ptr_value_ivect_as_tuple'
|
||||
print ivect.shared_ptr_value_ivect_as_tuple(siv)
|
||||
#
|
||||
sdv = dvect.dvect_as_shared_ptr(dv)
|
||||
print '1. shared_ptr_value_dvect_as_tuple'
|
||||
print ivect.shared_ptr_value_dvect_as_tuple(sdv)
|
||||
print '2. shared_ptr_value_dvect_as_tuple'
|
||||
print ivect.shared_ptr_value_dvect_as_tuple(sdv)
|
||||
#
|
||||
aiv = dvect.ivect_as_auto_ptr(iv)
|
||||
print '1. auto_ptr_reference_ivect_as_tuple'
|
||||
print ivect.auto_ptr_reference_ivect_as_tuple(aiv)
|
||||
print '2. auto_ptr_reference_ivect_as_tuple'
|
||||
print ivect.auto_ptr_reference_ivect_as_tuple(aiv)
|
||||
#
|
||||
adv = dvect.dvect_as_auto_ptr(dv)
|
||||
print '1. auto_ptr_reference_dvect_as_tuple'
|
||||
print ivect.auto_ptr_reference_dvect_as_tuple(adv)
|
||||
print '2. auto_ptr_reference_dvect_as_tuple'
|
||||
print ivect.auto_ptr_reference_dvect_as_tuple(adv)
|
||||
#
|
||||
siv = dvect.ivect_as_shared_ptr(iv)
|
||||
print '1. shared_ptr_reference_ivect_as_tuple'
|
||||
print ivect.shared_ptr_reference_ivect_as_tuple(siv)
|
||||
print '2. shared_ptr_reference_ivect_as_tuple'
|
||||
print ivect.shared_ptr_reference_ivect_as_tuple(siv)
|
||||
#
|
||||
sdv = dvect.dvect_as_shared_ptr(dv)
|
||||
print '1. shared_ptr_reference_dvect_as_tuple'
|
||||
print ivect.shared_ptr_reference_dvect_as_tuple(sdv)
|
||||
print '2. shared_ptr_reference_dvect_as_tuple'
|
||||
print ivect.shared_ptr_reference_dvect_as_tuple(sdv)
|
||||
#
|
||||
aiv = dvect.ivect_as_auto_ptr(iv)
|
||||
print '1. auto_ptr_const_reference_ivect_as_tuple'
|
||||
print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv)
|
||||
print '2. auto_ptr_const_reference_ivect_as_tuple'
|
||||
print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv)
|
||||
#
|
||||
adv = dvect.dvect_as_auto_ptr(dv)
|
||||
print '1. auto_ptr_const_reference_dvect_as_tuple'
|
||||
print ivect.auto_ptr_const_reference_dvect_as_tuple(adv)
|
||||
print '2. auto_ptr_const_reference_dvect_as_tuple'
|
||||
print ivect.auto_ptr_const_reference_dvect_as_tuple(adv)
|
||||
#
|
||||
siv = dvect.ivect_as_shared_ptr(iv)
|
||||
print '1. shared_ptr_const_reference_ivect_as_tuple'
|
||||
print ivect.shared_ptr_const_reference_ivect_as_tuple(siv)
|
||||
print '2. shared_ptr_const_reference_ivect_as_tuple'
|
||||
print ivect.shared_ptr_const_reference_ivect_as_tuple(siv)
|
||||
#
|
||||
sdv = dvect.dvect_as_shared_ptr(dv)
|
||||
print '1. shared_ptr_const_reference_dvect_as_tuple'
|
||||
print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv)
|
||||
print '2. shared_ptr_const_reference_dvect_as_tuple'
|
||||
print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv)
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
import sys, string
|
||||
broken_auto_ptr = 0
|
||||
n = 1
|
||||
if (len(sys.argv) > 1):
|
||||
if (sys.argv[1] == "--broken-auto-ptr"):
|
||||
broken_auto_ptr = 1
|
||||
if (len(sys.argv) > 2):
|
||||
n = string.atoi(sys.argv[2])
|
||||
else:
|
||||
n = string.atoi(sys.argv[1])
|
||||
for i in xrange(n):
|
||||
f(broken_auto_ptr)
|
||||
20
example/tst_ivect1.py
Normal file
20
example/tst_ivect1.py
Normal file
@@ -0,0 +1,20 @@
|
||||
def f():
|
||||
import ivect
|
||||
iv = ivect.ivect((1,2,3,4,5))
|
||||
print iv.as_tuple()
|
||||
dv = iv.as_dvect()
|
||||
print dv.as_tuple()
|
||||
print ivect.const_dvect_reference_as_tuple(dv)
|
||||
adv = ivect.dvect_as_auto_ptr(dv)
|
||||
print ivect.const_dvect_reference_as_tuple(adv)
|
||||
sdv = ivect.dvect_as_shared_ptr(dv)
|
||||
print ivect.const_dvect_reference_as_tuple(sdv)
|
||||
print adv.as_tuple()
|
||||
print sdv.as_tuple()
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
import sys, string
|
||||
n = 1
|
||||
if (len(sys.argv) > 1): n = string.atoi(sys.argv[1])
|
||||
for i in xrange(n):
|
||||
f()
|
||||
98
example/tst_ivect2.py
Normal file
98
example/tst_ivect2.py
Normal file
@@ -0,0 +1,98 @@
|
||||
def f(broken_auto_ptr):
|
||||
import ivect
|
||||
import dvect
|
||||
#
|
||||
iv = ivect.ivect((1,2,3,4,5))
|
||||
dv = iv.as_dvect()
|
||||
#
|
||||
adv = ivect.dvect_as_auto_ptr(dv)
|
||||
print '1. auto_ptr_value_dvect_as_tuple'
|
||||
print dvect.auto_ptr_value_dvect_as_tuple(adv)
|
||||
print '2. auto_ptr_value_dvect_as_tuple'
|
||||
if (not broken_auto_ptr):
|
||||
print dvect.auto_ptr_value_dvect_as_tuple(adv)
|
||||
else:
|
||||
print None
|
||||
#
|
||||
aiv = ivect.ivect_as_auto_ptr(iv)
|
||||
print '1. auto_ptr_value_ivect_as_tuple'
|
||||
print dvect.auto_ptr_value_ivect_as_tuple(aiv)
|
||||
print '2. auto_ptr_value_ivect_as_tuple'
|
||||
if (not broken_auto_ptr):
|
||||
print dvect.auto_ptr_value_ivect_as_tuple(aiv)
|
||||
else:
|
||||
print None
|
||||
#
|
||||
sdv = ivect.dvect_as_shared_ptr(dv)
|
||||
print '1. shared_ptr_value_dvect_as_tuple'
|
||||
print dvect.shared_ptr_value_dvect_as_tuple(sdv)
|
||||
print '2. shared_ptr_value_dvect_as_tuple'
|
||||
print dvect.shared_ptr_value_dvect_as_tuple(sdv)
|
||||
#
|
||||
siv = ivect.ivect_as_shared_ptr(iv)
|
||||
print '1. shared_ptr_value_ivect_as_tuple'
|
||||
print dvect.shared_ptr_value_ivect_as_tuple(siv)
|
||||
print '2. shared_ptr_value_ivect_as_tuple'
|
||||
print dvect.shared_ptr_value_ivect_as_tuple(siv)
|
||||
#
|
||||
adv = ivect.dvect_as_auto_ptr(dv)
|
||||
print '1. auto_ptr_reference_dvect_as_tuple'
|
||||
print dvect.auto_ptr_reference_dvect_as_tuple(adv)
|
||||
print '2. auto_ptr_reference_dvect_as_tuple'
|
||||
print dvect.auto_ptr_reference_dvect_as_tuple(adv)
|
||||
#
|
||||
aiv = ivect.ivect_as_auto_ptr(iv)
|
||||
print '1. auto_ptr_reference_ivect_as_tuple'
|
||||
print dvect.auto_ptr_reference_ivect_as_tuple(aiv)
|
||||
print '2. auto_ptr_reference_ivect_as_tuple'
|
||||
print dvect.auto_ptr_reference_ivect_as_tuple(aiv)
|
||||
#
|
||||
sdv = ivect.dvect_as_shared_ptr(dv)
|
||||
print '1. shared_ptr_reference_dvect_as_tuple'
|
||||
print dvect.shared_ptr_reference_dvect_as_tuple(sdv)
|
||||
print '2. shared_ptr_reference_dvect_as_tuple'
|
||||
print dvect.shared_ptr_reference_dvect_as_tuple(sdv)
|
||||
#
|
||||
siv = ivect.ivect_as_shared_ptr(iv)
|
||||
print '1. shared_ptr_reference_ivect_as_tuple'
|
||||
print dvect.shared_ptr_reference_ivect_as_tuple(siv)
|
||||
print '2. shared_ptr_reference_ivect_as_tuple'
|
||||
print dvect.shared_ptr_reference_ivect_as_tuple(siv)
|
||||
#
|
||||
adv = ivect.dvect_as_auto_ptr(dv)
|
||||
print '1. auto_ptr_const_reference_dvect_as_tuple'
|
||||
print dvect.auto_ptr_const_reference_dvect_as_tuple(adv)
|
||||
print '2. auto_ptr_const_reference_dvect_as_tuple'
|
||||
print dvect.auto_ptr_const_reference_dvect_as_tuple(adv)
|
||||
#
|
||||
aiv = ivect.ivect_as_auto_ptr(iv)
|
||||
print '1. auto_ptr_const_reference_ivect_as_tuple'
|
||||
print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv)
|
||||
print '2. auto_ptr_const_reference_ivect_as_tuple'
|
||||
print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv)
|
||||
#
|
||||
sdv = ivect.dvect_as_shared_ptr(dv)
|
||||
print '1. shared_ptr_const_reference_dvect_as_tuple'
|
||||
print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv)
|
||||
print '2. shared_ptr_const_reference_dvect_as_tuple'
|
||||
print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv)
|
||||
#
|
||||
siv = ivect.ivect_as_shared_ptr(iv)
|
||||
print '1. shared_ptr_const_reference_ivect_as_tuple'
|
||||
print dvect.shared_ptr_const_reference_ivect_as_tuple(siv)
|
||||
print '2. shared_ptr_const_reference_ivect_as_tuple'
|
||||
print dvect.shared_ptr_const_reference_ivect_as_tuple(siv)
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
import sys, string
|
||||
broken_auto_ptr = 0
|
||||
n = 1
|
||||
if (len(sys.argv) > 1):
|
||||
if (sys.argv[1] == "--broken-auto-ptr"):
|
||||
broken_auto_ptr = 1
|
||||
if (len(sys.argv) > 2):
|
||||
n = string.atoi(sys.argv[2])
|
||||
else:
|
||||
n = string.atoi(sys.argv[1])
|
||||
for i in xrange(n):
|
||||
f(broken_auto_ptr)
|
||||
16
example/tst_noncopyable.py
Normal file
16
example/tst_noncopyable.py
Normal file
@@ -0,0 +1,16 @@
|
||||
def f():
|
||||
import noncopyable_export
|
||||
import noncopyable_import
|
||||
s1 = noncopyable_export.store(1)
|
||||
print s1.recall()
|
||||
s2 = noncopyable_export.store(2)
|
||||
print s2.recall()
|
||||
s3 = noncopyable_import.add_stores(s1, s2)
|
||||
print s3.recall()
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
import sys, string
|
||||
n = 1
|
||||
if (len(sys.argv) > 1): n = string.atoi(sys.argv[1])
|
||||
for i in xrange(n):
|
||||
f()
|
||||
@@ -46,7 +46,7 @@ struct callback
|
||||
template <class A1>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
@@ -57,7 +57,7 @@ struct callback
|
||||
template <class A1>
|
||||
static R call(PyObject* self, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
@@ -67,8 +67,8 @@ struct callback
|
||||
template <class A1, class A2>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
@@ -80,8 +80,8 @@ struct callback
|
||||
template <class A1, class A2>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
@@ -92,9 +92,9 @@ struct callback
|
||||
template <class A1, class A2, class A3>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
@@ -107,9 +107,9 @@ struct callback
|
||||
template <class A1, class A2, class A3>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -121,10 +121,10 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
@@ -138,10 +138,10 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -154,11 +154,11 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
@@ -173,11 +173,11 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -191,12 +191,12 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -212,12 +212,12 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -232,13 +232,13 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -255,13 +255,13 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -277,14 +277,14 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -302,14 +302,14 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -326,15 +326,15 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -353,15 +353,15 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -379,16 +379,16 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref p10(to_python(a10, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -408,16 +408,16 @@ struct callback
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref p10(to_python(a10, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -455,7 +455,7 @@ struct callback<void>
|
||||
template <class A1>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
@@ -464,7 +464,7 @@ struct callback<void>
|
||||
template <class A1>
|
||||
static void call(PyObject* self, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
}
|
||||
@@ -472,8 +472,8 @@ struct callback<void>
|
||||
template <class A1, class A2>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
@@ -483,8 +483,8 @@ struct callback<void>
|
||||
template <class A1, class A2>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
@@ -493,9 +493,9 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
@@ -506,9 +506,9 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -518,10 +518,10 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
@@ -533,10 +533,10 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -547,11 +547,11 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
@@ -564,11 +564,11 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -580,12 +580,12 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -599,12 +599,12 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -617,13 +617,13 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -638,13 +638,13 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -658,14 +658,14 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -681,14 +681,14 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -703,15 +703,15 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -728,15 +728,15 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
@@ -752,16 +752,16 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref p10(to_python(a10, lookup_tag()));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
@@ -779,16 +779,16 @@ struct callback<void>
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref p1(to_python(a1, lookup_tag()));
|
||||
ref p2(to_python(a2, lookup_tag()));
|
||||
ref p3(to_python(a3, lookup_tag()));
|
||||
ref p4(to_python(a4, lookup_tag()));
|
||||
ref p5(to_python(a5, lookup_tag()));
|
||||
ref p6(to_python(a6, lookup_tag()));
|
||||
ref p7(to_python(a7, lookup_tag()));
|
||||
ref p8(to_python(a8, lookup_tag()));
|
||||
ref p9(to_python(a9, lookup_tag()));
|
||||
ref p10(to_python(a10, lookup_tag()));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
|
||||
@@ -30,7 +30,7 @@ struct caller
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &self))
|
||||
return 0;
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)());
|
||||
return to_python((target.*pmf)(), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1>
|
||||
@@ -40,7 +40,7 @@ struct caller
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &self, &a1))
|
||||
return 0;
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>())));
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
@@ -52,7 +52,7 @@ struct caller
|
||||
return 0;
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>())));
|
||||
from_python(a2, type<A2>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3>
|
||||
@@ -66,7 +66,7 @@ struct caller
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>())));
|
||||
from_python(a3, type<A3>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4>
|
||||
@@ -82,7 +82,7 @@ struct caller
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>())));
|
||||
from_python(a4, type<A4>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5>
|
||||
@@ -100,7 +100,7 @@ struct caller
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>())));
|
||||
from_python(a5, type<A5>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
@@ -120,7 +120,7 @@ struct caller
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>())));
|
||||
from_python(a6, type<A6>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
@@ -142,7 +142,7 @@ struct caller
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>())));
|
||||
from_python(a7, type<A7>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
@@ -166,7 +166,7 @@ struct caller
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>())));
|
||||
from_python(a8, type<A8>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
@@ -192,7 +192,7 @@ struct caller
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>()),
|
||||
from_python(a9, type<A9>())));
|
||||
from_python(a9, type<A9>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
@@ -220,7 +220,7 @@ struct caller
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>()),
|
||||
from_python(a9, type<A9>()),
|
||||
from_python(a10, type<A10>())));
|
||||
from_python(a10, type<A10>())), lookup_tag());
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ struct caller
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &self))
|
||||
return 0;
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)());
|
||||
return to_python((target.*pmf)(), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1>
|
||||
@@ -240,7 +240,7 @@ struct caller
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &self, &a1))
|
||||
return 0;
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>())));
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
@@ -252,7 +252,7 @@ struct caller
|
||||
return 0;
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>())));
|
||||
from_python(a2, type<A2>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3>
|
||||
@@ -266,7 +266,7 @@ struct caller
|
||||
T& target = from_python(self, type<T&>());
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>())));
|
||||
from_python(a3, type<A3>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4>
|
||||
@@ -282,7 +282,7 @@ struct caller
|
||||
return to_python((target.*pmf)(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>())));
|
||||
from_python(a4, type<A4>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5>
|
||||
@@ -300,7 +300,7 @@ struct caller
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>())));
|
||||
from_python(a5, type<A5>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
@@ -320,7 +320,7 @@ struct caller
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>())));
|
||||
from_python(a6, type<A6>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
@@ -342,7 +342,7 @@ struct caller
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>())));
|
||||
from_python(a7, type<A7>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
@@ -366,7 +366,7 @@ struct caller
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>())));
|
||||
from_python(a8, type<A8>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
@@ -392,7 +392,7 @@ struct caller
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>()),
|
||||
from_python(a9, type<A9>())));
|
||||
from_python(a9, type<A9>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
@@ -420,14 +420,14 @@ struct caller
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>()),
|
||||
from_python(a9, type<A9>()),
|
||||
from_python(a10, type<A10>())));
|
||||
from_python(a10, type<A10>())), lookup_tag());
|
||||
}
|
||||
|
||||
// Free functions
|
||||
static PyObject* call(R (*f)(), PyObject* args, PyObject* /* keywords */ ) {
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("")))
|
||||
return 0;
|
||||
return to_python(f());
|
||||
return to_python(f(), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
@@ -435,7 +435,7 @@ struct caller
|
||||
PyObject* a1;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &a1))
|
||||
return 0;
|
||||
return to_python(f(from_python(a1, type<A1>())));
|
||||
return to_python(f(from_python(a1, type<A1>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
@@ -445,7 +445,7 @@ struct caller
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
|
||||
return 0;
|
||||
return to_python(f(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>())));
|
||||
from_python(a2, type<A2>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
@@ -457,7 +457,7 @@ struct caller
|
||||
return 0;
|
||||
return to_python(f(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>())));
|
||||
from_python(a3, type<A3>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
@@ -471,7 +471,7 @@ struct caller
|
||||
return to_python(f(from_python(a1, type<A1>()),
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>())));
|
||||
from_python(a4, type<A4>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
@@ -487,7 +487,7 @@ struct caller
|
||||
from_python(a2, type<A2>()),
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>())));
|
||||
from_python(a5, type<A5>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
@@ -505,7 +505,7 @@ struct caller
|
||||
from_python(a3, type<A3>()),
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>())));
|
||||
from_python(a6, type<A6>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
@@ -525,7 +525,7 @@ struct caller
|
||||
from_python(a4, type<A4>()),
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>())));
|
||||
from_python(a7, type<A7>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
@@ -547,7 +547,7 @@ struct caller
|
||||
from_python(a5, type<A5>()),
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>())));
|
||||
from_python(a8, type<A8>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
@@ -571,7 +571,7 @@ struct caller
|
||||
from_python(a6, type<A6>()),
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>()),
|
||||
from_python(a9, type<A9>())));
|
||||
from_python(a9, type<A9>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
@@ -597,7 +597,7 @@ struct caller
|
||||
from_python(a7, type<A7>()),
|
||||
from_python(a8, type<A8>()),
|
||||
from_python(a9, type<A9>()),
|
||||
from_python(a10, type<A10>())));
|
||||
from_python(a10, type<A10>())), lookup_tag());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11>
|
||||
@@ -625,7 +625,7 @@ struct caller
|
||||
from_python(a8, type<A8>()),
|
||||
from_python(a9, type<A9>()),
|
||||
from_python(a10, type<A10>()),
|
||||
from_python(a11, type<A11>())));
|
||||
from_python(a11, type<A11>())), lookup_tag());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -19,117 +19,118 @@ class class_builder
|
||||
: python_extension_class_converters<T, U> // Works around MSVC6.x/GCC2.95.2 bug described below
|
||||
{
|
||||
public:
|
||||
/// Construct a class named name in the given module
|
||||
class_builder(module_builder& module, const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
~class_builder()
|
||||
{}
|
||||
|
||||
/// Tell Boost.Python that for the purposes of pickling, the state is
|
||||
/// completely captured in the object's __dict__.
|
||||
inline void dict_defines_state() {
|
||||
add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__dict_defines_state__");
|
||||
}
|
||||
inline void getstate_manages_dict() {
|
||||
add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__getstate_manages_dict__");
|
||||
add(ref(to_python(1, lookup_tag())), "__dict_defines_state__");
|
||||
}
|
||||
|
||||
// define constructors
|
||||
inline void getstate_manages_dict() {
|
||||
add(ref(to_python(1, lookup_tag())), "__getstate_manages_dict__");
|
||||
}
|
||||
|
||||
/// define constructors
|
||||
template <class signature>
|
||||
void def(const signature& s)
|
||||
{ m_class->def(s); }
|
||||
|
||||
// export heterogeneous reverse-argument operators
|
||||
// (type of lhs: 'left', of rhs: 'right')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
// boost::python::left_operand<int const &>());
|
||||
/// export heterogeneous reverse-argument operators
|
||||
/// (type of lhs: 'left', of rhs: 'right')
|
||||
/// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
/// boost::python::left_operand<int const &>());
|
||||
template <long which, class left, class right>
|
||||
void def(operators<which, right> o1, left_operand<left> o2)
|
||||
{ m_class->def(o1, o2); }
|
||||
|
||||
// export heterogeneous operators (type of lhs: 'left', of rhs: 'right')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
// boost::python::right_operand<int const &>());
|
||||
/// export heterogeneous operators (type of lhs: 'left', of rhs: 'right')
|
||||
/// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
/// boost::python::right_operand<int const &>());
|
||||
template <long which, class left, class right>
|
||||
void def(operators<which, left> o1, right_operand<right> o2)
|
||||
{ m_class->def(o1, o2); }
|
||||
|
||||
// define a function that passes Python arguments and keywords
|
||||
// to C++ verbatim (as a 'tuple const &' and 'dictionary const &'
|
||||
// respectively). This is useful for manual argument passing.
|
||||
// It's also the only possibility to pass keyword arguments to C++.
|
||||
// Fn must have a signatur that is compatible to
|
||||
// PyObject * (*)(PyObject * aTuple, PyObject * aDictionary)
|
||||
/// define a function that passes Python arguments and keywords
|
||||
/// to C++ verbatim (as a 'tuple const &' and 'dictionary const &'
|
||||
/// respectively). This is useful for manual argument passing.
|
||||
/// It's also the only way to pass keyword arguments to C++.
|
||||
/// Fn must have a signature that is compatible with
|
||||
/// PyObject * (*)(PyObject * aTuple, PyObject * aDictionary)
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{ m_class->def_raw(fn, name); }
|
||||
|
||||
// define member functions. In fact this works for free functions, too -
|
||||
// they act like static member functions, or if they start with the
|
||||
// appropriate self argument (as a pointer or reference), they can be used
|
||||
// just like ordinary member functions -- just like Python!
|
||||
/// define member functions. In fact this works for free functions, too -
|
||||
/// they act like static member functions, or if they start with the
|
||||
/// appropriate self argument (as a pointer or reference), they can be used
|
||||
/// just like ordinary member functions -- just like Python!
|
||||
template <class Fn>
|
||||
void def(Fn fn, const char* name)
|
||||
{ m_class->def(fn, name); }
|
||||
|
||||
// Define a virtual member function with a default implementation.
|
||||
// default_fn should be a function which provides the default implementation.
|
||||
// Be careful that default_fn does not in fact call fn virtually!
|
||||
/// Define a virtual member function with a default implementation.
|
||||
/// default_fn should be a function which provides the default implementation.
|
||||
/// Be careful that default_fn does not in fact call fn virtually!
|
||||
template <class Fn, class DefaultFn>
|
||||
void def(Fn fn, const char* name, DefaultFn default_fn)
|
||||
{ m_class->def(fn, name, default_fn); }
|
||||
|
||||
// Provide a function which implements x.<name>, reading from the given
|
||||
// member (pm) of the T obj
|
||||
/// Provide a function which implements x.<name>, reading from the given
|
||||
/// member (pm) of the T obj
|
||||
template <class MemberType>
|
||||
void def_getter(MemberType T::*pm, const char* name)
|
||||
{ m_class->def_getter(pm, name); }
|
||||
|
||||
// Provide a function which implements assignment to x.<name>, writing to
|
||||
// the given member (pm) of the T obj
|
||||
/// Provide a function which implements assignment to x.<name>, writing to
|
||||
/// the given member (pm) of the T obj
|
||||
template <class MemberType>
|
||||
void def_setter(MemberType T::*pm, const char* name)
|
||||
{ m_class->def_getter(pm, name); }
|
||||
|
||||
// Expose the given member (pm) of the T obj as a read-only attribute
|
||||
/// Expose the given member (pm) of the T obj as a read-only attribute
|
||||
template <class MemberType>
|
||||
void def_readonly(MemberType T::*pm, const char* name)
|
||||
{ m_class->def_readonly(pm, name); }
|
||||
|
||||
// Expose the given member (pm) of the T obj as a read/write attribute
|
||||
/// Expose the given member (pm) of the T obj as a read/write attribute
|
||||
template <class MemberType>
|
||||
void def_read_write(MemberType T::*pm, const char* name)
|
||||
{ m_class->def_read_write(pm, name); }
|
||||
|
||||
// define the standard coercion needed for operator overloading
|
||||
/// define the standard coercion needed for operator overloading
|
||||
void def_standard_coerce()
|
||||
{ m_class->def_standard_coerce(); }
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// conversion functions
|
||||
/// declare the given class a base class of this one and register
|
||||
/// conversion functions
|
||||
template <class S, class V>
|
||||
void declare_base(class_builder<S, V> const & base)
|
||||
{
|
||||
m_class->declare_base(base.get_extension_class());
|
||||
}
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// upcast conversion function
|
||||
/// declare the given class a base class of this one and register
|
||||
/// upcast conversion function
|
||||
template <class S, class V>
|
||||
void declare_base(class_builder<S, V> const & base, without_downcast_t)
|
||||
{
|
||||
m_class->declare_base(base.get_extension_class(), without_downcast);
|
||||
}
|
||||
|
||||
// get the embedded ExtensioClass object
|
||||
/// get the embedded ExtensioClass object
|
||||
detail::extension_class<T, U> * get_extension_class() const
|
||||
{
|
||||
return m_class.get();
|
||||
}
|
||||
|
||||
// set an arbitrary attribute. Useful for non-function class data members,
|
||||
// e.g. enums
|
||||
/// set an arbitrary attribute. Useful for non-function class data members,
|
||||
/// e.g. enums
|
||||
void add(PyObject* x, const char* name)
|
||||
{ m_class->set_attribute(name, x); }
|
||||
void add(ref x, const char* name)
|
||||
@@ -143,8 +144,8 @@ class class_builder
|
||||
m_class->declare_base(base);
|
||||
}
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// upcast conversion function
|
||||
/// declare the given class a base class of this one and register
|
||||
/// upcast conversion function
|
||||
template <class S, class V>
|
||||
void declare_base(detail::extension_class<S, V> * base, without_downcast_t)
|
||||
{
|
||||
|
||||
@@ -284,14 +284,14 @@ PyObject* class_t<T>::instance_mapping_subscript(PyObject* obj, PyObject* key) c
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_sequence_item(PyObject* obj, int n) const
|
||||
{
|
||||
ref key(to_python(n));
|
||||
ref key(to_python(n, lookup_tag()));
|
||||
return downcast<T>(obj)->get_subscript(key.get());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const
|
||||
{
|
||||
ref key(to_python(n));
|
||||
ref key(to_python(n, lookup_tag()));
|
||||
downcast<T>(obj)->set_subscript(key.get(), value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
struct lookup_tag {}; // Used to find to_python functions via Koenig lookup.
|
||||
}}
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
|
||||
// This can be instantiated on an enum to provide the to_python/from_python
|
||||
@@ -52,16 +56,16 @@ class py_enum_as_int_converters
|
||||
from_python(x, boost::python::type<long>()));
|
||||
}
|
||||
|
||||
friend PyObject* to_python(EnumType x)
|
||||
friend PyObject* to_python(EnumType x, boost::python::lookup_tag)
|
||||
{
|
||||
return to_python(static_cast<long>(x));
|
||||
return to_python(static_cast<long>(x), boost::python::lookup_tag());
|
||||
}
|
||||
};
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
template <class EnumType> class enum_as_int_converters
|
||||
: public BOOST_PYTHON_CONVERSION::py_enum_as_int_converters<EnumType> {};
|
||||
: public py_enum_as_int_converters<EnumType> {};
|
||||
|
||||
template <class P, class T> class wrapped_pointer;
|
||||
|
||||
@@ -116,70 +120,70 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
//
|
||||
// Converters
|
||||
//
|
||||
PyObject* to_python(long);
|
||||
PyObject* to_python(long, boost::python::lookup_tag);
|
||||
long from_python(PyObject* p, boost::python::type<long>);
|
||||
long from_python(PyObject* p, boost::python::type<const long&>);
|
||||
|
||||
PyObject* to_python(unsigned long);
|
||||
PyObject* to_python(unsigned long, boost::python::lookup_tag);
|
||||
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);
|
||||
PyObject* to_python(int, boost::python::lookup_tag);
|
||||
int from_python(PyObject*, boost::python::type<int>);
|
||||
int from_python(PyObject*, boost::python::type<const int&>);
|
||||
|
||||
PyObject* to_python(unsigned int);
|
||||
PyObject* to_python(unsigned int, boost::python::lookup_tag);
|
||||
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);
|
||||
PyObject* to_python(short, boost::python::lookup_tag);
|
||||
short from_python(PyObject*, boost::python::type<short>);
|
||||
short from_python(PyObject*, boost::python::type<const short&>);
|
||||
|
||||
PyObject* to_python(unsigned short);
|
||||
PyObject* to_python(unsigned short, boost::python::lookup_tag);
|
||||
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);
|
||||
PyObject* to_python(char, boost::python::lookup_tag);
|
||||
char from_python(PyObject*, boost::python::type<char>);
|
||||
char from_python(PyObject*, boost::python::type<const char&>);
|
||||
|
||||
PyObject* to_python(signed char);
|
||||
PyObject* to_python(signed char, boost::python::lookup_tag);
|
||||
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);
|
||||
PyObject* to_python(unsigned char, boost::python::lookup_tag);
|
||||
unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
|
||||
unsigned char from_python(PyObject*, boost::python::type<const unsigned char&>);
|
||||
|
||||
PyObject* to_python(float);
|
||||
PyObject* to_python(float, boost::python::lookup_tag);
|
||||
float from_python(PyObject*, boost::python::type<float>);
|
||||
float from_python(PyObject*, boost::python::type<const float&>);
|
||||
|
||||
PyObject* to_python(double);
|
||||
PyObject* to_python(double, boost::python::lookup_tag);
|
||||
double from_python(PyObject*, boost::python::type<double>);
|
||||
double from_python(PyObject*, boost::python::type<const double&>);
|
||||
|
||||
PyObject* to_python(bool);
|
||||
PyObject* to_python(bool, boost::python::lookup_tag);
|
||||
bool from_python(PyObject*, boost::python::type<bool>);
|
||||
bool from_python(PyObject*, boost::python::type<const bool&>);
|
||||
|
||||
PyObject* to_python(void);
|
||||
PyObject* to_python(boost::python::lookup_tag);
|
||||
void from_python(PyObject*, boost::python::type<void>);
|
||||
|
||||
PyObject* to_python(const char* s);
|
||||
PyObject* to_python(const char* s, boost::python::lookup_tag);
|
||||
const char* from_python(PyObject*, boost::python::type<const char*>);
|
||||
|
||||
PyObject* to_python(const std::string& s);
|
||||
PyObject* to_python(const std::string& s, boost::python::lookup_tag);
|
||||
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)
|
||||
inline PyObject* to_python(const std::complex<float>& x, boost::python::lookup_tag)
|
||||
{
|
||||
return boost::python::detail::complex_to_python<float>(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(const std::complex<double>& x)
|
||||
inline PyObject* to_python(const std::complex<double>& x, boost::python::lookup_tag)
|
||||
{
|
||||
return boost::python::detail::complex_to_python<double>(x);
|
||||
}
|
||||
@@ -205,7 +209,7 @@ inline std::complex<float> from_python(PyObject* p,
|
||||
}
|
||||
|
||||
// For when your C++ function really wants to pass/return a PyObject*
|
||||
PyObject* to_python(PyObject*);
|
||||
PyObject* to_python(PyObject*, boost::python::lookup_tag);
|
||||
PyObject* from_python(PyObject*, boost::python::type<PyObject*>);
|
||||
|
||||
// Some standard conversions to/from smart pointer types. You can add your own
|
||||
@@ -259,13 +263,13 @@ boost::shared_ptr<T> from_python(PyObject*p, boost::python::type<boost::shared_p
|
||||
|
||||
#if 0
|
||||
template <class T>
|
||||
PyObject* to_python(std::auto_ptr<T> p)
|
||||
PyObject* to_python(std::auto_ptr<T> p, boost::python::lookup_tag)
|
||||
{
|
||||
return new boost::python::wrapped_pointer<std::auto_ptr<T>, T>(p);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* to_python(boost::shared_ptr<T> p)
|
||||
PyObject* to_python(boost::shared_ptr<T> p, boost::python::lookup_tag)
|
||||
{
|
||||
return new boost::python::wrapped_pointer<boost::shared_ptr<T>, T>(p);
|
||||
}
|
||||
@@ -276,43 +280,43 @@ PyObject* to_python(boost::shared_ptr<T> p)
|
||||
//
|
||||
|
||||
#ifndef BOOST_MSVC6_OR_EARLIER
|
||||
inline PyObject* to_python(double d)
|
||||
inline PyObject* to_python(double d, boost::python::lookup_tag)
|
||||
{
|
||||
return PyFloat_FromDouble(d);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(float f)
|
||||
inline PyObject* to_python(float f, boost::python::lookup_tag)
|
||||
{
|
||||
return PyFloat_FromDouble(f);
|
||||
}
|
||||
#endif // BOOST_MSVC6_OR_EARLIER
|
||||
|
||||
inline PyObject* to_python(long l)
|
||||
inline PyObject* to_python(long l, boost::python::lookup_tag)
|
||||
{
|
||||
return PyInt_FromLong(l);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(int x)
|
||||
inline PyObject* to_python(int x, boost::python::lookup_tag)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(short x)
|
||||
inline PyObject* to_python(short x, boost::python::lookup_tag)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(bool b)
|
||||
inline PyObject* to_python(bool b, boost::python::lookup_tag)
|
||||
{
|
||||
return PyInt_FromLong(b);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(void)
|
||||
inline PyObject* to_python(boost::python::lookup_tag)
|
||||
{
|
||||
return boost::python::detail::none();
|
||||
}
|
||||
|
||||
inline PyObject* to_python(const char* s)
|
||||
inline PyObject* to_python(const char* s, boost::python::lookup_tag)
|
||||
{
|
||||
return PyString_FromString(s);
|
||||
}
|
||||
@@ -322,7 +326,7 @@ inline std::string from_python(PyObject* p, boost::python::type<const std::strin
|
||||
return from_python(p, boost::python::type<std::string>());
|
||||
}
|
||||
|
||||
inline PyObject* to_python(PyObject* p)
|
||||
inline PyObject* to_python(PyObject* p, boost::python::lookup_tag)
|
||||
{
|
||||
Py_INCREF(p);
|
||||
return p;
|
||||
|
||||
320
include/boost/python/cross_module.hpp
Normal file
320
include/boost/python/cross_module.hpp
Normal file
@@ -0,0 +1,320 @@
|
||||
/* (C) Copyright Ralf W. Grosse-Kunstleve 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.
|
||||
|
||||
Revision History:
|
||||
17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve)
|
||||
*/
|
||||
|
||||
/* Implementation of Boost.Python cross-module support.
|
||||
See root/libs/python/doc/cross_module.html for details.
|
||||
*/
|
||||
|
||||
#ifndef CROSS_MODULE_HPP
|
||||
# define CROSS_MODULE_HPP
|
||||
|
||||
# include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
struct import_error : error_already_set {};
|
||||
struct export_error : error_already_set {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace python { 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);
|
||||
|
||||
}}}
|
||||
|
||||
// forward declaration
|
||||
namespace boost { namespace python { namespace detail {
|
||||
template <class T> class import_extension_class;
|
||||
}}}
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
/* This class template is instantiated by import_converters<T>.
|
||||
This class is a look-alike of class python_extension_class_converters.
|
||||
The converters in this class are wrappers that call converters
|
||||
imported from another module.
|
||||
To ensure that the dynamic loader resolves all symbols in the
|
||||
intended way, the signature of all friend functions is changed with
|
||||
respect to the original functions in class
|
||||
python_extension_class_converters by adding an arbitrary additional
|
||||
parameter with a default value, in this case "bool sig = false".
|
||||
See also: comments for class export_converter_object_base below.
|
||||
*/
|
||||
template <class T>
|
||||
class python_import_extension_class_converters
|
||||
{
|
||||
public:
|
||||
|
||||
friend python_import_extension_class_converters py_extension_class_converters(boost::python::type<T>, bool sig = false) {
|
||||
return python_import_extension_class_converters();
|
||||
}
|
||||
|
||||
PyObject* m_to_python(const T& x) const {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->dispatcher_to_python(x);
|
||||
}
|
||||
|
||||
friend T* from_python(PyObject* p, boost::python::type<T*> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_Ts(p, t);
|
||||
}
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_cTs(p, t);
|
||||
}
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*const&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_cTscr(p, t);
|
||||
}
|
||||
friend T* from_python(PyObject* p, boost::python::type<T* const&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_Tscr(p, t);
|
||||
}
|
||||
friend T& from_python(PyObject* p, boost::python::type<T&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_Tr(p, t);
|
||||
}
|
||||
friend const T& from_python(PyObject* p, boost::python::type<const T&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_cTr(p, t);
|
||||
}
|
||||
friend const T& from_python(PyObject* p, boost::python::type<T> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_T(p, t);
|
||||
}
|
||||
|
||||
friend std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T>&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_aTr(p, t);
|
||||
}
|
||||
friend std::auto_ptr<T> from_python(PyObject* p, boost::python::type<std::auto_ptr<T> > t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_aT(p, t);
|
||||
}
|
||||
friend const std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<const std::auto_ptr<T>&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_caTr(p, t);
|
||||
}
|
||||
friend PyObject* to_python(std::auto_ptr<T> x, boost::python::lookup_tag, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->dispatcher_to_python(x);
|
||||
}
|
||||
|
||||
friend boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T>&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_sTr(p, t);
|
||||
}
|
||||
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T> > t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_sT(p, t);
|
||||
}
|
||||
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<const boost::shared_ptr<T>&> t, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_csTr(p, t);
|
||||
}
|
||||
friend PyObject* to_python(boost::shared_ptr<T> x, boost::python::lookup_tag, bool sig = false) {
|
||||
return boost::python::detail::import_extension_class<T>::get_converters()->dispatcher_to_python(x);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
/* This class template is instantiated by export_converters().
|
||||
A pointer to this class is exported/imported via the Python API.
|
||||
Using the Python API ensures maximum portability.
|
||||
All member functions are virtual. This is, what we export/import
|
||||
is essentially just a pointer to a vtbl.
|
||||
To work around a deficiency of Visual C++ 6.0, the name of each
|
||||
from_python() member functions is made unique by appending a few
|
||||
characters (derived in a ad-hoc manner from the corresponding type).
|
||||
*/
|
||||
template <class T>
|
||||
struct export_converter_object_base
|
||||
{
|
||||
virtual int get_api_major() const { return detail::export_converters_api_major; }
|
||||
virtual int get_api_minor() const { return detail::export_converters_api_minor; }
|
||||
|
||||
virtual PyObject* dispatcher_to_python(const T& x) = 0;
|
||||
|
||||
virtual T* from_python_Ts(PyObject* p, type<T*> t) = 0;
|
||||
virtual const T* from_python_cTs(PyObject* p, type<const T*> t) = 0;
|
||||
virtual const T* from_python_cTscr(PyObject* p, type<const T*const&> t) = 0;
|
||||
virtual T* from_python_Tscr(PyObject* p, type<T* const&> t) = 0;
|
||||
virtual T& from_python_Tr(PyObject* p, type<T&> t) = 0;
|
||||
virtual const T& from_python_cTr(PyObject* p, type<const T&> t) = 0;
|
||||
virtual const T& from_python_T(PyObject* p, type<T> t) = 0;
|
||||
|
||||
virtual std::auto_ptr<T>& from_python_aTr(PyObject* p, type<std::auto_ptr<T>&> t) = 0;
|
||||
virtual std::auto_ptr<T> from_python_aT(PyObject* p, type<std::auto_ptr<T> > t) = 0;
|
||||
virtual const std::auto_ptr<T>& from_python_caTr(PyObject* p, type<const std::auto_ptr<T>&> t) = 0;
|
||||
virtual PyObject* dispatcher_to_python(std::auto_ptr<T> x) = 0;
|
||||
|
||||
virtual boost::shared_ptr<T>& from_python_sTr(PyObject* p, type<boost::shared_ptr<T>&> t) = 0;
|
||||
virtual const boost::shared_ptr<T>& from_python_sT(PyObject* p, type<boost::shared_ptr<T> > t) = 0;
|
||||
virtual const boost::shared_ptr<T>& from_python_csTr(PyObject* p, type<const boost::shared_ptr<T>&> t) = 0;
|
||||
virtual PyObject* dispatcher_to_python(boost::shared_ptr<T> x) = 0;
|
||||
};
|
||||
|
||||
// Converters to be used if T is not copyable.
|
||||
template <class T>
|
||||
struct export_converter_object_noncopyable : export_converter_object_base<T>
|
||||
{
|
||||
virtual PyObject* dispatcher_to_python(const T& x) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"to_python(const T&, boost::python::lookup_tag) converter not exported");
|
||||
throw import_error();
|
||||
}
|
||||
|
||||
virtual T* from_python_Ts(PyObject* p, type<T*> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual const T* from_python_cTs(PyObject* p, type<const T*> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual const T* from_python_cTscr(PyObject* p, type<const T*const&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual T* from_python_Tscr(PyObject* p, type<T* const&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual T& from_python_Tr(PyObject* p, type<T&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual const T& from_python_cTr(PyObject* p, type<const T&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual const T& from_python_T(PyObject* p, type<T> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
|
||||
virtual std::auto_ptr<T>& from_python_aTr(PyObject* p, type<std::auto_ptr<T>&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual std::auto_ptr<T> from_python_aT(PyObject* p, type<std::auto_ptr<T> > t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual const std::auto_ptr<T>& from_python_caTr(PyObject* p, type<const std::auto_ptr<T>&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual PyObject* dispatcher_to_python(std::auto_ptr<T> x) {
|
||||
return to_python(x, lookup_tag());
|
||||
}
|
||||
|
||||
virtual boost::shared_ptr<T>& from_python_sTr(PyObject* p, type<boost::shared_ptr<T>&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual const boost::shared_ptr<T>& from_python_sT(PyObject* p, type<boost::shared_ptr<T> > t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual const boost::shared_ptr<T>& from_python_csTr(PyObject* p, type<const boost::shared_ptr<T>&> t) {
|
||||
return from_python(p, t);
|
||||
}
|
||||
virtual PyObject* dispatcher_to_python(boost::shared_ptr<T> x) {
|
||||
return to_python(x, lookup_tag());
|
||||
}
|
||||
};
|
||||
|
||||
// The addditional to_python() converter that can be used if T is copyable.
|
||||
template <class T>
|
||||
struct export_converter_object : export_converter_object_noncopyable<T>
|
||||
{
|
||||
virtual PyObject* dispatcher_to_python(const T& x) {
|
||||
return py_extension_class_converters(type<T>()).m_to_python(x);
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static export_converter_object_base<T>* get_converters();
|
||||
|
||||
private:
|
||||
static std::string m_module;
|
||||
static std::string m_py_class;
|
||||
static 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>
|
||||
export_converter_object_base<T>*
|
||||
import_extension_class<T>::imported_converters = 0;
|
||||
|
||||
template <class T>
|
||||
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<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;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Implementation of export_converters().
|
||||
template <class T, class U>
|
||||
void export_converters(class_builder<T, U>& cb)
|
||||
{
|
||||
static export_converter_object<T> export_cvts;
|
||||
cb.add(
|
||||
ref(PyCObject_FromVoidPtr(reinterpret_cast<void*>(&export_cvts), NULL)),
|
||||
detail::converters_attribute_name);
|
||||
}
|
||||
|
||||
// Implementation of export_converters_noncopyable().
|
||||
template <class T, class U>
|
||||
void export_converters_noncopyable(class_builder<T, U>& cb)
|
||||
{
|
||||
static export_converter_object_noncopyable<T> export_cvts;
|
||||
cb.add(
|
||||
ref(PyCObject_FromVoidPtr(reinterpret_cast<void*>(&export_cvts), NULL)),
|
||||
detail::converters_attribute_name);
|
||||
}
|
||||
|
||||
// Implementation of import_converters<T>.
|
||||
template <class T>
|
||||
class import_converters
|
||||
: python_import_extension_class_converters<T> // Works around MSVC6.x/GCC2.95.2 bug described
|
||||
// at the bottom of class_builder.hpp.
|
||||
{
|
||||
public:
|
||||
import_converters(const char* module, const char* py_class)
|
||||
: m_class(new detail::import_extension_class<T>(module, py_class))
|
||||
{ }
|
||||
private:
|
||||
boost::shared_ptr<detail::import_extension_class<T> > m_class;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CROSS_MODULE_HPP
|
||||
@@ -7,6 +7,7 @@
|
||||
// producing this work.
|
||||
|
||||
// Revision History:
|
||||
// 24 May 01 friend lookup fixes (Ralf W. Grosse-Kunstleve)
|
||||
// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams)
|
||||
|
||||
#ifndef CONFIG_DWA052200_H_
|
||||
@@ -15,19 +16,6 @@
|
||||
# include <boost/config.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
// A gcc bug forces some symbols into the global namespace
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
# define BOOST_PYTHON_CONVERSION
|
||||
# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x
|
||||
# else
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python {
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python
|
||||
# define BOOST_PYTHON_CONVERSION boost::python
|
||||
# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';'
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_MSVC)
|
||||
# if _MSC_VER <= 1200
|
||||
# define BOOST_MSVC6_OR_EARLIER 1
|
||||
@@ -37,6 +25,29 @@
|
||||
|
||||
# endif
|
||||
|
||||
# if defined(__GNUC__) && __GNUC__ < 3
|
||||
# define BOOST_NO_FRIEND_KOENIG_LOOKUP
|
||||
# endif
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
|
||||
# define BOOST_NO_FRIEND_KOENIG_LOOKUP
|
||||
# endif
|
||||
# if defined(__DECCXX_VER) && __DECCXX_VER <= 60290024
|
||||
# define BOOST_NO_FRIEND_KOENIG_LOOKUP
|
||||
# endif
|
||||
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
|
||||
# define BOOST_NO_FRIEND_KOENIG_LOOKUP
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_NO_FRIEND_KOENIG_LOOKUP)
|
||||
// for compilers that do not support Koenig lookup for friend functions
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
# else
|
||||
// for compilers that support Koenig lookup
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python {
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python
|
||||
# endif
|
||||
|
||||
// Work around the broken library implementation/strict ansi checking on some
|
||||
// EDG-based compilers (e.g. alpha), which incorrectly warn that the result of
|
||||
// offsetof() is not an integer constant expression.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// (C) Copyright David Abrahams 2000-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.
|
||||
@@ -10,6 +10,7 @@
|
||||
// gen_extclass.python
|
||||
|
||||
// Revision History:
|
||||
// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve)
|
||||
// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted
|
||||
// to_python (Dave Abrahams)
|
||||
|
||||
@@ -166,36 +167,45 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
// and U. T is the class the user really intends to wrap. U is a class derived
|
||||
// from T with some virtual function overriding boilerplate, or if there are no
|
||||
// virtual functions, U = held_instance<T>.
|
||||
//
|
||||
// A look-alike of this class in root/boost/python/cross_module.hpp
|
||||
// is used for the implementation of the cross-module support
|
||||
// (export_converters and import_converters). If from_python
|
||||
// and to_python converters are added or removed from the class
|
||||
// below, the class python_import_extension_class_converters has
|
||||
// to be modified accordingly.
|
||||
//
|
||||
template <class T, class U = boost::python::detail::held_instance<T> >
|
||||
class python_extension_class_converters
|
||||
{
|
||||
public:
|
||||
// Get an object which can be used to convert T to/from python. This is used
|
||||
// as a kind of concept check by the global template
|
||||
//
|
||||
// PyObject* to_python(const T& x)
|
||||
//
|
||||
// below this class, to prevent the confusing messages that would otherwise
|
||||
// pop up. Now, if T hasn't been wrapped as an extension class, the user
|
||||
// will see an error message about the lack of an eligible
|
||||
// py_extension_class_converters() function.
|
||||
friend python_extension_class_converters py_extension_class_converters(boost::python::type<T>)
|
||||
/// Get an object which can be used to convert T to/from python. This is used
|
||||
/// as a kind of concept check by the free template function
|
||||
///
|
||||
/// PyObject* to_python(const T& x, boost::python::lookup_tag)
|
||||
///
|
||||
/// below this class, to prevent the confusing messages that would otherwise
|
||||
/// pop up. Now, if T hasn't been wrapped as an extension class, the user
|
||||
/// will see an error message about the lack of an eligible
|
||||
/// py_extension_class_converters() function.
|
||||
friend python_extension_class_converters py_extension_class_converters(
|
||||
boost::python::type<T>)
|
||||
{
|
||||
return python_extension_class_converters();
|
||||
}
|
||||
|
||||
// This is a member function because in a conforming implementation, friend
|
||||
// funcitons defined inline in the class body are all instantiated as soon
|
||||
// as the enclosing class is instantiated. If T is not copyable, that causes
|
||||
// a compiler error. Instead, we access this function through the global
|
||||
// template
|
||||
//
|
||||
// PyObject* to_python(const T& x)
|
||||
//
|
||||
// defined below this class. Since template functions are instantiated only
|
||||
// on demand, errors will be avoided unless T is noncopyable and the user
|
||||
// writes code which causes us to try to copy a T.
|
||||
PyObject* to_python(const T& x) const
|
||||
/// This is a member function because in a conforming implementation, friend
|
||||
/// functions defined inline in the class body are all instantiated as soon
|
||||
/// as the enclosing class is instantiated. If T is not copyable, that causes
|
||||
/// a compiler error. Instead, we access this function through the global
|
||||
/// template
|
||||
///
|
||||
/// PyObject* to_python(const T& x, boost::python::lookup_tag)
|
||||
///
|
||||
/// defined below this class. Since template functions are instantiated only
|
||||
/// on demand, errors will be avoided unless T is noncopyable and the user
|
||||
/// writes code which causes us to try to copy a T.
|
||||
PyObject* m_to_python(const T& x) const
|
||||
{
|
||||
boost::python::reference<boost::python::detail::extension_instance> result(create_instance());
|
||||
result->add_implementation(
|
||||
@@ -204,6 +214,7 @@ class python_extension_class_converters
|
||||
return result.release();
|
||||
}
|
||||
|
||||
/// Extract a pointer to T from the given PyObject. Will throw argument_error if obj == None.
|
||||
friend
|
||||
T* non_null_from_python(PyObject* obj, boost::python::type<T*>)
|
||||
{
|
||||
@@ -226,16 +237,14 @@ class python_extension_class_converters
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
|
||||
// Convert to T*
|
||||
/// Convert obj to T*. If obj == None, returns 0.
|
||||
friend T* from_python(PyObject* obj, boost::python::type<T*>)
|
||||
{
|
||||
if (obj == Py_None)
|
||||
return 0;
|
||||
else
|
||||
return non_null_from_python(obj, boost::python::type<T*>());
|
||||
if (obj == Py_None) return 0;
|
||||
return non_null_from_python(obj, boost::python::type<T*>());
|
||||
}
|
||||
|
||||
// Extract from obj a mutable reference to the PtrType object which is holding a T.
|
||||
/// Extract from obj a mutable reference to the PtrType object which is holding a T.
|
||||
template <class PtrType>
|
||||
static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type<PtrType>)
|
||||
{
|
||||
@@ -254,10 +263,10 @@ class python_extension_class_converters
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
|
||||
// Extract from obj a reference to the PtrType object which is holding a
|
||||
// T. If it weren't for auto_ptr, it would be a constant reference. Do not
|
||||
// modify the referent except by copying an auto_ptr! If obj is None, the
|
||||
// reference denotes a default-constructed PtrType
|
||||
/// Extract from obj a reference to the PtrType object which is holding a
|
||||
/// T. If it weren't for auto_ptr, it would be a constant reference. Do not
|
||||
/// modify the referent except by copying an auto_ptr! If obj is None, the
|
||||
/// reference denotes a default-constructed PtrType
|
||||
template <class PtrType>
|
||||
static PtrType& smart_ptr_value(PyObject* obj, boost::python::type<PtrType>)
|
||||
{
|
||||
@@ -268,7 +277,9 @@ class python_extension_class_converters
|
||||
}
|
||||
return smart_ptr_reference(obj, boost::python::type<PtrType>());
|
||||
}
|
||||
|
||||
|
||||
/// Wrap x in a Python object which implements the functionality of a
|
||||
/// regular wrapped T by dereferencing a copy of x.
|
||||
template <class PtrType>
|
||||
static PyObject* smart_ptr_to_python(PtrType x)
|
||||
{
|
||||
@@ -284,6 +295,9 @@ class python_extension_class_converters
|
||||
return result.release();
|
||||
}
|
||||
|
||||
/// Create a Python object which is an instance of the Python type wrapper
|
||||
/// for T. The result does not actually contain the neccessary instance of
|
||||
/// T. This function is an implementation detail.
|
||||
static boost::python::reference<boost::python::detail::extension_instance> create_instance()
|
||||
{
|
||||
PyTypeObject* class_object = boost::python::detail::class_registry<T>::class_object();
|
||||
@@ -294,15 +308,15 @@ class python_extension_class_converters
|
||||
new boost::python::detail::extension_instance(class_object));
|
||||
}
|
||||
|
||||
// Convert to const T*
|
||||
/// Convert p to const T*
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*>)
|
||||
{ return from_python(p, boost::python::type<T*>()); }
|
||||
|
||||
// Convert to const T* const&
|
||||
/// Convert p to const T* const&
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*const&>)
|
||||
{ return from_python(p, boost::python::type<const T*>()); }
|
||||
|
||||
// Convert to T* const&
|
||||
/// Convert p to T* const&
|
||||
friend T* from_python(PyObject* p, boost::python::type<T* const&>)
|
||||
{ return from_python(p, boost::python::type<T*>()); }
|
||||
|
||||
@@ -310,11 +324,11 @@ class python_extension_class_converters
|
||||
friend T& from_python(PyObject* p, boost::python::type<T&>)
|
||||
{ return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type<T*>())); }
|
||||
|
||||
// Convert to const T&
|
||||
// Convert p to const T&
|
||||
friend const T& from_python(PyObject* p, boost::python::type<const T&>)
|
||||
{ return from_python(p, boost::python::type<T&>()); }
|
||||
|
||||
// Convert to T
|
||||
/// Convert p to T
|
||||
friend const T& from_python(PyObject* p, boost::python::type<T>)
|
||||
{ return from_python(p, boost::python::type<T&>()); }
|
||||
|
||||
@@ -327,7 +341,7 @@ class python_extension_class_converters
|
||||
friend const std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<const std::auto_ptr<T>&>)
|
||||
{ return smart_ptr_value(p, boost::python::type<std::auto_ptr<T> >()); }
|
||||
|
||||
friend PyObject* to_python(std::auto_ptr<T> x)
|
||||
friend PyObject* to_python(std::auto_ptr<T> x, boost::python::lookup_tag)
|
||||
{ return smart_ptr_to_python(x); }
|
||||
|
||||
friend boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T>&>)
|
||||
@@ -339,7 +353,7 @@ class python_extension_class_converters
|
||||
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<const boost::shared_ptr<T>&>)
|
||||
{ return smart_ptr_value(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
|
||||
friend PyObject* to_python(boost::shared_ptr<T> x)
|
||||
friend PyObject* to_python(boost::shared_ptr<T> x, boost::python::lookup_tag)
|
||||
{ return smart_ptr_to_python(x); }
|
||||
};
|
||||
|
||||
@@ -348,17 +362,15 @@ class python_extension_class_converters
|
||||
// T is a wrapped class. See the first 2 functions declared in
|
||||
// python_extension_class_converters above for more info.
|
||||
template <class T>
|
||||
PyObject* to_python(const T& x)
|
||||
PyObject* to_python(const T& x, boost::python::lookup_tag)
|
||||
{
|
||||
return py_extension_class_converters(boost::python::type<T>()).to_python(x);
|
||||
return py_extension_class_converters(boost::python::type<T>()).m_to_python(x);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters);
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T> class instance_holder;
|
||||
|
||||
@@ -95,8 +95,9 @@ struct raw_arguments_function : function
|
||||
ref(PyDict_New()));
|
||||
|
||||
return to_python(
|
||||
(*m_pf)(from_python(args, boost::python::type<Args>()),
|
||||
from_python(dict.get(), boost::python::type<Keywords>())));
|
||||
(*m_pf)(from_python(args, type<Args>()),
|
||||
from_python(dict.get(), type<Keywords>())),
|
||||
lookup_tag());
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
@@ -263,8 +264,8 @@ PyObject* getter_function<ClassType, MemberType>::do_call(
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &self))
|
||||
return 0;
|
||||
|
||||
return to_python(
|
||||
from_python(self, type<const ClassType*>())->*m_pm);
|
||||
return to_python(from_python(self, type<const ClassType*>())->*m_pm,
|
||||
lookup_tag());
|
||||
}
|
||||
|
||||
template <class ClassType, class MemberType>
|
||||
|
||||
@@ -297,7 +297,7 @@ struct list::slice_proxy
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
PyObject* to_python(const boost::python::tuple&);
|
||||
PyObject* to_python(const boost::python::tuple&, boost::python::lookup_tag);
|
||||
boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple>);
|
||||
|
||||
inline boost::python::tuple from_python(PyObject* p, boost::python::type<const boost::python::tuple&>)
|
||||
@@ -305,7 +305,7 @@ inline boost::python::tuple from_python(PyObject* p, boost::python::type<const b
|
||||
return from_python(p, boost::python::type<boost::python::tuple>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::list&);
|
||||
PyObject* to_python(const boost::python::list&, boost::python::lookup_tag);
|
||||
boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list>);
|
||||
|
||||
inline boost::python::list from_python(PyObject* p, boost::python::type<const boost::python::list&>)
|
||||
@@ -313,7 +313,7 @@ inline boost::python::list from_python(PyObject* p, boost::python::type<const bo
|
||||
return from_python(p, boost::python::type<boost::python::list>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::string&);
|
||||
PyObject* to_python(const boost::python::string&, boost::python::lookup_tag);
|
||||
boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string>);
|
||||
|
||||
inline boost::python::string from_python(PyObject* p, boost::python::type<const boost::python::string&>)
|
||||
@@ -321,7 +321,7 @@ inline boost::python::string from_python(PyObject* p, boost::python::type<const
|
||||
return from_python(p, boost::python::type<boost::python::string>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::dictionary&);
|
||||
PyObject* to_python(const boost::python::dictionary&, boost::python::lookup_tag);
|
||||
boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary>);
|
||||
|
||||
inline boost::python::dictionary from_python(PyObject* p, boost::python::type<const boost::python::dictionary&>)
|
||||
|
||||
@@ -237,11 +237,11 @@ namespace detail
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) oper \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())); \
|
||||
return to_python( \
|
||||
from_python(args[0].get(), type<Left>()) oper \
|
||||
from_python(args[1].get(), type<Right>()), lookup_tag()); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
@@ -253,11 +253,11 @@ namespace detail
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) oper \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())); \
|
||||
return to_python( \
|
||||
from_python(args[1].get(), type<Left>()) oper \
|
||||
from_python(args[0].get(), type<Right>()), lookup_tag()); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
@@ -278,10 +278,10 @@ namespace detail
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()))); \
|
||||
return to_python( \
|
||||
oper(from_python(args[0].get(), type<operand>())), lookup_tag()); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
@@ -335,9 +335,9 @@ namespace detail
|
||||
throw argument_error();
|
||||
}
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
pow(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()),
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
return to_python(
|
||||
pow(from_python(args[0].get(), type<Left>()),
|
||||
from_python(args[1].get(), type<Right>())), lookup_tag());
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
@@ -358,9 +358,9 @@ namespace detail
|
||||
throw argument_error();
|
||||
}
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
pow(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()),
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
return to_python(
|
||||
pow(from_python(args[1].get(), type<Left>()),
|
||||
from_python(args[0].get(), type<Right>())), lookup_tag());
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
@@ -386,13 +386,11 @@ namespace detail
|
||||
PyObject * res = PyTuple_New(2);
|
||||
|
||||
PyTuple_SET_ITEM(res, 0,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) /
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
to_python(from_python(args[0].get(), type<Left>()) /
|
||||
from_python(args[1].get(), type<Right>()), lookup_tag()));
|
||||
PyTuple_SET_ITEM(res, 1,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) %
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
to_python(from_python(args[0].get(), type<Left>()) %
|
||||
from_python(args[1].get(), type<Right>()), lookup_tag()));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -411,13 +409,11 @@ namespace detail
|
||||
PyObject * res = PyTuple_New(2);
|
||||
|
||||
PyTuple_SET_ITEM(res, 0,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) /
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
to_python(from_python(args[1].get(), type<Left>()) /
|
||||
from_python(args[0].get(), type<Right>()), lookup_tag()));
|
||||
PyTuple_SET_ITEM(res, 1,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) %
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
to_python(from_python(args[1].get(), type<Left>()) %
|
||||
from_python(args[0].get(), type<Right>()), lookup_tag()));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -443,14 +439,14 @@ namespace detail
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())) ?
|
||||
return to_python(
|
||||
(from_python(args[0].get(), type<Left>()) <
|
||||
from_python(args[1].get(), type<Right>())) ?
|
||||
- 1 :
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>())) ?
|
||||
(from_python(args[1].get(), type<Right>()) <
|
||||
from_python(args[0].get(), type<Left>())) ?
|
||||
1 :
|
||||
0) ;
|
||||
0, lookup_tag()) ;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
@@ -465,14 +461,14 @@ namespace detail
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())) ?
|
||||
return to_python(
|
||||
(from_python(args[1].get(), type<Left>()) <
|
||||
from_python(args[0].get(), type<Right>())) ?
|
||||
- 1 :
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>())) ?
|
||||
(from_python(args[0].get(), type<Right>()) <
|
||||
from_python(args[1].get(), type<Left>())) ?
|
||||
1 :
|
||||
0) ;
|
||||
0, lookup_tag()) ;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
@@ -510,13 +506,13 @@ namespace detail
|
||||
// _STL::string, but std::string.
|
||||
# ifdef BOOST_PYTHON_USE_SSTREAM
|
||||
std::ostringstream s;
|
||||
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>());
|
||||
return BOOST_PYTHON_CONVERSION::to_python(s.str());
|
||||
s << from_python(args[0].get(), type<operand>());
|
||||
return to_python(s.str(), lookup_tag());
|
||||
# else
|
||||
std::ostrstream s;
|
||||
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()) << char();
|
||||
s << from_python(args[0].get(), type<operand>()) << char();
|
||||
auto unfreezer unfreeze(s);
|
||||
return BOOST_PYTHON_CONVERSION::to_python(const_cast<char const *>(s.str()));
|
||||
return to_python(const_cast<char const *>(s.str()), lookup_tag());
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ struct py_ptr_conversions : Base
|
||||
inline friend T from_python(PyObject* x, boost::python::type<T>)
|
||||
{ return T(boost::python::downcast<Value>(x).get(), T::increment_count); }
|
||||
|
||||
inline friend PyObject* to_python(T x)
|
||||
inline friend PyObject* to_python(T x, boost::python::lookup_tag)
|
||||
{ return boost::python::as_object(x.release()); }
|
||||
|
||||
};
|
||||
@@ -38,8 +38,6 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions);
|
||||
|
||||
template <class T>
|
||||
class reference
|
||||
: public py_ptr_conversions<reference<T>, T,
|
||||
@@ -165,7 +163,7 @@ typedef reference<PyObject> ref;
|
||||
template <class T>
|
||||
ref make_ref(const T& x)
|
||||
{
|
||||
return ref(to_python(x));
|
||||
return ref(to_python(x, lookup_tag()));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// producing this work.
|
||||
//
|
||||
// Revision History:
|
||||
// 05 Apr 01 added: from_python std::string type checking (rwgk)
|
||||
// 12 Mar 01 Python 1.5.2 fixes (Ralf W. Grosse-Kunstleve)
|
||||
// 11 Mar 01 std::string *MAY* include nulls (Alex Martelli)
|
||||
// 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams)
|
||||
@@ -141,7 +142,7 @@ PyObject* integer_to_python(T value)
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
return to_python(value_as_long);
|
||||
return to_python(value_as_long, boost::python::lookup_tag());
|
||||
}
|
||||
|
||||
int from_python(PyObject* p, boost::python::type<int> type)
|
||||
@@ -149,7 +150,7 @@ int from_python(PyObject* p, boost::python::type<int> type)
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned int i)
|
||||
PyObject* to_python(unsigned int i, boost::python::lookup_tag)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
@@ -169,7 +170,7 @@ float from_python(PyObject* p, boost::python::type<float>)
|
||||
return static_cast<float>(from_python(p, boost::python::type<double>()));
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned short i)
|
||||
PyObject* to_python(unsigned short i, boost::python::lookup_tag)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
@@ -179,7 +180,7 @@ unsigned short from_python(PyObject* p, boost::python::type<unsigned short> type
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(char c)
|
||||
PyObject* to_python(char c, boost::python::lookup_tag)
|
||||
{
|
||||
if (c == '\0') return PyString_FromString("");
|
||||
return PyString_FromStringAndSize(&c, 1);
|
||||
@@ -197,7 +198,7 @@ char from_python(PyObject* p, boost::python::type<char>)
|
||||
return PyString_AsString(p)[0];
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned char i)
|
||||
PyObject* to_python(unsigned char i, boost::python::lookup_tag)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
@@ -207,7 +208,7 @@ unsigned char from_python(PyObject* p, boost::python::type<unsigned char> type)
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(signed char i)
|
||||
PyObject* to_python(signed char i, boost::python::lookup_tag)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
@@ -217,7 +218,7 @@ signed char from_python(PyObject* p, boost::python::type<signed char> type)
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned long x)
|
||||
PyObject* to_python(unsigned long x, boost::python::lookup_tag)
|
||||
{
|
||||
return integer_to_python(x);
|
||||
}
|
||||
@@ -243,13 +244,17 @@ const char* from_python(PyObject* p, boost::python::type<const char*>)
|
||||
return s;
|
||||
}
|
||||
|
||||
PyObject* to_python(const std::string& s)
|
||||
PyObject* to_python(const std::string& s, boost::python::lookup_tag)
|
||||
{
|
||||
return PyString_FromStringAndSize(s.data(), s.size());
|
||||
}
|
||||
|
||||
std::string from_python(PyObject* p, boost::python::type<std::string>)
|
||||
{
|
||||
if (! PyString_Check(p)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a string");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
return std::string(PyString_AsString(p), PyString_Size(p));
|
||||
}
|
||||
|
||||
@@ -263,12 +268,12 @@ bool from_python(PyObject* p, boost::python::type<bool>)
|
||||
|
||||
#ifdef BOOST_MSVC6_OR_EARLIER
|
||||
// An optimizer bug prevents these from being inlined.
|
||||
PyObject* to_python(double d)
|
||||
PyObject* to_python(double d, boost::python::lookup_tag)
|
||||
{
|
||||
return PyFloat_FromDouble(d);
|
||||
}
|
||||
|
||||
PyObject* to_python(float f)
|
||||
PyObject* to_python(float f, boost::python::lookup_tag)
|
||||
{
|
||||
return PyFloat_FromDouble(f);
|
||||
}
|
||||
|
||||
87
src/cross_module.cpp
Normal file
87
src/cross_module.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/* (C) Copyright Ralf W. Grosse-Kunstleve 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.
|
||||
|
||||
Revision History:
|
||||
17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve)
|
||||
*/
|
||||
|
||||
# include <boost/python/cross_module.hpp>
|
||||
namespace python = boost::python;
|
||||
# include <stdio.h> // MSVC6.0SP4 does not know std::fprintf
|
||||
# include <string.h> // MSVC6.0SP4 does not know std::strcmp
|
||||
|
||||
namespace {
|
||||
|
||||
PyObject* get_module_dict(const char* module_name)
|
||||
{
|
||||
python::ref module_obj(PyImport_ImportModule((char*) module_name));
|
||||
PyObject* module_dict = PyModule_GetDict(module_obj.get());
|
||||
if (module_dict == 0) throw python::import_error();
|
||||
return module_dict;
|
||||
}
|
||||
}
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
const char* converters_attribute_name = "__converters__";
|
||||
|
||||
void* import_converter_object(const std::string& module_name,
|
||||
const std::string& py_class_name,
|
||||
const std::string& attribute_name)
|
||||
{
|
||||
static std::string err;
|
||||
PyObject* module_dict = get_module_dict(const_cast<char*>(module_name.c_str()));
|
||||
PyObject* py_class = PyDict_GetItemString(module_dict, const_cast<char*>(py_class_name.c_str()));
|
||||
if (py_class == 0) {
|
||||
err = std::string("module ") + module_name + " has no attribute " + py_class_name;
|
||||
PyErr_SetString(PyExc_RuntimeError, const_cast<char*>(err.c_str()));
|
||||
throw python::import_error();
|
||||
}
|
||||
python::ref c_obj(PyObject_GetAttrString(py_class, const_cast<char*>(attribute_name.c_str())), ref::null_ok);
|
||||
if (c_obj.get() == 0) {
|
||||
err = std::string("object ") + module_name + "." + py_class_name
|
||||
+ " has no attribute " + attribute_name;
|
||||
PyErr_SetString(PyExc_RuntimeError, const_cast<char*>(err.c_str()));
|
||||
throw python::import_error();
|
||||
}
|
||||
if (! PyCObject_Check(c_obj.get())) {
|
||||
err = std::string("object ") + module_name + "." + py_class_name + "."
|
||||
+ attribute_name + " is not a PyCObject";
|
||||
PyErr_SetString(PyExc_RuntimeError, const_cast<char*>(err.c_str()));
|
||||
throw python::import_error();
|
||||
}
|
||||
return PyCObject_AsVoidPtr(c_obj.get());
|
||||
}
|
||||
|
||||
void check_export_converters_api(const int importing_major,
|
||||
const int importing_minor,
|
||||
const int imported_major,
|
||||
const int imported_minor)
|
||||
{
|
||||
if (importing_major != imported_major) {
|
||||
// Python uses fprintf(stderr, ...) for API warnings.
|
||||
fprintf(stderr,
|
||||
"Fatal: export_converters_api mismatch:"
|
||||
" Importing module = %d.%d"
|
||||
" Imported module = %d.%d\n",
|
||||
importing_major, importing_minor,
|
||||
imported_major, imported_minor);
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Fatal: export_converters_api mismatch");
|
||||
throw import_error();
|
||||
}
|
||||
if (importing_minor != imported_minor) {
|
||||
// Python uses fprintf(stderr, ...) for API warnings.
|
||||
fprintf(stderr,
|
||||
"Warning: export_converters_api mismatch:"
|
||||
" Importing module = %d.%d"
|
||||
" Imported module = %d.%d\n",
|
||||
importing_major, importing_minor,
|
||||
imported_major, imported_minor);
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
@@ -42,7 +42,7 @@ namespace detail {
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
inline PyObject* to_python(boost::python::detail::operator_dispatcher* n) { return n; }
|
||||
inline PyObject* to_python(boost::python::detail::operator_dispatcher* n, boost::python::lookup_tag) { return n; }
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
@@ -608,7 +608,7 @@ int operator_dispatcher_call_cmp(PyObject* left, PyObject* right)
|
||||
{
|
||||
try
|
||||
{
|
||||
return BOOST_PYTHON_CONVERSION::from_python(result, type<int>());
|
||||
return from_python(result, type<int>());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ struct callback
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static R call_method(PyObject* self, const char* name%(, const A%n& a%n%))
|
||||
{%(
|
||||
ref p%n(to_python(a%n));%)
|
||||
ref p%n(to_python(a%n, lookup_tag()));%)
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
@@ -49,7 +49,7 @@ struct callback
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static R call(PyObject* self%(, const A%n& a%n%))
|
||||
{%(
|
||||
ref p%n(to_python(a%n));%)
|
||||
ref p%n(to_python(a%n, lookup_tag()));%)
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
@@ -70,7 +70,7 @@ struct callback<void>
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static void call_method(PyObject* self, const char* name%(, const A%n& a%n%))
|
||||
{%(
|
||||
ref p%n(to_python(a%n));%)
|
||||
ref p%n(to_python(a%n, lookup_tag()));%)
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
@@ -79,7 +79,7 @@ struct callback<void>
|
||||
%{ template <%(class A%n%:, %)>
|
||||
%} static void call(PyObject* self%(, const A%n& a%n%))
|
||||
{%(
|
||||
ref p%n(to_python(a%n));%)
|
||||
ref p%n(to_python(a%n, lookup_tag()));%)
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
|
||||
p%n.get()%)));
|
||||
}
|
||||
|
||||
@@ -97,14 +97,14 @@ def gen_caller(member_function_args, free_function_args = None):
|
||||
return (header % (member_function_args, free_function_args)
|
||||
+ body_sections[0]
|
||||
+ gen_functions(member_function, member_function_args,
|
||||
'R', '', 'return to_python(', ');')
|
||||
'R', '', 'return to_python(', ', lookup_tag());')
|
||||
+ body_sections[1]
|
||||
+ gen_functions(member_function, member_function_args,
|
||||
'R', ' const', 'return to_python(', ');')
|
||||
'R', ' const', 'return to_python(', ', lookup_tag());')
|
||||
+ body_sections[2]
|
||||
|
||||
+ gen_functions(free_function, free_function_args,
|
||||
'R', 'return to_python(', ');')
|
||||
'R', 'return to_python(', ', lookup_tag());')
|
||||
+ body_sections[3]
|
||||
|
||||
# specialized part for void return values begins here
|
||||
|
||||
@@ -3,7 +3,7 @@ import string
|
||||
|
||||
def gen_extclass(args):
|
||||
return (
|
||||
"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
"""// (C) Copyright David Abrahams 2000-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.
|
||||
@@ -15,6 +15,7 @@ def gen_extclass(args):
|
||||
// gen_extclass.python
|
||||
|
||||
// Revision History:
|
||||
// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve)
|
||||
// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted
|
||||
// to_python (Dave Abrahams)
|
||||
|
||||
@@ -171,36 +172,45 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
// and U. T is the class the user really intends to wrap. U is a class derived
|
||||
// from T with some virtual function overriding boilerplate, or if there are no
|
||||
// virtual functions, U = held_instance<T>.
|
||||
//
|
||||
// A look-alike of this class in root/boost/python/cross_module.hpp
|
||||
// is used for the implementation of the cross-module support
|
||||
// (export_converters and import_converters). If from_python
|
||||
// and to_python converters are added or removed from the class
|
||||
// below, the class python_import_extension_class_converters has
|
||||
// to be modified accordingly.
|
||||
//
|
||||
template <class T, class U = boost::python::detail::held_instance<T> >
|
||||
class python_extension_class_converters
|
||||
{
|
||||
public:
|
||||
// Get an object which can be used to convert T to/from python. This is used
|
||||
// as a kind of concept check by the global template
|
||||
//
|
||||
// PyObject* to_python(const T& x)
|
||||
//
|
||||
// below this class, to prevent the confusing messages that would otherwise
|
||||
// pop up. Now, if T hasn't been wrapped as an extension class, the user
|
||||
// will see an error message about the lack of an eligible
|
||||
// py_extension_class_converters() function.
|
||||
friend python_extension_class_converters py_extension_class_converters(boost::python::type<T>)
|
||||
/// Get an object which can be used to convert T to/from python. This is used
|
||||
/// as a kind of concept check by the free template function
|
||||
///
|
||||
/// PyObject* to_python(const T& x, boost::python::lookup_tag)
|
||||
///
|
||||
/// below this class, to prevent the confusing messages that would otherwise
|
||||
/// pop up. Now, if T hasn't been wrapped as an extension class, the user
|
||||
/// will see an error message about the lack of an eligible
|
||||
/// py_extension_class_converters() function.
|
||||
friend python_extension_class_converters py_extension_class_converters(
|
||||
boost::python::type<T>)
|
||||
{
|
||||
return python_extension_class_converters();
|
||||
}
|
||||
|
||||
// This is a member function because in a conforming implementation, friend
|
||||
// funcitons defined inline in the class body are all instantiated as soon
|
||||
// as the enclosing class is instantiated. If T is not copyable, that causes
|
||||
// a compiler error. Instead, we access this function through the global
|
||||
// template
|
||||
//
|
||||
// PyObject* to_python(const T& x)
|
||||
//
|
||||
// defined below this class. Since template functions are instantiated only
|
||||
// on demand, errors will be avoided unless T is noncopyable and the user
|
||||
// writes code which causes us to try to copy a T.
|
||||
PyObject* to_python(const T& x) const
|
||||
/// This is a member function because in a conforming implementation, friend
|
||||
/// functions defined inline in the class body are all instantiated as soon
|
||||
/// as the enclosing class is instantiated. If T is not copyable, that causes
|
||||
/// a compiler error. Instead, we access this function through the global
|
||||
/// template
|
||||
///
|
||||
/// PyObject* to_python(const T& x, boost::python::lookup_tag)
|
||||
///
|
||||
/// defined below this class. Since template functions are instantiated only
|
||||
/// on demand, errors will be avoided unless T is noncopyable and the user
|
||||
/// writes code which causes us to try to copy a T.
|
||||
PyObject* m_to_python(const T& x) const
|
||||
{
|
||||
boost::python::reference<boost::python::detail::extension_instance> result(create_instance());
|
||||
result->add_implementation(
|
||||
@@ -209,6 +219,7 @@ class python_extension_class_converters
|
||||
return result.release();
|
||||
}
|
||||
|
||||
/// Extract a pointer to T from the given PyObject. Will throw argument_error if obj == None.
|
||||
friend
|
||||
T* non_null_from_python(PyObject* obj, boost::python::type<T*>)
|
||||
{
|
||||
@@ -231,16 +242,14 @@ class python_extension_class_converters
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
|
||||
// Convert to T*
|
||||
/// Convert obj to T*. If obj == None, returns 0.
|
||||
friend T* from_python(PyObject* obj, boost::python::type<T*>)
|
||||
{
|
||||
if (obj == Py_None)
|
||||
return 0;
|
||||
else
|
||||
return non_null_from_python(obj, boost::python::type<T*>());
|
||||
if (obj == Py_None) return 0;
|
||||
return non_null_from_python(obj, boost::python::type<T*>());
|
||||
}
|
||||
|
||||
// Extract from obj a mutable reference to the PtrType object which is holding a T.
|
||||
/// Extract from obj a mutable reference to the PtrType object which is holding a T.
|
||||
template <class PtrType>
|
||||
static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type<PtrType>)
|
||||
{
|
||||
@@ -259,10 +268,10 @@ class python_extension_class_converters
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
|
||||
// Extract from obj a reference to the PtrType object which is holding a
|
||||
// T. If it weren't for auto_ptr, it would be a constant reference. Do not
|
||||
// modify the referent except by copying an auto_ptr! If obj is None, the
|
||||
// reference denotes a default-constructed PtrType
|
||||
/// Extract from obj a reference to the PtrType object which is holding a
|
||||
/// T. If it weren't for auto_ptr, it would be a constant reference. Do not
|
||||
/// modify the referent except by copying an auto_ptr! If obj is None, the
|
||||
/// reference denotes a default-constructed PtrType
|
||||
template <class PtrType>
|
||||
static PtrType& smart_ptr_value(PyObject* obj, boost::python::type<PtrType>)
|
||||
{
|
||||
@@ -273,7 +282,9 @@ class python_extension_class_converters
|
||||
}
|
||||
return smart_ptr_reference(obj, boost::python::type<PtrType>());
|
||||
}
|
||||
|
||||
|
||||
/// Wrap x in a Python object which implements the functionality of a
|
||||
/// regular wrapped T by dereferencing a copy of x.
|
||||
template <class PtrType>
|
||||
static PyObject* smart_ptr_to_python(PtrType x)
|
||||
{
|
||||
@@ -289,6 +300,9 @@ class python_extension_class_converters
|
||||
return result.release();
|
||||
}
|
||||
|
||||
/// Create a Python object which is an instance of the Python type wrapper
|
||||
/// for T. The result does not actually contain the neccessary instance of
|
||||
/// T. This function is an implementation detail.
|
||||
static boost::python::reference<boost::python::detail::extension_instance> create_instance()
|
||||
{
|
||||
PyTypeObject* class_object = boost::python::detail::class_registry<T>::class_object();
|
||||
@@ -299,15 +313,15 @@ class python_extension_class_converters
|
||||
new boost::python::detail::extension_instance(class_object));
|
||||
}
|
||||
|
||||
// Convert to const T*
|
||||
/// Convert p to const T*
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*>)
|
||||
{ return from_python(p, boost::python::type<T*>()); }
|
||||
|
||||
// Convert to const T* const&
|
||||
/// Convert p to const T* const&
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*const&>)
|
||||
{ return from_python(p, boost::python::type<const T*>()); }
|
||||
|
||||
// Convert to T* const&
|
||||
/// Convert p to T* const&
|
||||
friend T* from_python(PyObject* p, boost::python::type<T* const&>)
|
||||
{ return from_python(p, boost::python::type<T*>()); }
|
||||
|
||||
@@ -315,11 +329,11 @@ class python_extension_class_converters
|
||||
friend T& from_python(PyObject* p, boost::python::type<T&>)
|
||||
{ return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type<T*>())); }
|
||||
|
||||
// Convert to const T&
|
||||
// Convert p to const T&
|
||||
friend const T& from_python(PyObject* p, boost::python::type<const T&>)
|
||||
{ return from_python(p, boost::python::type<T&>()); }
|
||||
|
||||
// Convert to T
|
||||
/// Convert p to T
|
||||
friend const T& from_python(PyObject* p, boost::python::type<T>)
|
||||
{ return from_python(p, boost::python::type<T&>()); }
|
||||
|
||||
@@ -332,7 +346,7 @@ class python_extension_class_converters
|
||||
friend const std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<const std::auto_ptr<T>&>)
|
||||
{ return smart_ptr_value(p, boost::python::type<std::auto_ptr<T> >()); }
|
||||
|
||||
friend PyObject* to_python(std::auto_ptr<T> x)
|
||||
friend PyObject* to_python(std::auto_ptr<T> x, boost::python::lookup_tag)
|
||||
{ return smart_ptr_to_python(x); }
|
||||
|
||||
friend boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T>&>)
|
||||
@@ -344,7 +358,7 @@ class python_extension_class_converters
|
||||
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<const boost::shared_ptr<T>&>)
|
||||
{ return smart_ptr_value(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
|
||||
friend PyObject* to_python(boost::shared_ptr<T> x)
|
||||
friend PyObject* to_python(boost::shared_ptr<T> x, boost::python::lookup_tag)
|
||||
{ return smart_ptr_to_python(x); }
|
||||
};
|
||||
|
||||
@@ -353,17 +367,15 @@ class python_extension_class_converters
|
||||
// T is a wrapped class. See the first 2 functions declared in
|
||||
// python_extension_class_converters above for more info.
|
||||
template <class T>
|
||||
PyObject* to_python(const T& x)
|
||||
PyObject* to_python(const T& x, boost::python::lookup_tag)
|
||||
{
|
||||
return py_extension_class_converters(boost::python::type<T>()).to_python(x);
|
||||
return py_extension_class_converters(boost::python::type<T>()).m_to_python(x);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters);
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T> class instance_holder;
|
||||
|
||||
@@ -49,9 +49,9 @@ PyObject* object::get() const
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
PyObject* to_python(const boost::python::tuple& x)
|
||||
PyObject* to_python(const boost::python::tuple& x, boost::python::lookup_tag)
|
||||
{
|
||||
return object_to_python(x);
|
||||
return boost::python::object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple> type)
|
||||
@@ -59,9 +59,9 @@ boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python:
|
||||
return boost::python::object_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::list& x)
|
||||
PyObject* to_python(const boost::python::list& x, boost::python::lookup_tag)
|
||||
{
|
||||
return object_to_python(x);
|
||||
return boost::python::object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list> type)
|
||||
@@ -69,9 +69,9 @@ boost::python::list from_python(PyObject* p, boost::python::type<boost::python::
|
||||
return boost::python::object_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::dictionary& x)
|
||||
PyObject* to_python(const boost::python::dictionary& x, boost::python::lookup_tag)
|
||||
{
|
||||
return object_to_python(x);
|
||||
return boost::python::object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary> type)
|
||||
@@ -79,9 +79,9 @@ boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::py
|
||||
return boost::python::object_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::string& x)
|
||||
PyObject* to_python(const boost::python::string& x, boost::python::lookup_tag)
|
||||
{
|
||||
return object_to_python(x);
|
||||
return boost::python::object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string> type)
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
#include <math.h> // for pow()
|
||||
#include <boost/rational.hpp>
|
||||
|
||||
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
|
||||
inline double pow(int x, int y) { return pow(static_cast<double>(x), y); }
|
||||
#endif
|
||||
|
||||
namespace bpl_test {
|
||||
|
||||
FooCallback::FooCallback(PyObject* self, int x)
|
||||
@@ -161,7 +165,7 @@ void throw_key_error_if_end(const StringMap& m, StringMap::const_iterator p, std
|
||||
{
|
||||
if (p == m.end())
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(key));
|
||||
PyErr_SetObject(PyExc_KeyError, to_python(key, boost::python::lookup_tag()));
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
}
|
||||
@@ -742,9 +746,9 @@ namespace boost { namespace python {
|
||||
}} // namespace boost::python
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
inline PyObject* to_python(const bpl_test::Record* p)
|
||||
inline PyObject* to_python(const bpl_test::Record* p, boost::python::lookup_tag)
|
||||
{
|
||||
return to_python(*p);
|
||||
return to_python(*p, boost::python::lookup_tag());
|
||||
}
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
@@ -831,7 +835,7 @@ namespace bpl_test {
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
const int number = BOOST_PYTHON_CONVERSION::from_python(state[0].get(), boost::python::type<int>());
|
||||
const int number = from_python(state[0].get(), boost::python::type<int>());
|
||||
if (number != 42)
|
||||
w.set_secret_number(number);
|
||||
}
|
||||
@@ -1113,13 +1117,13 @@ PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary&
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
|
||||
RawTest* first = BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<RawTest*>());
|
||||
int second = BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<int>());
|
||||
RawTest* first = from_python(args[0].get(), boost::python::type<RawTest*>());
|
||||
int second = from_python(args[1].get(), boost::python::type<int>());
|
||||
|
||||
int third = BOOST_PYTHON_CONVERSION::from_python(keywords[boost::python::string("third")].get(), boost::python::type<int>());
|
||||
int fourth = BOOST_PYTHON_CONVERSION::from_python(keywords[boost::python::string("fourth")].get(), boost::python::type<int>());
|
||||
int third = from_python(keywords[boost::python::string("third")].get(), boost::python::type<int>());
|
||||
int fourth = from_python(keywords[boost::python::string("fourth")].get(), boost::python::type<int>());
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(first->i_ + second + third + fourth);
|
||||
return to_python(first->i_ + second + third + fourth, boost::python::lookup_tag());
|
||||
}
|
||||
|
||||
void init_module()
|
||||
|
||||
Reference in New Issue
Block a user