2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 16:52:15 +00:00

Compare commits

..

10 Commits

Author SHA1 Message Date
Ralf W. Grosse-Kunstleve
7dcb0b1996 struct lookup_tag {}; to_python(x, lookup_tag());
[SVN r10226]
2001-05-25 17:07:07 +00:00
Ralf W. Grosse-Kunstleve
de57613c7e gen_extension_class.py script updated.
[SVN r10223]
2001-05-24 20:28:34 +00:00
Ralf W. Grosse-Kunstleve
ade195b9ac BOOST_NO_FRIEND_KOENIG_LOOKUP for vc60, tru64_cxx, irix_CC, linux_gcc
[SVN r10219]
2001-05-24 17:55:28 +00:00
Jens Maurer
daf0865cdf add -fPIC
[SVN r10216]
2001-05-24 10:45:38 +00:00
Jens Maurer
2fa4bb7410 std::vector<> iterators are not necessarily pointers
[SVN r10215]
2001-05-24 10:42:37 +00:00
Ralf W. Grosse-Kunstleve
6db04861ed fixes tested with vc60, tru64cxx, irixCC, gcc2952
[SVN r10211]
2001-05-24 09:02:13 +00:00
Ralf W. Grosse-Kunstleve
dac8e861c8 fixes tested with vc60, tru64cxx, irixCC, gcc2952
[SVN r10208]
2001-05-24 08:28:46 +00:00
Ralf W. Grosse-Kunstleve
f0a0e9ec02 fixes tested with vc60, tru64cxx, irixCC, gcc2952
[SVN r10207]
2001-05-24 07:50:00 +00:00
Dave Abrahams
4d3079293d Initial attempt to fix problems
[SVN r10158]
2001-05-19 23:29:04 +00:00
nobody
9261e2a3d9 This commit was manufactured by cvs2svn to create branch
'boost_python_friend_fixes'.

[SVN r10123]
2001-05-18 15:12:31 +00:00
71 changed files with 3523 additions and 1261 deletions

View File

@@ -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
View 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

View File

@@ -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
View 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

View File

@@ -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; \

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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 &lt;<a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>&gt;</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 &lt;<a href=
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>&gt;</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>&copy; 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
View 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&lt;double&gt;&amp; x, const std::vector&lt;double&gt;&amp; y) : m_x(x), m_y(y) {}
const std::vector&lt;double&gt;&amp; x() const { return m_x; }
const std::vector&lt;double&gt;&amp; y() const { return m_y; }
double correlation();
private:
std::vector&lt;double&gt; m_x;
std::vector&lt;double&gt; 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&lt;double&gt;</tt> is exposed to Python in the usual
way with the <tt>class_builder&lt;&gt;</tt> template. To also enable the
automatic conversion of <tt>std::vector&lt;double&gt;</tt> function
arguments or return values in other Boost.Python C++ modules, the
converters that convert a <tt>std::vector&lt;double&gt;</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 &lt;boost/python/cross_module.hpp&gt;
//...
class_builder&lt;std::vector&lt;double&gt; &gt; v_double(std_vector_module, &quot;double&quot;);
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&lt;&gt;</tt> template.
For example:
<pre>
#include &lt;boost/python/cross_module.hpp&gt;
//...
import_converters&lt;std::vector&lt;double&gt; &gt; v_double_converters(&quot;std_vector&quot;, &quot;double&quot;);
</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&lt;&gt;</tt> template instantiations</h2>
<tt>import_converts&lt;&gt;</tt> can be viewed as a drop-in replacement
for <tt>class_wrapper&lt;&gt;</tt>, and the recommendations for the
placement of <tt>class_wrapper&lt;&gt;</tt> template instantiations
also apply to to <tt>import_converts&lt;&gt;</tt>. In particular, it is
important that an instantiation of <tt>class_wrapper&lt;&gt;</tt> is
visible to any code which wraps a C++ function with a <tt>T</tt>,
<tt>T*</tt>, const <tt>T&amp;</tt>, etc. parameter or return value.
Therefore you may want to group all <tt>class_wrapper&lt;&gt;</tt> and
<tt>import_converts&lt;&gt;</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&lt;store&gt; py_store(your_module, &quot;store&quot;);
export_converters_noncopyable(py_store);
</pre>
The corresponding <tt>import_converters&lt;&gt;</tt> statement does not
need any special attention:
<pre>
import_converters&lt;store&gt; py_store(&quot;noncopyable_export&quot;, &quot;store&quot;);
</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 &quot;foo.py&quot;, 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 &lt;vector&gt;</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&lt;&gt;</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&lt;X&gt;::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&lt;&gt;</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>
&copy; 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>

View File

@@ -75,7 +75,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
from_python(x, boost::python::type&lt;long&gt;()));
}
PyObject* to_python(MyEnumType x)
PyObject* to_python(boost::python::semantics, MyEnumType x)
{
return to_python(static_cast&lt;long&gt;(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>

View File

@@ -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>
&copy; Copyright David Abrahams 2001. Permission to copy, use, modify,

View File

@@ -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*,&nbsp;const&nbsp;T&amp;)</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&lt</tt><i>return-type</i><tt>&gt;::call_method(self,&nbsp;&quot;</tt><i>name</i><tt>&quot;,&nbsp;</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

View File

@@ -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>
&copy; 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>

View File

@@ -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&ltFoo&gt::ptr_to_python(p);
}
PyObject* to_python(const Foo* p)
PyObject* to_python(boost::python::semantics, const Foo* p)
{
return to_python(const_cast&lt;Foo*&gt;(p));
}

View File

@@ -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();
}
}

View File

@@ -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>
&copy; 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>

View File

@@ -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&lt;</code><em>S</em><code>&gt;)</code> which convert between any C++
type <em>S</em> and a <code>PyObject*</code>, the type which represents a

View File

@@ -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.

View File

@@ -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");

View File

@@ -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
View 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
View 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

View 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
View 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");

View File

@@ -1,3 +1,5 @@
// Example by Ralf W. Grosse-Kunstleve
#include <string>
namespace { // Avoid cluttering the global namespace.

View File

@@ -1,3 +1,5 @@
// Example by Ralf W. Grosse-Kunstleve
#include <iostream>
#include <string>

View File

@@ -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
View 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
View 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

View 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
View 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
View 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

View 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
}
}

View 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
View 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
View 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
View 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();
}
}

View File

@@ -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");

View 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()

View File

@@ -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()

View File

@@ -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
View 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
View 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
View 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()

View File

@@ -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
View 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
View 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
View 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
View 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)

View 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()

View File

@@ -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(),

View File

@@ -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());
}
};

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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;

View 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

View File

@@ -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.

View File

@@ -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;

View File

@@ -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>

View File

@@ -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&>)

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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(...)
{

View File

@@ -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()%)));
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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)

View File

@@ -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()