mirror of
https://github.com/boostorg/python.git
synced 2026-01-24 18:12:43 +00:00
Compare commits
2 Commits
svn-branch
...
boost-1.22
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e32901304d | ||
|
|
9b602d16b4 |
70
Jamfile
70
Jamfile
@@ -1,70 +0,0 @@
|
||||
subproject libs/python ;
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
PYTHON_PROPERTIES
|
||||
+= <metrowerks><*><cxxflags>"-inline deferred"
|
||||
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
|
||||
<define>BOOST_PYTHON_DYNAMIC_LIB
|
||||
<define>BOOST_PYTHON_V2
|
||||
;
|
||||
|
||||
{
|
||||
dll bpl
|
||||
:
|
||||
src/converter/from_python.cpp
|
||||
src/converter/registry.cpp
|
||||
src/converter/type_id.cpp
|
||||
src/object/class.cpp
|
||||
src/object/function.cpp
|
||||
src/object/inheritance.cpp
|
||||
src/object/life_support.cpp
|
||||
src/errors.cpp
|
||||
src/module.cpp
|
||||
src/objects.cpp
|
||||
src/converter/builtin_converters.cpp
|
||||
:
|
||||
$(PYTHON_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
;
|
||||
|
||||
# -------- general test -------
|
||||
extension m1 : test/m1.cpp <lib>bpl
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
extension m2 : test/m2.cpp <lib>bpl
|
||||
:
|
||||
: debug-python ;
|
||||
|
||||
boost-python-runtest try : test/newtest.py <lib>m1 <lib>m2 : : debug-python ;
|
||||
|
||||
# ----------- builtin converters -----------
|
||||
|
||||
extension builtin_converters_ext : test/test_builtin_converters.cpp <lib>bpl
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
boost-python-runtest test_builtin_converters : test/test_builtin_converters.py
|
||||
<lib>builtin_converters_ext
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
# ----------- pointer adoption -----------
|
||||
|
||||
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <lib>bpl
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
|
||||
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
|
||||
<lib>test_pointer_adoption_ext
|
||||
:
|
||||
: debug-python
|
||||
;
|
||||
}
|
||||
156
build/Jamfile
156
build/Jamfile
@@ -1,156 +0,0 @@
|
||||
# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
# distribute this software is granted provided this copyright notice appears
|
||||
# in all copies. This software is provided "as is" without express or implied
|
||||
# warranty, and with no claim as to its suitability for any purpose.
|
||||
#
|
||||
# Boost.Python build and test Jamfile
|
||||
#
|
||||
# To run all tests quietly: jam test
|
||||
# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test
|
||||
#
|
||||
# Declares the following targets:
|
||||
# 1. libboost_python, a static link library to be linked with all
|
||||
# Boost.Python modules
|
||||
#
|
||||
# 2. pairs of test targets of the form <name>.test and <name>.run
|
||||
# <name>.test runs the test when it is out-of-date, and the "test"
|
||||
# pseudotarget depends on it. <name>.run runs
|
||||
# a test unconditionally, and can be used to force a test to run.. Each
|
||||
# test target builds one or more Boost.Python modules and runs a Python
|
||||
# script to test them. The test names are:
|
||||
#
|
||||
# from ../test
|
||||
#
|
||||
# comprehensive - a comprehensive test of Boost.Python features
|
||||
#
|
||||
# from ../example:
|
||||
# abstract -
|
||||
# getting_started1 -
|
||||
# getting_started2 -
|
||||
# simple_vector -
|
||||
# do_it_yourself_convts -
|
||||
# pickle1 -
|
||||
# pickle2 -
|
||||
# pickle3 -
|
||||
#
|
||||
# dvect1 -
|
||||
# dvect2 -
|
||||
# ivect1 -
|
||||
# ivect2 -
|
||||
# noncopyable -
|
||||
#
|
||||
# subproject-specific environment/command-line variables:
|
||||
#
|
||||
# PYTHON - How to invoke the Python interpreter. Defaults to "python"
|
||||
#
|
||||
# PYTHON_ROOT - Windows only: where Python is installed. Defaults to "c:/tools/python"
|
||||
#
|
||||
# PYTHON_VERSION - Version of Python. Defaults to "2.1" on Windows, "1.5" on Unix
|
||||
#
|
||||
# PYTHON_TEST_ARGS - specifies arguments to be passed to test scripts on
|
||||
# the command line. "-v" can be useful if you want to
|
||||
# see the output of successful tests.
|
||||
#
|
||||
# PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for
|
||||
# the dvect and ivect tests above.
|
||||
|
||||
# declare the location of this subproject relative to the root
|
||||
subproject libs/python/build ;
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_DYNAMIC_LIB ;
|
||||
|
||||
#######################
|
||||
rule bpl-test ( test-name : sources + )
|
||||
{
|
||||
boost-python-test $(test-name) : $(sources) <lib>libboost_python ;
|
||||
}
|
||||
|
||||
#######################
|
||||
|
||||
#
|
||||
# Declare the boost python static link library
|
||||
#
|
||||
|
||||
# Base names of the source files for libboost_python
|
||||
local CPP_SOURCES =
|
||||
types classes conversions extension_class functions
|
||||
init_function module_builder objects cross_module errors
|
||||
;
|
||||
|
||||
lib libboost_python_static : ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<define>BOOST_PYTHON_STATIC_LIB=1
|
||||
$(PYTHON_PROPERTIES) ;
|
||||
|
||||
dll libboost_python
|
||||
# $(SUFDLL[1])
|
||||
: ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<runtime-link>dynamic
|
||||
<define>BOOST_PYTHON_HAS_DLL_RUNTIME=1
|
||||
$(PYTHON_PROPERTIES)
|
||||
;
|
||||
|
||||
############# comprehensive module and test ###########
|
||||
bpl-test boost_python_test
|
||||
: ../test/comprehensive.cpp ;
|
||||
|
||||
boost-python-runtest comprehensive
|
||||
: ../test/comprehensive.py <lib>boost_python_test <lib>libboost_python ;
|
||||
|
||||
############# simple tests from ../example ############
|
||||
|
||||
rule boost-python-example-runtest ( name )
|
||||
{
|
||||
bpl-test $(name)
|
||||
: ../example/$(name).cpp ;
|
||||
|
||||
boost-python-runtest $(name)
|
||||
: ../example/test_$(name).py <lib>$(name) ;
|
||||
}
|
||||
|
||||
|
||||
boost-python-example-runtest abstract ;
|
||||
boost-python-example-runtest getting_started1 ;
|
||||
boost-python-example-runtest getting_started2 ;
|
||||
boost-python-example-runtest simple_vector ;
|
||||
boost-python-example-runtest do_it_yourself_convts ;
|
||||
boost-python-example-runtest pickle1 ;
|
||||
boost-python-example-runtest pickle2 ;
|
||||
boost-python-example-runtest pickle3 ;
|
||||
|
||||
|
||||
bpl-test ivect : ../example/ivect.cpp ;
|
||||
bpl-test dvect : ../example/dvect.cpp ;
|
||||
bpl-test noncopyable_export : ../example/noncopyable_export.cpp ;
|
||||
bpl-test noncopyable_import : ../example/noncopyable_import.cpp ;
|
||||
|
||||
############## cross-module tests from ../example ##########
|
||||
|
||||
# A simple rule to build a test which depends on multiple modules in the PYTHONPATH
|
||||
rule boost-python-multi-example-runtest ( test-name : modules + )
|
||||
{
|
||||
boost-python-runtest $(test-name)
|
||||
: ../example/tst_$(test-name).py <lib>$(modules) <lib>libboost_python
|
||||
: : : $(PYTHON_VECT_ITERATIONS) ;
|
||||
}
|
||||
|
||||
PYTHON_VECT_ITERATIONS ?= 10 ;
|
||||
|
||||
boost-python-multi-example-runtest dvect1 : ivect dvect ;
|
||||
boost-python-multi-example-runtest dvect2 : ivect dvect ;
|
||||
|
||||
boost-python-multi-example-runtest ivect1 : ivect dvect ;
|
||||
boost-python-multi-example-runtest ivect2 : ivect dvect ;
|
||||
|
||||
boost-python-multi-example-runtest
|
||||
noncopyable : noncopyable_import noncopyable_export ;
|
||||
|
||||
@@ -7,7 +7,6 @@ LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
errors.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
|
||||
@@ -8,7 +8,6 @@ bpl_exa = "/libs/python/example"
|
||||
files = (
|
||||
bpl_src + "/classes.cpp",
|
||||
bpl_src + "/conversions.cpp",
|
||||
bpl_src + "/errors.cpp",
|
||||
bpl_src + "/extension_class.cpp",
|
||||
bpl_src + "/functions.cpp",
|
||||
bpl_src + "/init_function.cpp",
|
||||
@@ -24,8 +23,7 @@ bpl_exa + "/abstract.cpp",
|
||||
bpl_exa + "/getting_started1.cpp",
|
||||
bpl_exa + "/getting_started2.cpp",
|
||||
bpl_exa + "/simple_vector.cpp",
|
||||
bpl_exa + "/do_it_yourself_convts.cpp",
|
||||
bpl_exa + "/nested.cpp",
|
||||
bpl_exa + "/do_it_yourself_converters.cpp",
|
||||
bpl_exa + "/pickle1.cpp",
|
||||
bpl_exa + "/pickle2.cpp",
|
||||
bpl_exa + "/pickle3.cpp",
|
||||
@@ -33,8 +31,7 @@ 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_convts.py",
|
||||
bpl_exa + "/test_nested.py",
|
||||
bpl_exa + "/test_do_it_yourself_converters.py",
|
||||
bpl_exa + "/test_pickle1.py",
|
||||
bpl_exa + "/test_pickle2.py",
|
||||
bpl_exa + "/test_pickle3.py",
|
||||
@@ -55,13 +52,6 @@ bpl_exa + "/tst_dvect2.py",
|
||||
bpl_exa + "/tst_ivect1.py",
|
||||
bpl_exa + "/tst_ivect2.py",
|
||||
bpl_exa + "/test_cross_module.py",
|
||||
bpl_exa + "/vector_wrapper.h",
|
||||
bpl_exa + "/richcmp1.cpp",
|
||||
bpl_exa + "/richcmp2.cpp",
|
||||
bpl_exa + "/richcmp3.cpp",
|
||||
bpl_exa + "/test_richcmp1.py",
|
||||
bpl_exa + "/test_richcmp2.py",
|
||||
bpl_exa + "/test_richcmp3.py",
|
||||
)
|
||||
|
||||
defs = (
|
||||
@@ -70,8 +60,7 @@ defs = (
|
||||
"getting_started1",
|
||||
"getting_started2",
|
||||
"simple_vector",
|
||||
"do_it_yourself_convts",
|
||||
"nested",
|
||||
"do_it_yourself_converters",
|
||||
"pickle1",
|
||||
"pickle2",
|
||||
"pickle3",
|
||||
@@ -79,9 +68,6 @@ defs = (
|
||||
"noncopyable_import",
|
||||
"ivect",
|
||||
"dvect",
|
||||
"richcmp1",
|
||||
"richcmp2",
|
||||
"richcmp3",
|
||||
)
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
|
||||
@@ -11,7 +11,6 @@ LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
errors.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
|
||||
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
|
||||
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=
|
||||
@@ -35,7 +35,7 @@ MAKEDEP=-M
|
||||
LD=CC -LANG:std -n32 -mips4
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.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) \
|
||||
@@ -43,12 +43,10 @@ DEPOBJ=$(OBJ) \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_convts.o \
|
||||
nested.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o \
|
||||
richcmp1.o richcmp2.o richcmp3.o
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
@@ -57,12 +55,10 @@ all: libboost_python.a \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_convts.so \
|
||||
nested.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so \
|
||||
richcmp1.so richcmp2.so richcmp3.so
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
@@ -83,11 +79,8 @@ getting_started2.so: $(OBJ) getting_started2.o
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so
|
||||
|
||||
nested.so: $(OBJ) nested.o
|
||||
$(LD) $(LDOPTS) $(OBJ) nested.o -o nested.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
|
||||
@@ -112,15 +105,6 @@ ivect.so: $(OBJ) ivect.o
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
richcmp1.so: $(OBJ) richcmp1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so
|
||||
|
||||
richcmp2.so: $(OBJ) richcmp2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so
|
||||
|
||||
richcmp3.so: $(OBJ) richcmp3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
@@ -130,15 +114,11 @@ test:
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_convts.py
|
||||
$(PYEXE) test_nested.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
$(PYEXE) test_richcmp1.py
|
||||
$(PYEXE) test_richcmp2.py
|
||||
$(PYEXE) test_richcmp3.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
@@ -147,8 +127,7 @@ clean:
|
||||
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_convts.o do_it_yourself_convts.so
|
||||
rm -f nested.o nested.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
|
||||
@@ -156,9 +135,6 @@ clean:
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f richcmp1.o richcmp1.so
|
||||
rm -f richcmp2.o richcmp2.so
|
||||
rm -f richcmp3.o richcmp3.so
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf ii_files
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
#PYEXE=PYTHONPATH=. /usr/bin/python
|
||||
#PYINC=-I/usr/include/python1.5
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
PYEXE=/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=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
|
||||
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
|
||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
||||
|
||||
STDOPTS=-fPIC -ftemplate-depth-21
|
||||
STDOPTS=-ftemplate-depth-21
|
||||
WARNOPTS=
|
||||
OPTOPTS=-g
|
||||
|
||||
@@ -33,10 +33,10 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
MAKEDEP=-M
|
||||
|
||||
LD=$(CPP)
|
||||
LD=g++
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.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) \
|
||||
@@ -44,12 +44,10 @@ DEPOBJ=$(OBJ) \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_convts.o \
|
||||
nested.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o \
|
||||
richcmp1.o richcmp2.o richcmp3.o
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
@@ -58,12 +56,10 @@ all: libboost_python.a \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_convts.so \
|
||||
nested.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so \
|
||||
richcmp1.so richcmp2.so richcmp3.so
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
@@ -84,11 +80,8 @@ getting_started2.so: $(OBJ) getting_started2.o
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so
|
||||
|
||||
nested.so: $(OBJ) nested.o
|
||||
$(LD) $(LDOPTS) $(OBJ) nested.o -o nested.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
|
||||
@@ -113,15 +106,6 @@ ivect.so: $(OBJ) ivect.o
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
richcmp1.so: $(OBJ) richcmp1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so
|
||||
|
||||
richcmp2.so: $(OBJ) richcmp2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so
|
||||
|
||||
richcmp3.so: $(OBJ) richcmp3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
@@ -131,15 +115,11 @@ test:
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_convts.py
|
||||
$(PYEXE) test_nested.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
$(PYEXE) test_richcmp1.py
|
||||
$(PYEXE) test_richcmp2.py
|
||||
$(PYEXE) test_richcmp3.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
@@ -148,8 +128,7 @@ clean:
|
||||
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_convts.o do_it_yourself_convts.so
|
||||
rm -f nested.o nested.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
|
||||
@@ -157,9 +136,6 @@ clean:
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f richcmp1.o richcmp1.so
|
||||
rm -f richcmp2.o richcmp2.so
|
||||
rm -f richcmp3.o richcmp3.so
|
||||
rm -f so_locations *.pyc
|
||||
|
||||
softlinks:
|
||||
|
||||
@@ -30,16 +30,13 @@
|
||||
# -fvtable-thunks eliminates the compiler warning, but
|
||||
# "import boost_python_test" still causes a crash.
|
||||
|
||||
ROOT=R:
|
||||
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:\Python21\python.exe"
|
||||
#PYINC=-I"C:\usr\include\python2.1"
|
||||
#PYLIB="C:\usr\lib\libpython21.a"
|
||||
|
||||
STDOPTS=-ftemplate-depth-21
|
||||
WARNOPTS=
|
||||
@@ -52,7 +49,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \
|
||||
LD=g++
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
|
||||
@@ -62,15 +59,13 @@ all: libboost_python.a \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_convts.pyd \
|
||||
nested.pyd \
|
||||
do_it_yourself_converters.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd \
|
||||
richcmp1.pyd richcmp2.pyd richcmp3.pyd
|
||||
ivect.pyd dvect.pyd
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
-del libboost_python.a
|
||||
del libboost_python.a
|
||||
ar r libboost_python.a $(OBJ)
|
||||
|
||||
DLLWRAPOPTS=-s --driver-name g++ -s \
|
||||
@@ -106,17 +101,11 @@ simple_vector.pyd: $(OBJ) simple_vector.o
|
||||
--def simple_vector.def \
|
||||
$(OBJ) simple_vector.o $(PYLIB)
|
||||
|
||||
do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.o
|
||||
do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname do_it_yourself_convts.pyd \
|
||||
--def do_it_yourself_convts.def \
|
||||
$(OBJ) do_it_yourself_convts.o $(PYLIB)
|
||||
|
||||
nested.pyd: $(OBJ) nested.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname nested.pyd \
|
||||
--def nested.def \
|
||||
$(OBJ) nested.o $(PYLIB)
|
||||
--dllname do_it_yourself_converters.pyd \
|
||||
--def do_it_yourself_converters.def \
|
||||
$(OBJ) do_it_yourself_converters.o $(PYLIB)
|
||||
|
||||
pickle1.pyd: $(OBJ) pickle1.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
@@ -160,24 +149,6 @@ dvect.pyd: $(OBJ) dvect.o
|
||||
--def dvect.def \
|
||||
$(OBJ) dvect.o $(PYLIB)
|
||||
|
||||
richcmp1.pyd: $(OBJ) richcmp1.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname richcmp1.pyd \
|
||||
--def richcmp1.def \
|
||||
$(OBJ) richcmp1.o $(PYLIB)
|
||||
|
||||
richcmp2.pyd: $(OBJ) richcmp2.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname richcmp2.pyd \
|
||||
--def richcmp2.def \
|
||||
$(OBJ) richcmp2.o $(PYLIB)
|
||||
|
||||
richcmp3.pyd: $(OBJ) richcmp3.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname richcmp3.pyd \
|
||||
--def richcmp3.def \
|
||||
$(OBJ) richcmp3.o $(PYLIB)
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
@@ -187,21 +158,17 @@ test:
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_convts.py
|
||||
$(PYEXE) test_nested.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
$(PYEXE) test_richcmp1.py
|
||||
$(PYEXE) test_richcmp2.py
|
||||
$(PYEXE) test_richcmp3.py
|
||||
|
||||
clean:
|
||||
-del *.o
|
||||
-del *.a
|
||||
-del *.pyd
|
||||
-del *.pyc
|
||||
del *.o
|
||||
del *.a
|
||||
del *.pyd
|
||||
del *.pyc
|
||||
|
||||
softlinks:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
|
||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
|
||||
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
|
||||
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= \
|
||||
@@ -46,7 +46,7 @@ LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*'
|
||||
|
||||
#HIDDEN=-hidden
|
||||
|
||||
OBJ=classes.o conversions.o errors.o extension_class.o functions.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) \
|
||||
@@ -54,12 +54,10 @@ DEPOBJ=$(OBJ) \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_convts.o \
|
||||
nested.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o \
|
||||
richcmp1.o richcmp2.o richcmp3.o
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
@@ -68,12 +66,10 @@ all: libboost_python.a \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_convts.so \
|
||||
nested.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so \
|
||||
richcmp1.so richcmp2.so richcmp3.so
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
@@ -98,11 +94,8 @@ getting_started2.so: $(OBJ) getting_started2.o
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so
|
||||
|
||||
nested.so: $(OBJ) nested.o
|
||||
$(LD) $(LDOPTS) $(OBJ) nested.o -o nested.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
|
||||
@@ -127,15 +120,6 @@ ivect.so: $(OBJ) ivect.o
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
richcmp1.so: $(OBJ) richcmp1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so
|
||||
|
||||
richcmp2.so: $(OBJ) richcmp2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so
|
||||
|
||||
richcmp3.so: $(OBJ) richcmp3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
@@ -145,15 +129,11 @@ test:
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_convts.py
|
||||
$(PYEXE) test_nested.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
$(PYEXE) test_richcmp1.py
|
||||
$(PYEXE) test_richcmp2.py
|
||||
$(PYEXE) test_richcmp3.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
@@ -162,8 +142,7 @@ clean:
|
||||
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_convts.o do_it_yourself_convts.so
|
||||
rm -f nested.o nested.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
|
||||
@@ -171,9 +150,6 @@ clean:
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f richcmp1.o richcmp1.so
|
||||
rm -f richcmp2.o richcmp2.so
|
||||
rm -f richcmp3.o richcmp3.so
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf cxx_repository
|
||||
|
||||
|
||||
@@ -10,18 +10,15 @@
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
ROOT=R:
|
||||
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"
|
||||
PYEXE="C:\Python21\python.exe"
|
||||
PYINC=/I"C:\Python21\include"
|
||||
PYLIB="C:\Python21\libs\python21.lib"
|
||||
PYEXE="C:\Program files\Python\python.exe"
|
||||
PYINC=/I"C:\Program files\Python\include"
|
||||
PYLIB="C:\Program files\Python\libs\python15.lib"
|
||||
|
||||
STDOPTS=/nologo /MD /GR /GX /Zm300 /DBOOST_PYTHON_STATIC_LIB
|
||||
STDOPTS=/nologo /MD /GR /GX /Zm200
|
||||
WARNOPTS=
|
||||
OPTOPTS=
|
||||
|
||||
@@ -32,7 +29,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \
|
||||
LD=link.exe
|
||||
LDOPTS=/nologo /dll /incremental:no
|
||||
|
||||
OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \
|
||||
OBJ=classes.obj conversions.obj extension_class.obj functions.obj \
|
||||
init_function.obj module_builder.obj \
|
||||
objects.obj types.obj cross_module.obj
|
||||
|
||||
@@ -43,12 +40,10 @@ all: boost_python.lib \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_convts.pyd \
|
||||
nested.pyd \
|
||||
do_it_yourself_converters.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd \
|
||||
richcmp1.pyd richcmp2.pyd richcmp3.pyd
|
||||
ivect.pyd dvect.pyd
|
||||
|
||||
boost_python.lib: $(OBJ)
|
||||
$(LD) -lib /nologo /out:boost_python.lib $(OBJ)
|
||||
@@ -68,11 +63,8 @@ getting_started2.pyd: $(OBJ) getting_started2.obj
|
||||
simple_vector.pyd: $(OBJ) simple_vector.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd"
|
||||
|
||||
do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) /export:initdo_it_yourself_convts /out:"do_it_yourself_convts.pyd"
|
||||
|
||||
nested.pyd: $(OBJ) nested.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) /export:initnested /out:"nested.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"
|
||||
@@ -95,15 +87,6 @@ ivect.pyd: $(OBJ) ivect.obj
|
||||
dvect.pyd: $(OBJ) dvect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd"
|
||||
|
||||
richcmp1.pyd: $(OBJ) richcmp1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) /export:initrichcmp1 /out:"richcmp1.pyd"
|
||||
|
||||
richcmp2.pyd: $(OBJ) richcmp2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) /export:initrichcmp2 /out:"richcmp2.pyd"
|
||||
|
||||
richcmp3.pyd: $(OBJ) richcmp3.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) /export:initrichcmp3 /out:"richcmp3.pyd"
|
||||
|
||||
.cpp.obj:
|
||||
$(CPP) $(CPPOPTS) /c $*.cpp
|
||||
|
||||
@@ -113,23 +96,19 @@ test:
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_convts.py
|
||||
$(PYEXE) test_nested.py
|
||||
$(PYEXE) test_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
|
||||
$(PYEXE) test_richcmp1.py
|
||||
$(PYEXE) test_richcmp2.py
|
||||
$(PYEXE) test_richcmp3.py
|
||||
|
||||
clean:
|
||||
-del *.obj
|
||||
-del *.lib
|
||||
-del *.exp
|
||||
-del *.idb
|
||||
-del *.pyd
|
||||
-del *.pyc
|
||||
del *.obj
|
||||
del *.lib
|
||||
del *.exp
|
||||
del *.idb
|
||||
del *.pyd
|
||||
del *.pyc
|
||||
|
||||
softlinks:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
# Usage:
|
||||
#
|
||||
# make copy Copy the sources and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make del Remove the sources and tests
|
||||
#
|
||||
# Revision history:
|
||||
# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve)
|
||||
|
||||
ROOT=R:
|
||||
BOOST_WIN="$(ROOT)\boost"
|
||||
BOOST_UNIX=$(HOME)/boost
|
||||
|
||||
#PYEXE="C:\Program files\Python\python.exe"
|
||||
#PYINC=-I"C:\Program files\Python\include"
|
||||
#PYLIB="C:\Program files\Python\libs\python15.lib"
|
||||
PYEXE="C:\Python21\python.exe"
|
||||
PYINC=-I"C:\Python21\include"
|
||||
PYLIB="C:\Python21\libs\python21.lib"
|
||||
|
||||
STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB
|
||||
WARNOPTS=-warn on,nounusedexpr,nounused
|
||||
OPTOPTS=-O
|
||||
|
||||
CPP=mwcc
|
||||
CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \
|
||||
$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC)
|
||||
|
||||
LD=mwld
|
||||
LDOPTS=-export dllexport -shared
|
||||
|
||||
OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \
|
||||
init_function.obj module_builder.obj \
|
||||
objects.obj types.obj cross_module.obj
|
||||
|
||||
.SUFFIXES: .obj .cpp
|
||||
|
||||
all: libboost_python.lib \
|
||||
boost_python_test.pyd \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_convts.pyd \
|
||||
nested.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd \
|
||||
richcmp1.pyd richcmp2.pyd richcmp3.pyd
|
||||
|
||||
libboost_python.lib: $(OBJ)
|
||||
$(LD) -library -o libboost_python.lib $(OBJ)
|
||||
|
||||
boost_python_test.pyd: $(OBJ) comprehensive.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) -o boost_python_test.pyd
|
||||
|
||||
abstract.pyd: $(OBJ) abstract.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) -o abstract.pyd
|
||||
|
||||
getting_started1.pyd: $(OBJ) getting_started1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) -o getting_started1.pyd
|
||||
|
||||
getting_started2.pyd: $(OBJ) getting_started2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) -o getting_started2.pyd
|
||||
|
||||
simple_vector.pyd: $(OBJ) simple_vector.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) -o simple_vector.pyd
|
||||
|
||||
do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) -o do_it_yourself_convts.pyd
|
||||
|
||||
nested.pyd: $(OBJ) nested.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) -o nested.pyd
|
||||
|
||||
pickle1.pyd: $(OBJ) pickle1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) -o pickle1.pyd
|
||||
|
||||
pickle2.pyd: $(OBJ) pickle2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) -o pickle2.pyd
|
||||
|
||||
pickle3.pyd: $(OBJ) pickle3.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) -o pickle3.pyd
|
||||
|
||||
noncopyable_export.pyd: $(OBJ) noncopyable_export.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) -o noncopyable_export.pyd
|
||||
|
||||
noncopyable_import.pyd: $(OBJ) noncopyable_import.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) -o noncopyable_import.pyd
|
||||
|
||||
ivect.pyd: $(OBJ) ivect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) -o ivect.pyd
|
||||
|
||||
dvect.pyd: $(OBJ) dvect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) -o dvect.pyd
|
||||
|
||||
richcmp1.pyd: $(OBJ) richcmp1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) -o richcmp1.pyd
|
||||
|
||||
richcmp2.pyd: $(OBJ) richcmp2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) -o richcmp2.pyd
|
||||
|
||||
richcmp3.pyd: $(OBJ) richcmp3.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) -o richcmp3.pyd
|
||||
|
||||
.cpp.obj:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_convts.py
|
||||
$(PYEXE) test_nested.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
$(PYEXE) test_richcmp1.py
|
||||
$(PYEXE) test_richcmp2.py
|
||||
$(PYEXE) test_richcmp3.py
|
||||
|
||||
clean:
|
||||
-del *.obj
|
||||
-del *.lib
|
||||
-del *.exp
|
||||
-del *.idb
|
||||
-del *.pyd
|
||||
-del *.pyc
|
||||
|
||||
softlinks:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||
|
||||
unlink:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink
|
||||
|
||||
cp:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp
|
||||
|
||||
rm:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm
|
||||
|
||||
copy:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy
|
||||
|
||||
del:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del
|
||||
@@ -1,2 +0,0 @@
|
||||
call "c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat"
|
||||
set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib
|
||||
@@ -112,10 +112,10 @@ that.''<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
|
||||
<h2>ILU</h2>
|
||||
<p>
|
||||
<a
|
||||
href="ftp://ftp.parc.xerox.com/pub/ilu/ilu.html">ILU</a>
|
||||
href="http://www.cl.cam.ac.uk/Research/Rainbow/projects/origami/ilu-1.8-manual">ILU</a>
|
||||
is a very ambitious project which tries to describe a module's interface
|
||||
(types and functions) in terms of an <a
|
||||
href="ftp://ftp.parc.xerox.com/pub/ilu/2.0b1/manual-html/manual_2.html">Interface
|
||||
href="http://www.cl.cam.ac.uk/Research/Rainbow/projects/origami/ilu-1.8-manual/manual_2.html">Interface
|
||||
Specification Language</a> (ISL) so that it can be uniformly interfaced
|
||||
to a wide range of computer languages, including Common Lisp, C++, C,
|
||||
Modula-3, and Python. ILU can parse the ISL to generate a C++ language
|
||||
|
||||
@@ -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::make_ref(enum_value_1), "enum_value_1");
|
||||
mymodule.add(boost::python::make_ref(enum_value_2), "enum_value_2");
|
||||
mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1");
|
||||
mymodule.add(boost::python::to_python(enum_value_2), "enum_value_2");
|
||||
...
|
||||
</pre></blockquote>
|
||||
|
||||
|
||||
@@ -98,12 +98,6 @@ Notes:<ul>
|
||||
|
||||
<li>Any function added to a class whose initial argument matches the class (or
|
||||
any base) will act like a member function in Python.
|
||||
|
||||
<li>To define a nested class, just pass the enclosing
|
||||
<tt>class_builder</tt> (instead of a <tt>module_builder</tt>) as the
|
||||
first argument to the nested <tt>class_builder</tt>'s constructor.
|
||||
|
||||
|
||||
</ul>
|
||||
<p>
|
||||
We can even make a subclass of <code>hello.world</code>:
|
||||
|
||||
@@ -1,326 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>A New Type Conversion Mechanism for Boost.Python</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<p><img border="0" src="../../../c++boost.gif" width="277" height="86"
|
||||
alt="boost logo"></p>
|
||||
|
||||
<h1>A New Type Conversion Mechanism for Boost.Python</h1>
|
||||
|
||||
<p>By <a href="../../../people/dave_abrahams.htm">David Abrahams</a>.
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
This document describes a redesign of the mechanism for automatically
|
||||
converting objects between C++ and Python. The current implementation
|
||||
uses two functions for any type <tt>T</tt>:
|
||||
|
||||
<blockquote><pre>
|
||||
U from_python(PyObject*, type<T>);
|
||||
void to_python(V);
|
||||
</pre></blockquote>
|
||||
|
||||
where U is convertible to T and T is convertible to V. These functions
|
||||
are at the heart of C++/Python interoperability in Boost.Python, so
|
||||
why would we want to change them? There are many reasons:
|
||||
|
||||
<h3>Bugs</h3>
|
||||
<p>Firstly, the current mechanism relies on a common C++ compiler
|
||||
bug. This is not just embarrassing: as compilers get to be more
|
||||
conformant, the library stops working. The issue, in detail, is the
|
||||
use of inline friend functions in templates to generate
|
||||
conversions. It is a very powerful, and legal technique as long as
|
||||
it's used correctly:
|
||||
|
||||
<blockquote><pre>
|
||||
template <class Derived>
|
||||
struct add_some_functions
|
||||
{
|
||||
friend <i>return-type</i> some_function1(..., Derived <i>cv-*-&-opt</i>, ...);
|
||||
friend <i>return-type</i> some_function2(..., Derived <i>cv-*-&-opt</i>, ...);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct some_template : add_some_functions<some_template<T> >
|
||||
{
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
The <tt>add_some_functions</tt> template generates free functions
|
||||
which operate on <tt>Derived</tt>, or on related types. Strictly
|
||||
speaking the related types are not just cv-qualified <tt>Derived</tt>
|
||||
values, pointers and/or references. Section 3.4.2 in the standard
|
||||
describes exactly which types you must use as parameters to these
|
||||
functions if you want the functions to be found
|
||||
(there is also a less-technical description in section 11.5.1 of
|
||||
C++PL3 <a href="#ref_1">[1]</a>). Suffice it to say that
|
||||
with the current design, the <tt>from_python</tt> and
|
||||
<tt>to_python</tt> functions are not supposed to be callable under any
|
||||
conditions!
|
||||
|
||||
<h3>Compilation and Linking Time</h3>
|
||||
|
||||
The conversion functions generated for each wrapped class using the
|
||||
above technique are not function templates, but regular functions. The
|
||||
upshot is that they must <i>all</i> be generated regardless of whether
|
||||
they are actually used. Generating all of those functions can slow
|
||||
down module compilation, and resolving the references can slow down
|
||||
linking.
|
||||
|
||||
<h3>Efficiency</h3>
|
||||
|
||||
The conversion functions are primarily used in (member) function
|
||||
wrappers to convert the arguments and return values. Being functions,
|
||||
converters have no interface which allows us to ask "will the
|
||||
conversion succeed?" without calling the function. Since the
|
||||
return value of the function must be the object to be passed as an
|
||||
argument, Boost.Python currently uses C++ exception-handling to detect
|
||||
an unsuccessful conversion. It's not a particularly good use of
|
||||
exception-handling, since the failure is not handled very far from
|
||||
where it occurred. More importantly, it means that C++ exceptions are
|
||||
thrown during overload resolution as we seek an overload that matches
|
||||
the arguments passed. Depending on the implementation, this approach
|
||||
can result in significant slowdowns.
|
||||
|
||||
<p>It is also unclear that the current library generates a minimal
|
||||
amount of code for any type conversion. Many of the conversion
|
||||
functions are nontrivial, and partly because of compiler limitations,
|
||||
they are declared <tt>inline</tt>. Also, we could have done a better
|
||||
job separating the type-specific conversion code from the code which
|
||||
is type-independent.
|
||||
|
||||
<h3>Cross-module Support</h3>
|
||||
|
||||
The current strategy requires every module to contain the definition
|
||||
of conversions it uses. In general, a new module can never supply
|
||||
conversion code which is used by another module. Ralf Grosse-Kunstleve
|
||||
designed a clever system which imports conversions directly from one
|
||||
library into another using some explicit declarations, but it has some
|
||||
disadvantages also:
|
||||
|
||||
<ol>
|
||||
<li>The system Ullrich Koethe designed for implicit conversion between
|
||||
wrapped classes related through inheritance does not currently work if
|
||||
the classes are defined in separate modules.
|
||||
|
||||
<li>The writer of the importing module is required to know the name of
|
||||
the module supplying the imported conversions.
|
||||
|
||||
<li>There can be only one way to extract any given C++ type from a
|
||||
Python object in a given module.
|
||||
</ol>
|
||||
|
||||
The first item might be addressed by moving Boost.Python into a shared
|
||||
library, but the other two cannot. Ralf turned the limitation in item
|
||||
two into a feature: the required module is loaded implicitly when a
|
||||
conversion it defines is invoked. We will probably want to provide
|
||||
that functionality anyway, but it's not clear that we should require
|
||||
the declaration of all such conversions. The final item is a more
|
||||
serious limitation. If, for example, new numeric types are defined in
|
||||
separate modules, and these types can all be converted to
|
||||
<tt>double</tt>s, we have to choose just one conversion method.
|
||||
|
||||
<h3>Ease-of-use</h3>
|
||||
|
||||
One persistent source of confusion for users of Boost.Python has been
|
||||
the fact that conversions for a class are not be visible at
|
||||
compile-time until the declaration of that class has been seen. When
|
||||
the user tries to expose a (member) function operating on or returning
|
||||
an instance of the class in question, compilation fails...even though
|
||||
the user goes on to expose the class in the same translation unit!
|
||||
|
||||
<p>
|
||||
The new system lifts all compile-time checks for the existence of
|
||||
particular type conversions and replaces them with runtime checks, in
|
||||
true Pythonic style. While this might seem cavalier, the compile-time
|
||||
checks are actually not much use in the current system if many classes
|
||||
are wrapped in separate modules, since the checks are based only on
|
||||
the user's declaration that the conversions exist.
|
||||
|
||||
<h2>The New Design</h2>
|
||||
|
||||
<h3>Motivation</h3>
|
||||
|
||||
The new design was heavily influenced by a desire to generate as
|
||||
little code as possible in extension modules. Some of Boost.Python's
|
||||
clients are enormous projects where link time is proportional to the
|
||||
amount of object code, and there are many Python extension modules. As
|
||||
such, we try to keep type-specific conversion code out of modules
|
||||
other than the one the converters are defined in, and rely as much as
|
||||
possible on centralized control through a shared library.
|
||||
|
||||
<h3>The Basics</h3>
|
||||
|
||||
The library contains a <tt>registry</tt> which maps runtime type
|
||||
identifiers (actually an extension of <tt>std::type_info</tt> which
|
||||
preserves references and constness) to entries containing type
|
||||
converters. An <tt>entry</tt> can contain only one converter from C++ to Python
|
||||
(<tt>wrapper</tt>), but many converters from Python to C++
|
||||
(<tt>unwrapper</tt>s). <font color="#ff0000">What should happen if
|
||||
multiple modules try to register wrappers for the same type?</font>. Wrappers
|
||||
and unwrappers are known as <tt>body</tt> objects, and are accessed
|
||||
by the user and the library (in its function-wrapping code) through
|
||||
corresponding <tt>handle</tt> (<tt>wrap<T></tt> and
|
||||
<tt>unwrap<T></tt>) objects. The <tt>handle</tt> objects are
|
||||
extremely lightweight, and delegate <i>all</i> of their operations to
|
||||
the corresponding <tt>body</tt>.
|
||||
|
||||
<p>
|
||||
When a <tt>handle</tt> object is constructed, it accesses the
|
||||
registry to find a corresponding <tt>body</tt> that can convert the
|
||||
handle's constructor argument. Actually the registry record for any
|
||||
type
|
||||
<tt>T</tt>used in a module is looked up only once and stored in a
|
||||
static <tt>registration<T></tt> object for efficiency. For
|
||||
example, if the handle is an <tt>unwrap<Foo&></tt> object,
|
||||
the <tt>entry</tt> for <tt>Foo&</tt> is looked up in the
|
||||
<tt>registry</tt>, and each <tt>unwrapper</tt> it contains is queried
|
||||
to determine if it can convert the
|
||||
<tt>PyObject*</tt> with which the <tt>unwrap</tt> was constructed. If
|
||||
a body object which can perform the conversion is found, a pointer to
|
||||
it is stored in the handle. A body object may at any point store
|
||||
additional data in the handle to speed up the conversion process.
|
||||
|
||||
<p>
|
||||
Now that the handle has been constructed, the user can ask it whether
|
||||
the conversion can be performed. All handles can be tested as though
|
||||
they were convertible to <tt>bool</tt>; a <tt>true</tt> value
|
||||
indicates success. If the user forges ahead and tries to do the
|
||||
conversion without checking when no conversion is possible, an
|
||||
exception will be thrown as usual. The conversion itself is performed
|
||||
by the body object.
|
||||
|
||||
<h3>Handling complex conversions</h3>
|
||||
|
||||
<p>Some conversions may require a dynamic allocation. For example,
|
||||
when a Python tuple is converted to a <tt>std::vector<double>
|
||||
const&</tt>, we need some storage into which to construct the
|
||||
vector so that a reference to it can be formed. Furthermore, multiple
|
||||
conversions of the same type may need to be "active"
|
||||
simultaneously, so we can't keep a single copy of the storage
|
||||
anywhere. We could keep the storage in the <tt>body</tt> object, and
|
||||
have the body clone itself in case the storage is used, but in that
|
||||
case the storage in the body which lives in the registry is never
|
||||
used. If the storage was actually an object of the target type (the
|
||||
safest way in C++), we'd have to find a way to construct one for the
|
||||
body in the registry, since it may not have a default constructor.
|
||||
|
||||
<p>
|
||||
The most obvious way out of this quagmire is to allocate the object using a
|
||||
<i>new-expression</i>, and store a pointer to it in the handle. Since
|
||||
the <tt>body</tt> object knows everything about the data it needs to
|
||||
allocate (if any), it is also given responsibility for destroying that
|
||||
data. When the <tt>handle</tt> is destroyed it asks the <tt>body</tt>
|
||||
object to tear down any data it may have stored there. In many ways,
|
||||
you can think of the <tt>body</tt> as a "dynamically-determined
|
||||
vtable" for the handle.
|
||||
|
||||
<h3>Eliminating Redundancy</h3>
|
||||
|
||||
If you look at the current Boost.Python code, you'll see that there
|
||||
are an enormous number of conversion functions generated for each
|
||||
wrapped class. For a given class <tt>T</tt>, functions are generated
|
||||
to extract the following types <tt>from_python</tt>:
|
||||
|
||||
<blockquote><pre>
|
||||
T*
|
||||
T const*
|
||||
T const* const&
|
||||
T* const&
|
||||
T&
|
||||
T const&
|
||||
T
|
||||
std::auto_ptr<T>&
|
||||
std::auto_ptr<T>
|
||||
std::auto_ptr<T> const&
|
||||
boost::shared_ptr<T>&
|
||||
boost::shared_ptr<T>
|
||||
boost::shared_ptr<T> const&
|
||||
</pre></blockquote>
|
||||
|
||||
Most of these are implemented in terms of just a few conversions, and
|
||||
<t>if you're lucky</t>, they will be inlined and cause no extra
|
||||
overhead. In the new system, however, a significant amount of data
|
||||
will be associated with each type that needs to be converted. We
|
||||
certainly don't want to register a separate unwrapper object for all
|
||||
of the above types.
|
||||
|
||||
<p>Fortunately, much of the redundancy can be eliminated. For example,
|
||||
if we generate an unwrapper for <tt>T&</tt>, we don't need an
|
||||
unwrapper for <tt>T const&</tt> or <tt>T</tt>. Accordingly, the user's
|
||||
request to wrap/unwrap a given type is translated at compile-time into
|
||||
a request which helps to eliminate redundancy. The rules used to
|
||||
<tt>unwrap</tt> a type are:
|
||||
|
||||
<ol>
|
||||
<li> Treat built-in types specially: when unwrapping a value or
|
||||
constant reference to one of these, use a value for the target
|
||||
type. It will bind to a const reference if neccessary, and more
|
||||
importantly, avoids having to dynamically allocate room for
|
||||
an lvalue of types which can be cheaply copied.
|
||||
<li>
|
||||
Reduce everything else to a reference to an un-cv-qualified type
|
||||
where possible. Since cv-qualification is lost on Python
|
||||
anyway, there's no point in trying to convert to a
|
||||
<tt>const&</tt>. <font color="#ff0000">What about conversions
|
||||
to values like the tuple->vector example above? It seems to me
|
||||
that we don't want to make a <tt>vector<double>&</tt>
|
||||
(non-const) converter available for that case. We may need to
|
||||
rethink this slightly.</font>
|
||||
</ol>
|
||||
|
||||
<p>To handle the problem described above in item 2, we modify the
|
||||
procedure slightly. To unwrap any non-scalar <tt>T</tt>, we seek an
|
||||
unwrapper for <tt>add_reference<T>::type</tt>. Unwrappers for
|
||||
<tt>T const&</tt> always return <tt>T&</tt>, and are
|
||||
registered under both <tt>T &</tt> and
|
||||
<tt>T const&</tt>.
|
||||
|
||||
<p>For compilers not supporting partial specialization, unwrappers for
|
||||
<tt>T const&</tt> must return <tt>T const&</tt>
|
||||
(since constness can't be stripped), but a separate unwrapper object
|
||||
need to be registered for <tt>T &</tt> and
|
||||
<tt>T const&</tt> anyway, for the same reasons.
|
||||
|
||||
<font color="#ff0000">We may want to make it possible to compile as
|
||||
though partial specialization were unavailable even on compilers where
|
||||
it is available, in case modules could be compiled by different
|
||||
compilers with compatible ABIs (e.g. Intel C++ and MSVC6).</font>
|
||||
|
||||
<h3>Efficient Argument Conversion</h3>
|
||||
|
||||
Since type conversions are primarily used in function wrappers, an
|
||||
optimization is provided for the case where a group of conversions are
|
||||
used together. Each <tt>handle</tt> class has a corresponding
|
||||
"<tt>_more</tt>" class which does the same job, but has a
|
||||
trivial destructor. Instead of asking each "<tt>_more</tt>"
|
||||
handle to destroy its own body, it is linked into an endogenous list
|
||||
managed by the first (ordinary) handle. The <tt>wrap</tt> and
|
||||
<tt>unwrap</tt> destructors are responsible for traversing that list
|
||||
and asking each <tt>body</tt> class to tear down its
|
||||
<tt>handle</tt>. This mechanism is also used to determine if all of
|
||||
the argument/return-value conversions can succeed with a single
|
||||
function call in the function wrapping code. <font color="#ff0000">We
|
||||
might need to handle return values in a separate step for Python
|
||||
callbacks, since the availablility of a conversion won't be known
|
||||
until the result object is retrieved.</font>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<h2>References</h2>
|
||||
|
||||
<p><a name="ref_1">[1]</a>B. Stroustrup, The C++ Programming Language
|
||||
Special Edition Addison-Wesley, ISBN 0-201-70073-5.
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->19 December 2001<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
|
||||
<p>© Copyright David Abrahams, 2001</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,111 +0,0 @@
|
||||
This hierarchy contains converter handle classes.
|
||||
|
||||
|
||||
+-------------+
|
||||
| noncopyable |
|
||||
+-------------+
|
||||
^
|
||||
| A common base class used so that
|
||||
+--------+--------+ conversions can be linked into a
|
||||
| conversion_base | chain for efficient argument
|
||||
+-----------------+ conversion
|
||||
^
|
||||
|
|
||||
+---------+-----------+
|
||||
| |
|
||||
+-----------+----+ +------+-------+ only used for
|
||||
| unwrap_more<T> | | wrap_more<T> | chaining, and don't manage any
|
||||
+----------------+ +--------------+ resources.
|
||||
^ ^
|
||||
| |
|
||||
+-----+-----+ +-------+-+ These converters are what users
|
||||
| unwrap<T> | | wrap<T> | actually touch, but they do so
|
||||
+-----------+ +---------+ through a type generator which
|
||||
minimizes the number of converters
|
||||
that must be generated, so they
|
||||
|
||||
|
||||
Each unwrap<T>, unwrap_more<T>, wrap<T>, wrap_more<T> converter holds
|
||||
a reference to an appropriate converter object
|
||||
|
||||
This hierarchy contains converter body classes
|
||||
|
||||
Exposes use/release which
|
||||
are needed in case the converter
|
||||
+-----------+ in the registry needs to be
|
||||
| converter | cloned. That occurs when a
|
||||
+-----------+ unwrap target type is not
|
||||
^ contained within the Python object.
|
||||
|
|
||||
+------------------+-----+
|
||||
| |
|
||||
+--------+-------+ Exposes |
|
||||
| unwrapper_base | convertible() |
|
||||
+----------------+ |
|
||||
^ |
|
||||
| |
|
||||
+--------+----+ +-----+-----+
|
||||
| unwrapper<T>| | wrapper<T>|
|
||||
+-------------+ +-----------+
|
||||
Exposes T convert(PyObject*) Exposes PyObject* convert(T)
|
||||
|
||||
|
||||
unwrap:
|
||||
|
||||
constructed with a PyObject*, whose reference count is
|
||||
incremented.
|
||||
|
||||
find the registry entry for the target type
|
||||
|
||||
look in the collection of converters for one which claims to be
|
||||
able to convert the PyObject to the target type.
|
||||
|
||||
stick a pointer to the unwrapper in the unwrap object
|
||||
|
||||
when unwrap is queried for convertibility, it checks to see
|
||||
if it has a pointer to an unwrapper.
|
||||
|
||||
on conversion, the unwrapper is asked to allocate an
|
||||
implementation if the unwrap object isn't already holding
|
||||
one. The unwrap object "takes ownership" of the unwrapper's
|
||||
implementation. No memory allocation will actually take place
|
||||
unless this is a value conversion.
|
||||
|
||||
on destruction, the unwrapper is asked to free any implementation
|
||||
held by the unwrap object. No memory deallocation actually
|
||||
takes place unless this is a value conversion
|
||||
|
||||
on destruction, the reference count on the held PyObject is
|
||||
decremented.
|
||||
|
||||
We need to make sure that by default, you can't instantiate
|
||||
callback<> for reference and pointer return types: although the
|
||||
unwrappers may exist, they may convert by-value, which would cause
|
||||
the referent to be destroyed upon return.
|
||||
|
||||
wrap:
|
||||
|
||||
find the registry entry for the source type
|
||||
|
||||
see if there is a converter. If found, stick a pointer to it in
|
||||
the wrap object.
|
||||
|
||||
when queried for convertibility, it checks to see if it has a
|
||||
pointer to a converter.
|
||||
|
||||
on conversion, a reference to the target PyObject is held by the
|
||||
converter. Generally, the PyObject will have been created by the
|
||||
converter, but in certain cases it may be a pre-existing object,
|
||||
whose reference count will have been incremented.
|
||||
|
||||
when a wrap<T> x is used to return from a C++ function,
|
||||
x.release() is returned so that x no longer holds a reference to
|
||||
the PyObject when destroyed.
|
||||
|
||||
Otherwise, on destruction, any PyObject still held has its
|
||||
reference-count decremented.
|
||||
|
||||
|
||||
When a converter is created by the user, the appropriate element must
|
||||
be added to the registry; when it is destroyed, it must be removed
|
||||
from the registry.
|
||||
@@ -85,7 +85,7 @@ code before the last Python reference to it disappears:
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
PyObject* to_python(Foo* p)
|
||||
{
|
||||
return boost::python::python_extension_class_converters<Foo>::smart_ptr_to_python(p);
|
||||
return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p);
|
||||
}
|
||||
|
||||
PyObject* to_python(const Foo* p)
|
||||
|
||||
106
doc/richcmp.html
106
doc/richcmp.html
@@ -1,106 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
|
||||
<title>Rich Comparisons</title>
|
||||
|
||||
<div>
|
||||
|
||||
<img src="../../../c++boost.gif"
|
||||
alt="c++boost.gif (8819 bytes)"
|
||||
align="center"
|
||||
width="277" height="86">
|
||||
|
||||
<hr>
|
||||
<h1>Rich Comparisons</h1>
|
||||
|
||||
<hr>
|
||||
In Python versions up to and including Python 2.0, support for
|
||||
implementing comparisons on user-defined classes and extension types
|
||||
was quite simple. Classes could implement a <tt>__cmp__</tt> method
|
||||
that was given two instances of a class as arguments, and could only
|
||||
return <tt>0</tt> if they were equal or <tt>+1</tt> or <tt>-1</tt> if
|
||||
they were not. The method could not raise an exception or return
|
||||
anything other than an integer value.
|
||||
In Python 2.1, <b>Rich Comparisons</b> were added (see
|
||||
<a href="http://python.sourceforge.net/peps/pep-0207.html">PEP 207</a>).
|
||||
Python classes can now individually overload each of the <, <=,
|
||||
>, >=, ==, and != operations.
|
||||
|
||||
<p>
|
||||
For more detailed information, search for "rich comparison"
|
||||
<a href="http://www.python.org/doc/current/ref/customization.html"
|
||||
>here</a>.
|
||||
|
||||
<p>
|
||||
Boost.Python supports both automatic overloading and manual overloading
|
||||
of the Rich Comparison operators. The <b>compile-time</b> support is
|
||||
independent of the Python version that is used when compiling
|
||||
Boost.Python extension modules. That is, <tt>op_lt</tt> for example can
|
||||
always be used, and the C++ <tt>operator<</tt> will always be bound
|
||||
to the Python method <tt>__lt__</tt>. However, the <b>run-time</b>
|
||||
behavior will depend on the Python version.
|
||||
|
||||
<p>
|
||||
With Python versions before 2.1, the Rich Comparison operators will not
|
||||
be called by Python when any of the six comparison operators
|
||||
(<tt><</tt>, <tt><=</tt>, <tt>==</tt>, <tt>!=</tt>,
|
||||
<tt>></tt>, <tt>>=</tt>) is used in an expression. The only way
|
||||
to access the corresponding methods is to call them explicitly, e.g.
|
||||
<tt>a.__lt__(b)</tt>. Only with Python versions 2.1 or higher will
|
||||
expressions like <tt>a < b</tt> work as expected.
|
||||
|
||||
<p>
|
||||
To support Rich Comparisions, the Python C API was modified between
|
||||
Python versions 2.0 and 2.1. A new slot was introduced in the
|
||||
<tt>PyTypeObject</tt> structure: <tt>tp_richcompare</tt>. For backwards
|
||||
compatibility, a flag (<tt>Py_TPFLAGS_HAVE_RICHCOMPARE</tt>) has to be
|
||||
set to signal to the Python interpreter that Rich Comparisions are
|
||||
supported by a particular type.
|
||||
There is only one flag for all the six comparison operators.
|
||||
When any of the six operators is wrapped automatically or
|
||||
manually, Boost.Python will set this flag. Attempts to use comparison
|
||||
operators at the Python level that are not defined at the C++ level
|
||||
will then lead to an <tt>AttributeError</tt> when the Python 2.1
|
||||
(or higher) interpreter tries, e.g., <tt>a.__lt__(b)</tt>. That
|
||||
is, in general all six operators should be supplied. Automatically
|
||||
wrapped operators and manually wrapped operators can be mixed. For
|
||||
example:<pre>
|
||||
boost::python::class_builder<code> py_code(this_module, "code");
|
||||
|
||||
py_code.def(boost::python::constructor<>());
|
||||
py_code.def(boost::python::constructor<int>());
|
||||
py_code.def(boost::python::operators<( boost::python::op_eq
|
||||
| boost::python::op_ne)>());
|
||||
py_code.def(NotImplemented, "__lt__");
|
||||
py_code.def(NotImplemented, "__le__");
|
||||
py_code.def(NotImplemented, "__gt__");
|
||||
py_code.def(NotImplemented, "__ge__");
|
||||
</pre>
|
||||
|
||||
<tt>NotImplemented</tt> is a simple free function that (currently) has
|
||||
to be provided by the user. For example:<pre>
|
||||
boost::python::ref
|
||||
NotImplemented(const code&, const code&) {
|
||||
return
|
||||
boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count);
|
||||
}
|
||||
</pre>
|
||||
|
||||
See also:
|
||||
<ul>
|
||||
<li><a href="../example/richcmp1.cpp"><tt>../example/richcmp1.cpp</tt></a>
|
||||
<li><a href="../example/richcmp2.cpp"><tt>../example/richcmp2.cpp</tt></a>
|
||||
<li><a href="../example/richcmp3.cpp"><tt>../example/richcmp3.cpp</tt></a>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
© Copyright Nicholas K. Sauter & 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: July 2001
|
||||
|
||||
</div>
|
||||
@@ -60,27 +60,13 @@
|
||||
<b><tt class='method'>__str__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
Create a string representation which is suitable for printing.
|
||||
<dt>
|
||||
<b><tt class='method'>__lt__</tt></b>(<i>self, other</i>)
|
||||
<dt>
|
||||
<b><tt class='method'>__le__</tt></b>(<i>self, other</i>)
|
||||
<dt>
|
||||
<b><tt class='method'>__eq__</tt></b>(<i>self, other</i>)
|
||||
<dt>
|
||||
<b><tt class='method'>__ne__</tt></b>(<i>self, other</i>)
|
||||
<dt>
|
||||
<b><tt class='method'>__gt__</tt></b>(<i>self, other</i>)
|
||||
<dt>
|
||||
<b><tt class='method'>__ge__</tt></b>(<i>self, other</i>)
|
||||
<dd>
|
||||
Rich Comparison methods.
|
||||
New in Python 2.1.
|
||||
See <a href="richcmp.html">Rich Comparisons</a>.
|
||||
<dt>
|
||||
<b><tt class='method'>__cmp__</tt></b>(<i>self, other</i>)
|
||||
<dd>
|
||||
Three-way compare function.
|
||||
See <a href="richcmp.html">Rich Comparisons</a>.
|
||||
Three-way compare function, used to implement comparison operators
|
||||
(< etc.) Should return a negative integer if <code> self < other
|
||||
</code> , zero if <code> self == other </code> , a positive integer if
|
||||
<code> self > other </code>.
|
||||
<dt>
|
||||
<b><tt class='method'>__hash__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
@@ -287,35 +273,6 @@ bignum_class.def(&rmod, "__rmod__");
|
||||
found first (be it ``<code>int</code>`` or ``<code>float</code>'') will be
|
||||
used for either of the two types.
|
||||
|
||||
<h3><a name="inplace">Inplace Operators</a></h3>
|
||||
<p>
|
||||
Boost.Python can also be used to expose inplace numeric operations
|
||||
(i.e., <code>+=</code> and so forth). These operators must be wrapped
|
||||
manually, as described in the previous section. For example, suppose
|
||||
the class BigNum has an <code>operator+=</code>:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum& operator+= (BigNum const& right);
|
||||
</pre></blockquote>
|
||||
|
||||
This can be exposed by first writing a wrapper function:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum& iadd (BigNum& self, const BigNum& right)
|
||||
{
|
||||
return self += right;
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
and then exposing the wrapper with
|
||||
|
||||
<blockquote><pre>
|
||||
bignum_class.def(&iadd, "__iadd__");
|
||||
</pre></blockquote>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3><a name="coercion">Coercion</a></h3>
|
||||
|
||||
|
||||
@@ -587,42 +544,17 @@ Note that "__rrpow__" is an extension not present in plain Python.
|
||||
<code>__cmp__, __rcmp__</code>
|
||||
<td>
|
||||
<code>cmp(left, right)</code><br>
|
||||
<br>See <a href="richcmp.html">Rich Comparisons</a>.
|
||||
<code>left < right</code><br>
|
||||
<code>left <= right</code><br>
|
||||
<code>left > right</code><br>
|
||||
<code>left >= right</code><br>
|
||||
<code>left == right</code><br>
|
||||
<code>left != right</code>
|
||||
<td>
|
||||
<code>op_cmp</code>
|
||||
<td>
|
||||
<code>cpp_left < cpp_right </code>
|
||||
<br><code>cpp_right < cpp_left</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__lt__</code>
|
||||
<br><code>__le__</code>
|
||||
<br><code>__eq__</code>
|
||||
<br><code>__ne__</code>
|
||||
<br><code>__gt__</code>
|
||||
<br><code>__ge__</code>
|
||||
<td>
|
||||
<code>left < right</code>
|
||||
<br><code>left <= right</code>
|
||||
<br><code>left == right</code>
|
||||
<br><code>left != right</code>
|
||||
<br><code>left > right</code>
|
||||
<br><code>left >= right</code>
|
||||
<br>See <a href="richcmp.html">Rich Comparisons</a>
|
||||
<td>
|
||||
<code>op_lt</code>
|
||||
<br><code>op_le</code>
|
||||
<br><code>op_eq</code>
|
||||
<br><code>op_ne</code>
|
||||
<br><code>op_gt</code>
|
||||
<br><code>op_ge</code>
|
||||
<td>
|
||||
<code>cpp_left < cpp_right </code>
|
||||
<br><code>cpp_left <= cpp_right </code>
|
||||
<br><code>cpp_left == cpp_right </code>
|
||||
<br><code>cpp_left != cpp_right </code>
|
||||
<br><code>cpp_left > cpp_right </code>
|
||||
<br><code>cpp_left >= cpp_right </code>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
"example1.html#world_class"><code>extension_class<T></code></a>
|
||||
template defines a whole raft of these conversions (for <code>T, T*,
|
||||
T&, std::auto_ptr<T></code>, etc.), using the same inline
|
||||
friend function technique employed by <a href="../../utility/operators.htm">the boost operators
|
||||
friend function technique employed by <a href=
|
||||
"http://www.boost.org/libs/utility/operators.htm">the boost operators
|
||||
library</a>.
|
||||
<p>
|
||||
Because the <code>to_python</code> and <code>from_python</code> functions
|
||||
|
||||
@@ -10,7 +10,7 @@ See also: libs/python/doc/pickle.html
|
||||
Other advanced concepts are introduced by:
|
||||
abstract.cpp
|
||||
simple_vector.cpp
|
||||
do_it_yourself_convts.cpp
|
||||
do_it_yourself_converters.cpp
|
||||
|
||||
Examples for the cross-module support are provided by:
|
||||
noncopyable_export.cpp
|
||||
|
||||
@@ -105,10 +105,12 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts)
|
||||
BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("do_it_yourself_convts");
|
||||
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");
|
||||
@@ -118,4 +120,9 @@ BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts)
|
||||
// Add the member functions.
|
||||
ixset_class.def(&IndexingSet::add, "add");
|
||||
ixset_class.def(&IndexingSet::get, "get");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
@@ -20,18 +20,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||
# include <windows.h>
|
||||
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
= _set_se_translator(structured_exception_translator);
|
||||
# endif
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(dvect)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("dvect");
|
||||
|
||||
python::class_builder<vects::dvect> dvect_class(this_module, "dvect");
|
||||
@@ -45,4 +37,9 @@ BOOST_PYTHON_MODULE_INIT(dvect)
|
||||
|
||||
# include "dvect_defs.cpp"
|
||||
# include "ivect_defs.cpp"
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace vects {
|
||||
struct dvect : public std::vector<double>
|
||||
{
|
||||
dvect() : std::vector<double>() {}
|
||||
dvect(std::size_t n) : std::vector<double>(n) {}
|
||||
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();
|
||||
|
||||
@@ -16,21 +16,32 @@ namespace hello {
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE_INIT(hello)
|
||||
extern "C"
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void inithello()
|
||||
{
|
||||
// create an object representing this extension module
|
||||
boost::python::module_builder hello("hello");
|
||||
try
|
||||
{
|
||||
// create an object representing this extension module
|
||||
boost::python::module_builder hello("hello");
|
||||
|
||||
// Create the Python type object for our extension class
|
||||
boost::python::class_builder<hello::world> world_class(hello, "world");
|
||||
// Create the Python type object for our extension class
|
||||
boost::python::class_builder<hello::world> world_class(hello, "world");
|
||||
|
||||
// Add the __init__ function
|
||||
world_class.def(boost::python::constructor<int>());
|
||||
// Add a regular member function
|
||||
world_class.def(&hello::world::get, "get");
|
||||
// Add the __init__ function
|
||||
world_class.def(boost::python::constructor<int>());
|
||||
// Add a regular member function
|
||||
world_class.def(&hello::world::get, "get");
|
||||
|
||||
// Add a regular function to the module
|
||||
hello.def(hello::length, "length");
|
||||
// Add a regular function to the module
|
||||
hello.def(hello::length, "length");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
// Win32 DLL boilerplate
|
||||
|
||||
@@ -16,10 +16,17 @@ namespace python = boost::python;
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started1");
|
||||
|
||||
// Add regular functions to the module.
|
||||
this_module.def(greet, "greet");
|
||||
this_module.def(square, "square");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace python = boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started2");
|
||||
|
||||
@@ -42,4 +44,9 @@ BOOST_PYTHON_MODULE_INIT(getting_started2)
|
||||
|
||||
// Even better, invite() can also be made a member of hello_class!!!
|
||||
hello_class.def(invite, "invite");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,18 +20,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||
# include <windows.h>
|
||||
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
= _set_se_translator(structured_exception_translator);
|
||||
# endif
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(ivect)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("ivect");
|
||||
|
||||
python::class_builder<vects::ivect> ivect_class(this_module, "ivect");
|
||||
@@ -45,5 +37,9 @@ BOOST_PYTHON_MODULE_INIT(ivect)
|
||||
|
||||
# include "dvect_defs.cpp"
|
||||
# include "ivect_defs.cpp"
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace vects {
|
||||
struct ivect : public std::vector<int>
|
||||
{
|
||||
ivect() : std::vector<int>() {}
|
||||
ivect(std::size_t n) : std::vector<int>(n) {}
|
||||
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();
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
/*
|
||||
This example shows how convert a nested Python tuple.
|
||||
*/
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace {
|
||||
|
||||
boost::python::list
|
||||
show_nested_tuples(boost::python::tuple outer)
|
||||
{
|
||||
boost::python::list result;
|
||||
for (int i = 0; i < outer.size(); i++) {
|
||||
boost::python::tuple inner(
|
||||
BOOST_PYTHON_CONVERSION::from_python(outer[i].get(),
|
||||
boost::python::type<boost::python::tuple>()));
|
||||
for (int j = 0; j < inner.size(); j++) {
|
||||
double x = BOOST_PYTHON_CONVERSION::from_python(inner[j].get(),
|
||||
boost::python::type<double>());
|
||||
char buf[128];
|
||||
sprintf(buf, "(%d,%d) %.6g", i, j, x);
|
||||
result.append(BOOST_PYTHON_CONVERSION::to_python(std::string(buf)));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(nested)
|
||||
{
|
||||
boost::python::module_builder this_module("nested");
|
||||
this_module.def(show_nested_tuples, "show_nested_tuples");
|
||||
}
|
||||
@@ -6,18 +6,10 @@ namespace python = boost::python;
|
||||
|
||||
#include "noncopyable.h"
|
||||
|
||||
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||
# include <windows.h>
|
||||
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
= _set_se_translator(structured_exception_translator);
|
||||
# endif
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(noncopyable_export)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("noncopyable_export");
|
||||
|
||||
python::class_builder<store> store_class(this_module, "store");
|
||||
@@ -25,4 +17,9 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_export)
|
||||
|
||||
store_class.def(python::constructor<int>());
|
||||
store_class.def(&store::recall, "recall");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,18 +19,10 @@ namespace { // Avoid cluttering the global namespace.
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||
# include <windows.h>
|
||||
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||
= _set_se_translator(structured_exception_translator);
|
||||
# endif
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(noncopyable_import)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("noncopyable_import");
|
||||
|
||||
python::import_converters<store>
|
||||
@@ -42,4 +34,9 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_import)
|
||||
// However, to keep this example simple, we only define a
|
||||
// module-level function.
|
||||
this_module.def(add_stores, "add_stores");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle1");
|
||||
|
||||
@@ -54,4 +56,9 @@ BOOST_PYTHON_MODULE_INIT(pickle1)
|
||||
|
||||
// Support for pickle.
|
||||
world_class.def(world_getinitargs, "__getinitargs__");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,8 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle2");
|
||||
|
||||
@@ -90,4 +92,9 @@ BOOST_PYTHON_MODULE_INIT(pickle2)
|
||||
world_class.def(world_getinitargs, "__getinitargs__");
|
||||
world_class.def(world_getstate, "__getstate__");
|
||||
world_class.def(world_setstate, "__setstate__");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(pickle3)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("pickle3");
|
||||
|
||||
@@ -83,6 +85,11 @@ BOOST_PYTHON_MODULE_INIT(pickle3)
|
||||
world_class.def_raw(world_getstate, "__getstate__");
|
||||
world_class.def_raw(world_setstate, "__setstate__");
|
||||
world_class.getstate_manages_dict();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -99,7 +106,7 @@ namespace {
|
||||
{
|
||||
if(args.size() != 1 || keywords.size() != 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw boost::python::error_already_set();
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
const world& w = from_python(args[0].get(), type<const world&>());
|
||||
ref mydict = getattr(args[0], "__dict__");
|
||||
@@ -115,7 +122,7 @@ namespace {
|
||||
{
|
||||
if(args.size() != 2 || keywords.size() != 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw boost::python::error_already_set();
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
world& w = from_python(args[0].get(), type<world&>());
|
||||
ref mydict = getattr(args[0], "__dict__");
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter
|
||||
// This example shows how to use rich comparisons for a vector type.
|
||||
// It also shows how to template the entire wrapping of a std::vector.
|
||||
// See vector_wrapper.h.
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
#include "vector_wrapper.h"
|
||||
|
||||
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 (std::size_t i = 0; i < tuple.size(); i++)
|
||||
v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(),
|
||||
boost::python::type<double>());
|
||||
}
|
||||
|
||||
boost::python::tuple as_tuple() const
|
||||
{
|
||||
boost::python::tuple t(size());
|
||||
for (std::size_t i = 0; i < size(); i++)
|
||||
t.set_item(i,
|
||||
boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i])));
|
||||
return t;
|
||||
}
|
||||
|
||||
# define DVECT_BINARY_OPERATORS(oper) \
|
||||
friend std::vector<bool> \
|
||||
operator##oper(const dvect& lhs, const dvect& rhs) \
|
||||
{ \
|
||||
if (lhs.size() != rhs.size()) { \
|
||||
PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \
|
||||
throw boost::python::error_already_set(); \
|
||||
} \
|
||||
std::vector<bool> result(lhs.size()); \
|
||||
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||
result[i] = (lhs[i] ##oper rhs[i]); \
|
||||
} \
|
||||
return result; \
|
||||
}
|
||||
DVECT_BINARY_OPERATORS(<)
|
||||
DVECT_BINARY_OPERATORS(<=)
|
||||
DVECT_BINARY_OPERATORS(==)
|
||||
DVECT_BINARY_OPERATORS(!=)
|
||||
DVECT_BINARY_OPERATORS(>)
|
||||
DVECT_BINARY_OPERATORS(>=)
|
||||
# undef VECTOR_BINARY_OPERATORS
|
||||
};
|
||||
|
||||
} // namespace <anonymous>
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void init_module(boost::python::module_builder& this_module)
|
||||
{
|
||||
(void) example::wrap_vector(this_module, "vector_of_bool", bool());
|
||||
|
||||
boost::python::class_builder<vects::dvect> py_dvect(this_module, "dvect");
|
||||
|
||||
py_dvect.def(boost::python::constructor<boost::python::tuple>());
|
||||
py_dvect.def(&vects::dvect::as_tuple, "as_tuple");
|
||||
|
||||
const long
|
||||
comp_operators = ( boost::python::op_lt | boost::python::op_le
|
||||
| boost::python::op_eq | boost::python::op_ne
|
||||
| boost::python::op_gt | boost::python::op_ge);
|
||||
py_dvect.def(boost::python::operators<comp_operators>());
|
||||
}
|
||||
|
||||
} // namespace <anonymous>
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(richcmp1)
|
||||
{
|
||||
boost::python::module_builder this_module("richcmp1");
|
||||
// The actual work is done in a separate function in order
|
||||
// to suppress a bogus VC60 warning.
|
||||
init_module(this_module);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
// This example shows how to use rich comparisons for a type that
|
||||
// does not support all six operators (<, <=, ==, !=, >, >=).
|
||||
// To keep the example simple, we are using a "code" type does
|
||||
// not really require rich comparisons. __cmp__ would be sufficient.
|
||||
// However, with a more complicated type the main point of this
|
||||
// example would be in danger of getting lost.
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
// suppose operator< and operator> are not meaningful for code
|
||||
class code {
|
||||
public:
|
||||
code(int c = 0) : m_code(c) {}
|
||||
inline friend bool operator==(const code& lhs, const code& rhs) {
|
||||
return lhs.m_code == rhs.m_code;
|
||||
}
|
||||
inline friend bool operator!=(const code& lhs, const code& rhs) {
|
||||
return lhs.m_code != rhs.m_code;
|
||||
}
|
||||
private:
|
||||
int m_code;
|
||||
};
|
||||
|
||||
#if PYTHON_API_VERSION >= 1010
|
||||
boost::python::ref
|
||||
NotImplemented(const code&, const code&) {
|
||||
return
|
||||
boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void init_module(boost::python::module_builder& this_module)
|
||||
{
|
||||
boost::python::class_builder<code> py_code(this_module, "code");
|
||||
|
||||
py_code.def(boost::python::constructor<>());
|
||||
py_code.def(boost::python::constructor<int>());
|
||||
py_code.def(boost::python::operators<( boost::python::op_eq
|
||||
| boost::python::op_ne)>());
|
||||
#if PYTHON_API_VERSION >= 1010
|
||||
py_code.def(NotImplemented, "__lt__");
|
||||
py_code.def(NotImplemented, "__le__");
|
||||
py_code.def(NotImplemented, "__gt__");
|
||||
py_code.def(NotImplemented, "__ge__");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace <anonymous>
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(richcmp2)
|
||||
{
|
||||
boost::python::module_builder this_module("richcmp2");
|
||||
// The actual work is done in a separate function in order
|
||||
// to suppress a bogus VC60 warning.
|
||||
init_module(this_module);
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter.
|
||||
// Comprehensive operator overloading for two vector types and scalars.
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
#include "vector_wrapper.h"
|
||||
#include "dvect.h"
|
||||
#include "ivect.h"
|
||||
|
||||
#define VECT_VECT_OPERATORS(result_type, vect_type1, oper, vect_type2) \
|
||||
namespace vects { \
|
||||
result_type \
|
||||
operator##oper (const vect_type1& lhs, const vect_type2& rhs) { \
|
||||
if (lhs.size() != rhs.size()) { \
|
||||
PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \
|
||||
throw boost::python::error_already_set(); \
|
||||
} \
|
||||
result_type result(lhs.size()); \
|
||||
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||
result[i] = (lhs[i] ##oper rhs[i]); \
|
||||
} \
|
||||
return result; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define VECT_SCALAR_OPERATORS(result_type, vect_type, oper, scalar_type) \
|
||||
namespace vects { \
|
||||
result_type \
|
||||
operator##oper (const vect_type& lhs, const scalar_type& rhs) { \
|
||||
result_type result(lhs.size()); \
|
||||
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||
result[i] = (lhs[i] ##oper rhs ); \
|
||||
} \
|
||||
return result; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SCALAR_VECT_OPERATORS(result_type, scalar_type, oper, vect_type) \
|
||||
namespace vects { \
|
||||
result_type \
|
||||
operator##oper (const scalar_type& lhs, const vect_type& rhs) { \
|
||||
result_type result(rhs.size()); \
|
||||
for (std::size_t i=0; i<rhs.size(); i++) { \
|
||||
result[i] = (lhs ##oper rhs[i]); \
|
||||
} \
|
||||
return result; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define MATH_VECT_VECT_OPERATORS(result_type, vect_type1, vect_type2) \
|
||||
VECT_VECT_OPERATORS(result_type, vect_type1, +, vect_type2) \
|
||||
VECT_VECT_OPERATORS(result_type, vect_type1, -, vect_type2) \
|
||||
VECT_VECT_OPERATORS(result_type, vect_type1, *, vect_type2) \
|
||||
VECT_VECT_OPERATORS(result_type, vect_type1, /, vect_type2)
|
||||
|
||||
#define COMP_VECT_VECT_OPERATORS(vect_type1, vect_type2) \
|
||||
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, <, vect_type2) \
|
||||
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, <=, vect_type2) \
|
||||
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, ==, vect_type2) \
|
||||
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, !=, vect_type2) \
|
||||
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, >, vect_type2) \
|
||||
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, >=, vect_type2)
|
||||
|
||||
#define MATH_VECT_SCALAR_OPERATORS(result_type, vect_type, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(result_type, vect_type, +, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(result_type, vect_type, -, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(result_type, vect_type, *, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(result_type, vect_type, /, scalar_type)
|
||||
|
||||
#define COMP_VECT_SCALAR_OPERATORS(vect_type, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, <, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, <=, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, ==, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, !=, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, >, scalar_type) \
|
||||
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, >=, scalar_type)
|
||||
|
||||
#define MATH_SCALAR_VECT_OPERATORS(result_type, scalar_type, vect_type) \
|
||||
SCALAR_VECT_OPERATORS(result_type, scalar_type, +, vect_type) \
|
||||
SCALAR_VECT_OPERATORS(result_type, scalar_type, -, vect_type) \
|
||||
SCALAR_VECT_OPERATORS(result_type, scalar_type, *, vect_type) \
|
||||
SCALAR_VECT_OPERATORS(result_type, scalar_type, /, vect_type)
|
||||
|
||||
MATH_VECT_VECT_OPERATORS(dvect, dvect, dvect)
|
||||
COMP_VECT_VECT_OPERATORS( dvect, dvect)
|
||||
MATH_VECT_SCALAR_OPERATORS(dvect, dvect, double)
|
||||
COMP_VECT_SCALAR_OPERATORS( dvect, double)
|
||||
MATH_SCALAR_VECT_OPERATORS(dvect, double, dvect)
|
||||
// comparison operators not needed since Python uses reflection
|
||||
|
||||
MATH_VECT_VECT_OPERATORS(ivect, ivect, ivect)
|
||||
COMP_VECT_VECT_OPERATORS( ivect, ivect)
|
||||
MATH_VECT_SCALAR_OPERATORS(ivect, ivect, int)
|
||||
COMP_VECT_SCALAR_OPERATORS( ivect, int)
|
||||
MATH_SCALAR_VECT_OPERATORS(ivect, int, ivect)
|
||||
// comparison operators not needed since Python uses reflection
|
||||
|
||||
MATH_VECT_VECT_OPERATORS(dvect, dvect, ivect)
|
||||
COMP_VECT_VECT_OPERATORS( dvect, ivect)
|
||||
MATH_VECT_VECT_OPERATORS(dvect, ivect, dvect)
|
||||
COMP_VECT_VECT_OPERATORS( ivect, dvect)
|
||||
|
||||
#undef VECT_VECT_OPERATORS
|
||||
#undef SCALAR_VECT_OPERATORS
|
||||
#undef VECT_SCALAR_OPERATORS
|
||||
#undef MATH_VECT_VECT_OPERATORS
|
||||
#undef COMP_VECT_VECT_OPERATORS
|
||||
#undef MATH_VECT_SCALAR_OPERATORS
|
||||
#undef COMP_VECT_SCALAR_OPERATORS
|
||||
#undef MATH_SCALAR_VECT_OPERATORS
|
||||
|
||||
namespace {
|
||||
|
||||
void init_module(boost::python::module_builder& this_module)
|
||||
{
|
||||
(void) example::wrap_vector(this_module, "vector_of_bool", bool());
|
||||
|
||||
const long
|
||||
math_operators ( boost::python::op_mul | boost::python::op_add
|
||||
| boost::python::op_div | boost::python::op_sub);
|
||||
const long
|
||||
comp_operators = ( boost::python::op_lt | boost::python::op_le
|
||||
| boost::python::op_eq | boost::python::op_ne
|
||||
| boost::python::op_gt | boost::python::op_ge);
|
||||
|
||||
boost::python::class_builder<vects::dvect>
|
||||
dvect_class(this_module, "dvect");
|
||||
boost::python::class_builder<vects::ivect>
|
||||
ivect_class(this_module, "ivect");
|
||||
|
||||
dvect_class.def(boost::python::constructor<boost::python::tuple>());
|
||||
dvect_class.def(&vects::dvect::as_tuple,"as_tuple");
|
||||
|
||||
dvect_class.def(boost::python::operators<math_operators>());
|
||||
dvect_class.def(boost::python::operators<math_operators>(),
|
||||
boost::python::right_operand<double>() );
|
||||
dvect_class.def(boost::python::operators<math_operators>(),
|
||||
boost::python::left_operand<double>() );
|
||||
dvect_class.def(boost::python::operators<math_operators>(),
|
||||
boost::python::right_operand<vects::ivect>() );
|
||||
|
||||
dvect_class.def(boost::python::operators<comp_operators>());
|
||||
dvect_class.def(boost::python::operators<comp_operators>(),
|
||||
boost::python::right_operand<double>() );
|
||||
// left_operand not needed since Python uses reflection
|
||||
dvect_class.def(boost::python::operators<comp_operators>(),
|
||||
boost::python::right_operand<vects::ivect>() );
|
||||
|
||||
ivect_class.def(boost::python::constructor<boost::python::tuple>());
|
||||
ivect_class.def(&vects::ivect::as_tuple,"as_tuple");
|
||||
|
||||
ivect_class.def(boost::python::operators<math_operators>());
|
||||
ivect_class.def(boost::python::operators<math_operators>(),
|
||||
boost::python::right_operand<int>() );
|
||||
ivect_class.def(boost::python::operators<math_operators>(),
|
||||
boost::python::left_operand<int>() );
|
||||
ivect_class.def(boost::python::operators<math_operators>(),
|
||||
boost::python::right_operand<vects::dvect>() );
|
||||
|
||||
ivect_class.def(boost::python::operators<comp_operators>());
|
||||
ivect_class.def(boost::python::operators<comp_operators>(),
|
||||
boost::python::right_operand<int>() );
|
||||
// left_operand not needed since Python uses reflection
|
||||
ivect_class.def(boost::python::operators<comp_operators>(),
|
||||
boost::python::right_operand<vects::dvect>() );
|
||||
}
|
||||
|
||||
} // namespace <anonymous>
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(richcmp3)
|
||||
{
|
||||
boost::python::module_builder this_module("richcmp3");
|
||||
// The actual work is done in a separate function in order
|
||||
// to suppress a bogus VC60 warning.
|
||||
init_module(this_module);
|
||||
}
|
||||
@@ -13,12 +13,29 @@ namespace python = boost::python;
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE_INIT(rwgk1)
|
||||
extern "C"
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void initrwgk1()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("rwgk1");
|
||||
|
||||
// Add regular functions to the module.
|
||||
this_module.def(greet, "greet");
|
||||
this_module.def(square, "square");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
// Win32 DLL boilerplate
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; }
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace { // Avoid cluttering the global namespace.
|
||||
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.
|
||||
@@ -85,13 +85,15 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(simple_vector)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder this_module("simple_vector");
|
||||
|
||||
python::class_builder<std::vector<double>, vector_double_wrapper>
|
||||
vector_double(this_module, "vector_double");
|
||||
|
||||
vector_double.def(python::constructor<>());
|
||||
vector_double.def(python::constructor<int>());
|
||||
vector_double.def(python::constructor<const int>());
|
||||
vector_double.def(python::constructor<python::tuple>());
|
||||
vector_double.def(&std::vector<double>::size, "__len__");
|
||||
vector_double.def(getitem, "__getitem__");
|
||||
@@ -101,4 +103,9 @@ BOOST_PYTHON_MODULE_INIT(simple_vector)
|
||||
|
||||
this_module.def(foo, "foo");
|
||||
this_module.def(bar, "bar");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_abstract
|
||||
return doctest.testmod(test_abstract)
|
||||
doctest.testmod(test_abstract)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
run()
|
||||
|
||||
@@ -133,8 +133,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_cross_module
|
||||
return doctest.testmod(test_cross_module)
|
||||
doctest.testmod(test_cross_module)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
run()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
r'''>>> import do_it_yourself_convts
|
||||
>>> ixset = do_it_yourself_convts.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,9 +15,8 @@ def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_do_it_yourself_convts
|
||||
return doctest.testmod(test_do_it_yourself_convts)
|
||||
import doctest, test_do_it_yourself_converters
|
||||
doctest.testmod(test_do_it_yourself_converters)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
run()
|
||||
@@ -44,8 +44,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_example1
|
||||
return doctest.testmod(test_example1)
|
||||
doctest.testmod(test_example1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
run()
|
||||
|
||||
@@ -11,8 +11,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started1
|
||||
return doctest.testmod(test_getting_started1)
|
||||
doctest.testmod(test_getting_started1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
run()
|
||||
|
||||
@@ -23,9 +23,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started2
|
||||
return doctest.testmod(test_getting_started2)
|
||||
doctest.testmod(test_getting_started2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
run()
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
r'''>>> import nested
|
||||
>>> s = nested.show_nested_tuples(((1,2,3), (4,5,6,7)))
|
||||
>>> for l in s:
|
||||
... print l
|
||||
(0,0) 1
|
||||
(0,1) 2
|
||||
(0,2) 3
|
||||
(1,0) 4
|
||||
(1,1) 5
|
||||
(1,2) 6
|
||||
(1,3) 7
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_nested
|
||||
return doctest.testmod(test_nested)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
@@ -25,9 +25,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_pickle1
|
||||
return doctest.testmod(test_pickle1)
|
||||
doctest.testmod(test_pickle1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
run()
|
||||
|
||||
@@ -39,9 +39,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_pickle2
|
||||
return doctest.testmod(test_pickle2)
|
||||
doctest.testmod(test_pickle2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
run()
|
||||
|
||||
@@ -19,12 +19,12 @@ r'''>>> import pickle3
|
||||
... wd.z = 3. * number
|
||||
... pstr = pickle.dumps(wd)
|
||||
... wl = pickle.loads(pstr)
|
||||
... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z
|
||||
... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z
|
||||
Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0
|
||||
Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0
|
||||
Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0
|
||||
Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0
|
||||
... 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):
|
||||
@@ -32,8 +32,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_pickle3
|
||||
return doctest.testmod(test_pickle3)
|
||||
doctest.testmod(test_pickle3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
run()
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
r'''>>> import richcmp1
|
||||
>>> d1 = richcmp1.dvect((0, 1, 3, 3, 6, 7))
|
||||
>>> d2 = richcmp1.dvect((1, 2, 3, 4, 5, 6))
|
||||
>>> print d1.as_tuple()
|
||||
(0.0, 1.0, 3.0, 3.0, 6.0, 7.0)
|
||||
>>> print d2.as_tuple()
|
||||
(1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
|
||||
>>> print (d1 < d2).as_tuple()
|
||||
(1, 1, 0, 1, 0, 0)
|
||||
>>> print (d1 <= d2).as_tuple()
|
||||
(1, 1, 1, 1, 0, 0)
|
||||
>>> print (d1 == d2).as_tuple()
|
||||
(0, 0, 1, 0, 0, 0)
|
||||
>>> print (d1 != d2).as_tuple()
|
||||
(1, 1, 0, 1, 1, 1)
|
||||
>>> print (d1 > d2).as_tuple()
|
||||
(0, 0, 0, 0, 1, 1)
|
||||
>>> print (d1 >= d2).as_tuple()
|
||||
(0, 0, 1, 0, 1, 1)
|
||||
>>> try: d1 == richcmp1.dvect((1, 2, 3, 4, 5))
|
||||
... except ValueError, e: print str(e)
|
||||
...
|
||||
vectors have different sizes
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_richcmp1
|
||||
return doctest.testmod(test_richcmp1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if ( hasattr(sys, 'version_info')
|
||||
and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1)
|
||||
or sys.version_info[0] > 2)):
|
||||
sys.exit(run()[0])
|
||||
else:
|
||||
print "Python version 2.1 or higher required. Test skipped."
|
||||
@@ -1,41 +0,0 @@
|
||||
r'''>>> import richcmp2
|
||||
>>> c1 = richcmp2.code(1)
|
||||
>>> c2 = richcmp2.code(2)
|
||||
>>> c3 = richcmp2.code(2)
|
||||
>>> print c1 == c2
|
||||
0
|
||||
>>> print c1 != c2
|
||||
1
|
||||
>>> print c2 == c3
|
||||
1
|
||||
>>> print c2 != c3
|
||||
0
|
||||
>>> print c1 < c2
|
||||
1
|
||||
>>> print c1 <= c2
|
||||
1
|
||||
>>> print c1 == c2
|
||||
0
|
||||
>>> print c1 != c2
|
||||
1
|
||||
>>> print c1 > c2
|
||||
0
|
||||
>>> print c1 >= c2
|
||||
0
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_richcmp1
|
||||
return doctest.testmod(test_richcmp1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if ( hasattr(sys, 'version_info')
|
||||
and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1)
|
||||
or sys.version_info[0] > 2)):
|
||||
sys.exit(run()[0])
|
||||
else:
|
||||
print "Python version 2.1 or higher required. Test skipped."
|
||||
@@ -1,77 +0,0 @@
|
||||
r'''>>> import richcmp3
|
||||
>>>
|
||||
>>> iv = richcmp3.ivect((1,2,3,4,5))
|
||||
>>> print iv.as_tuple()
|
||||
(1, 2, 3, 4, 5)
|
||||
>>> dv = richcmp3.dvect((2,-2,3,8,-5))
|
||||
>>> print dv.as_tuple()
|
||||
(2.0, -2.0, 3.0, 8.0, -5.0)
|
||||
>>>
|
||||
>>> print (iv+dv).as_tuple()
|
||||
(3.0, 0.0, 6.0, 12.0, 0.0)
|
||||
>>> print (iv+3).as_tuple()
|
||||
(4, 5, 6, 7, 8)
|
||||
>>> print (3+iv).as_tuple()
|
||||
(4, 5, 6, 7, 8)
|
||||
>>>
|
||||
>>> print "vect vs. vect Comparisons:"
|
||||
vect vs. vect Comparisons:
|
||||
>>> print (iv < dv).as_tuple()
|
||||
(1, 0, 0, 1, 0)
|
||||
>>> print (iv <= dv).as_tuple()
|
||||
(1, 0, 1, 1, 0)
|
||||
>>> print (iv == dv).as_tuple()
|
||||
(0, 0, 1, 0, 0)
|
||||
>>> print (iv != dv).as_tuple()
|
||||
(1, 1, 0, 1, 1)
|
||||
>>> print (iv > dv).as_tuple()
|
||||
(0, 1, 0, 0, 1)
|
||||
>>> print (iv >= dv).as_tuple()
|
||||
(0, 1, 1, 0, 1)
|
||||
>>>
|
||||
>>> print "vect vs. scalar Comparisons:"
|
||||
vect vs. scalar Comparisons:
|
||||
>>> print (iv < 3).as_tuple()
|
||||
(1, 1, 0, 0, 0)
|
||||
>>> print (iv <= 3).as_tuple()
|
||||
(1, 1, 1, 0, 0)
|
||||
>>> print (iv == 3).as_tuple()
|
||||
(0, 0, 1, 0, 0)
|
||||
>>> print (iv != 3).as_tuple()
|
||||
(1, 1, 0, 1, 1)
|
||||
>>> print (iv > 3).as_tuple()
|
||||
(0, 0, 0, 1, 1)
|
||||
>>> print (iv >= 3).as_tuple()
|
||||
(0, 0, 1, 1, 1)
|
||||
>>>
|
||||
>>> print "scalar vs. vect Comparisons:"
|
||||
scalar vs. vect Comparisons:
|
||||
>>> print (3 < iv).as_tuple()
|
||||
(0, 0, 0, 1, 1)
|
||||
>>> print (3 <= iv).as_tuple()
|
||||
(0, 0, 1, 1, 1)
|
||||
>>> print (3 == iv).as_tuple()
|
||||
(0, 0, 1, 0, 0)
|
||||
>>> print (3 != iv).as_tuple()
|
||||
(1, 1, 0, 1, 1)
|
||||
>>> print (3 > iv).as_tuple()
|
||||
(1, 1, 0, 0, 0)
|
||||
>>> print (3 >= iv).as_tuple()
|
||||
(1, 1, 1, 0, 0)
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_richcmp3
|
||||
return doctest.testmod(test_richcmp3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if ( hasattr(sys, 'version_info')
|
||||
and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1)
|
||||
or sys.version_info[0] > 2)):
|
||||
sys.exit(run()[0])
|
||||
else:
|
||||
print "Python version 2.1 or higher required. Test skipped."
|
||||
@@ -11,9 +11,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_rwgk1
|
||||
return doctest.testmod(test_rwgk1)
|
||||
doctest.testmod(test_rwgk1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
run()
|
||||
|
||||
@@ -34,9 +34,7 @@ def run(args = None):
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_simple_vector
|
||||
return doctest.testmod(test_simple_vector)
|
||||
doctest.testmod(test_simple_vector)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
run()
|
||||
|
||||
@@ -87,18 +87,12 @@ if (__name__ == "__main__"):
|
||||
import sys, string
|
||||
broken_auto_ptr = 0
|
||||
n = 1
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
argv = []
|
||||
|
||||
for x in sys.argv:
|
||||
if x != '--broken-auto-ptr':
|
||||
argv.append(x)
|
||||
broken_auto_ptr = argv != sys.argv
|
||||
sys.argv = argv
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
n = string.atoi(sys.argv[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)
|
||||
|
||||
@@ -87,18 +87,12 @@ if (__name__ == "__main__"):
|
||||
import sys, string
|
||||
broken_auto_ptr = 0
|
||||
n = 1
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
argv = []
|
||||
|
||||
for x in sys.argv:
|
||||
if x != '--broken-auto-ptr':
|
||||
argv.append(x)
|
||||
broken_auto_ptr = argv != sys.argv
|
||||
sys.argv = argv
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
n = string.atoi(sys.argv[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)
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
// Based on wrapVector.hh by Mike Owen and Jeff Johnson.
|
||||
// http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/spheral/src/src/BPLWraps/CXXWraps/
|
||||
|
||||
#ifndef BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H
|
||||
#define BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace example {
|
||||
|
||||
// A wrapper is used to define additional constructors. This wrapper
|
||||
// is templated on the template parameter for its corresponding vector.
|
||||
template <typename T>
|
||||
struct vector_wrapper: std::vector<T>
|
||||
{
|
||||
// Tell the compiler how to convert a base class object to
|
||||
// this wrapper object.
|
||||
vector_wrapper(PyObject*,
|
||||
const std::vector<T>& vec):
|
||||
std::vector<T>(vec) {}
|
||||
|
||||
vector_wrapper(PyObject* self):
|
||||
std::vector<T>() {}
|
||||
|
||||
vector_wrapper(PyObject* self,
|
||||
std::size_t n):
|
||||
std::vector<T>(n) {}
|
||||
|
||||
vector_wrapper(PyObject* self,
|
||||
boost::python::tuple tuple):
|
||||
std::vector<T>(tuple.size())
|
||||
{
|
||||
std::vector<T>::iterator vec = begin();
|
||||
for (std::size_t i = 0; i < tuple.size(); i++)
|
||||
vec[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(),
|
||||
boost::python::type<T>());
|
||||
}
|
||||
};
|
||||
|
||||
void raise_vector_IndexError() {
|
||||
PyErr_SetString(PyExc_IndexError, "vector index out of range");
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct vector_access
|
||||
{
|
||||
static
|
||||
T
|
||||
getitem(const std::vector<T>& vec,
|
||||
std::size_t key)
|
||||
{
|
||||
if (key >= vec.size()) raise_vector_IndexError();
|
||||
return vec[key];
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
setitem(std::vector<T>& vec,
|
||||
std::size_t key,
|
||||
const T &value)
|
||||
{
|
||||
if (key >= vec.size()) raise_vector_IndexError();
|
||||
vec[key] = value;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
delitem(std::vector<T>& vec,
|
||||
std::size_t key)
|
||||
{
|
||||
if (key >= vec.size()) raise_vector_IndexError();
|
||||
vec.erase(vec.begin() + key);
|
||||
}
|
||||
|
||||
// Convert vector<T> to a regular Python tuple.
|
||||
static
|
||||
boost::python::tuple
|
||||
as_tuple(const std::vector<T>& vec)
|
||||
{
|
||||
// Create a python type of size vec.size().
|
||||
boost::python::tuple t(vec.size());
|
||||
for (std::size_t i = 0; i < vec.size(); i++) {
|
||||
t.set_item(i,
|
||||
boost::python::ref(BOOST_PYTHON_CONVERSION::to_python(vec[i])));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
// This function will build a vector<T> and add it to the given
|
||||
// module with the given name.
|
||||
template <typename T>
|
||||
boost::python::class_builder<std::vector<T>, vector_wrapper<T> >
|
||||
wrap_vector(boost::python::module_builder& module,
|
||||
const std::string& vector_name,
|
||||
const T&)
|
||||
{
|
||||
// Add the vector<T> to the module.
|
||||
boost::python::class_builder<std::vector<T>, vector_wrapper<T> >
|
||||
py_vector(module, vector_name.c_str());
|
||||
|
||||
// Define constructors and methods for the vector<T>.
|
||||
py_vector.def(boost::python::constructor<>());
|
||||
py_vector.def(boost::python::constructor<std::size_t>());
|
||||
py_vector.def(boost::python::constructor<boost::python::tuple>());
|
||||
py_vector.def(&std::vector<T>::size, "__len__");
|
||||
py_vector.def(&vector_access<T>::getitem, "__getitem__");
|
||||
py_vector.def(&vector_access<T>::setitem, "__setitem__");
|
||||
py_vector.def(&vector_access<T>::delitem, "__delitem__");
|
||||
py_vector.def(&vector_access<T>::as_tuple, "as_tuple");
|
||||
|
||||
return py_vector;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H
|
||||
@@ -1,210 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
//
|
||||
// This work was funded in part by Lawrence Berkeley National Labs
|
||||
//
|
||||
// This file generated for 5-argument member functions and 6-argument free
|
||||
// functions by gen_call.py
|
||||
|
||||
#ifndef CALL_DWA20011214_HPP
|
||||
# define CALL_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/detail/returning.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class R>
|
||||
inline PyObject* call(R (*f)(), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0>
|
||||
inline PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
inline PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CALL_DWA20011214_HPP
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CLASS_DWA200216_HPP
|
||||
# define CLASS_DWA200216_HPP
|
||||
|
||||
# include <boost/python/class_fwd.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/detail/wrap_function.hpp>
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
# include <boost/python/object/class_converters.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
|
||||
namespace // put some convenience classes into the unnamed namespace for the user
|
||||
{
|
||||
// A type list for specifying bases
|
||||
template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) >
|
||||
struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type
|
||||
{};
|
||||
|
||||
// A type list for specifying arguments
|
||||
template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) >
|
||||
struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type
|
||||
{};
|
||||
}
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Forward declarations
|
||||
namespace objects
|
||||
{
|
||||
struct value_holder_generator;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// This is an mpl BinaryMetaFunction object with a runtime behavior,
|
||||
// which is to write the id of the type which is passed as its 2nd
|
||||
// compile-time argument into the iterator pointed to by its runtime
|
||||
// argument
|
||||
struct write_type_id
|
||||
{
|
||||
// The first argument is Ignored because mpl::for_each is still
|
||||
// currently an accumulate (reduce) implementation.
|
||||
template <class Ignored, class T> struct apply
|
||||
{
|
||||
// also an artifact of accumulate-based for_each
|
||||
typedef void type;
|
||||
|
||||
// Here's the runtime behavior
|
||||
static void execute(converter::undecorated_type_id_t** p)
|
||||
{
|
||||
*(*p)++ = converter::undecorated_type_id<T>();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// class_<T,Bases,HolderGenerator>
|
||||
//
|
||||
// This is the primary mechanism through which users will expose
|
||||
// C++ classes to Python. The three template arguments are:
|
||||
//
|
||||
// T - The class being exposed to Python
|
||||
//
|
||||
// Bases - An MPL sequence of base classes
|
||||
//
|
||||
// HolderGenerator -
|
||||
// An optional type generator for the "holder" which
|
||||
// maintains the C++ object inside the Python instance. The
|
||||
// default just holds the object "by-value", but other
|
||||
// holders can be substituted which will hold the C++ object
|
||||
// by smart pointer, for example.
|
||||
//
|
||||
template <
|
||||
class T // class being wrapped
|
||||
, class Bases
|
||||
, class HolderGenerator
|
||||
>
|
||||
class class_ : private objects::class_base
|
||||
{
|
||||
typedef class_<T,Bases,HolderGenerator> self;
|
||||
public:
|
||||
|
||||
// Automatically derive the class name - only works on some
|
||||
// compilers because type_info::name is sometimes mangled (gcc)
|
||||
class_();
|
||||
|
||||
// Construct with the class name. [ Would have used a default
|
||||
// argument but gcc-2.95.2 choked on typeid(T).name() as a default
|
||||
// parameter value]
|
||||
class_(char const* name);
|
||||
|
||||
|
||||
// Wrap a member function or a non-member function which can take
|
||||
// a T, T cv&, or T cv* as its first parameter, or a callable
|
||||
// python object.
|
||||
template <class F>
|
||||
self& def(char const* name, F f)
|
||||
{
|
||||
// Use function::add_to_namespace to achieve overloading if
|
||||
// appropriate.
|
||||
objects::function::add_to_namespace(
|
||||
this->object(), name, ref(detail::wrap_function(f)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Fn, class CallPolicy>
|
||||
self& def(char const* name, Fn fn, CallPolicy policy)
|
||||
{
|
||||
this->def(name, boost::python::make_function(fn, policy));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Define the constructor with the given Args, which should be an
|
||||
// MPL sequence of types.
|
||||
template <class Args>
|
||||
self& def_init(Args const& = Args())
|
||||
{
|
||||
def("__init__", make_constructor<T,Args,HolderGenerator>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Define the default constructor.
|
||||
self& def_init()
|
||||
{
|
||||
this->def_init(mpl::type_list<>::type());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// return the underlying object
|
||||
ref object() const;
|
||||
|
||||
private: // types
|
||||
typedef objects::class_id class_id;
|
||||
|
||||
// A helper class which will contain an array of id objects to be
|
||||
// passed to the base class constructor
|
||||
struct id_vector
|
||||
{
|
||||
typedef objects::class_id class_id;
|
||||
id_vector()
|
||||
{
|
||||
// Stick the derived class id into the first element of the array
|
||||
ids[0] = converter::undecorated_type_id<T>();
|
||||
|
||||
// Write the rest of the elements into succeeding positions.
|
||||
class_id* p = ids + 1;
|
||||
mpl::for_each<Bases, void, detail::write_type_id>::execute(&p);
|
||||
}
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, size = mpl::size<Bases>::value + 1);
|
||||
class_id ids[size];
|
||||
};
|
||||
|
||||
private: // helper functions
|
||||
void initialize_converters();
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
inline class_<T, Bases, HolderGenerator>::class_()
|
||||
: class_base(typeid(T).name(), id_vector::size, id_vector().ids)
|
||||
{
|
||||
// Bring the class converters into existence. This static object
|
||||
// will survive until the shared library this module lives in is
|
||||
// unloaded (that doesn't happen until Python terminates).
|
||||
static objects::class_converters<T,Bases> converters(object());
|
||||
}
|
||||
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
inline class_<T, Bases, HolderGenerator>::class_(char const* name)
|
||||
: class_base(name, id_vector::size, id_vector().ids)
|
||||
{
|
||||
// Bring the class converters into existence. This static object
|
||||
// will survive until the shared library this module lives in is
|
||||
// unloaded (that doesn't happen until Python terminates).
|
||||
static objects::class_converters<T,Bases> converters(object());
|
||||
}
|
||||
|
||||
template <class T, class Bases, class HolderGenerator>
|
||||
inline ref class_<T, Bases, HolderGenerator>::object() const
|
||||
{
|
||||
typedef objects::class_base base;
|
||||
|
||||
return this->base::object();
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_DWA200216_HPP
|
||||
@@ -25,22 +25,6 @@ class class_builder
|
||||
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
template <class OtherT, class OtherU>
|
||||
class_builder(class_builder<OtherT, OtherU>& cls, const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
cls.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
template <class OtherT, class OtherU>
|
||||
class_builder(detail::extension_class<OtherT, OtherU>* cls,
|
||||
const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
cls->set_attribute(name,
|
||||
ref(as_object(m_class.get()), ref::increment_count));
|
||||
}
|
||||
|
||||
~class_builder()
|
||||
{}
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CLASS_FWD_DWA200222_HPP
|
||||
# define CLASS_FWD_DWA200222_HPP
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct empty_list;
|
||||
}
|
||||
|
||||
namespace objects
|
||||
{
|
||||
struct value_holder_generator;
|
||||
}
|
||||
|
||||
template <
|
||||
class T // class being wrapped
|
||||
, class Bases = detail::empty_list
|
||||
, class HolderGenerator = objects::value_holder_generator
|
||||
>
|
||||
class class_;
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_FWD_DWA200222_HPP
|
||||
@@ -20,7 +20,7 @@
|
||||
namespace boost { namespace python {
|
||||
|
||||
// A simple type which acts something like a built-in Python class obj.
|
||||
class BOOST_PYTHON_DECL instance
|
||||
class instance
|
||||
: public boost::python::detail::python_object
|
||||
{
|
||||
public:
|
||||
@@ -70,27 +70,6 @@ class BOOST_PYTHON_DECL instance
|
||||
PyObject* oct();
|
||||
PyObject* hex();
|
||||
|
||||
// Rich comparisons
|
||||
PyObject* lt(PyObject* other);
|
||||
PyObject* le(PyObject* other);
|
||||
PyObject* eq(PyObject* other);
|
||||
PyObject* ne(PyObject* other);
|
||||
PyObject* gt(PyObject* other);
|
||||
PyObject* ge(PyObject* other);
|
||||
|
||||
// Inplace operations.
|
||||
PyObject* inplace_add(PyObject* other);
|
||||
PyObject* inplace_subtract(PyObject* other);
|
||||
PyObject* inplace_multiply(PyObject* other);
|
||||
PyObject* inplace_divide(PyObject* other);
|
||||
PyObject* inplace_remainder(PyObject* other);
|
||||
PyObject* inplace_power(PyObject* exponent, PyObject* modulus);
|
||||
PyObject* inplace_lshift(PyObject* other);
|
||||
PyObject* inplace_rshift(PyObject* other);
|
||||
PyObject* inplace_and(PyObject* other);
|
||||
PyObject* inplace_or(PyObject* other);
|
||||
PyObject* inplace_xor(PyObject* other);
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
instance(const instance&);
|
||||
void operator=(const instance&);
|
||||
@@ -105,7 +84,7 @@ class BOOST_PYTHON_DECL instance
|
||||
template <class T> class meta_class;
|
||||
|
||||
namespace detail {
|
||||
class BOOST_PYTHON_DECL class_base : public type_object_base
|
||||
class class_base : public type_object_base
|
||||
{
|
||||
public:
|
||||
class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space);
|
||||
@@ -128,10 +107,6 @@ namespace detail {
|
||||
|
||||
private: // boost::python::type_object_base required interface implementation
|
||||
void instance_dealloc(PyObject*) const; // subclasses should not override this
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
class_base(const class_base&);
|
||||
void operator=(const class_base&);
|
||||
|
||||
private:
|
||||
string m_name;
|
||||
@@ -145,12 +120,11 @@ namespace detail {
|
||||
// A type which acts a lot like a built-in Python class. T is the obj type,
|
||||
// so class_t<instance> is a very simple "class-alike".
|
||||
template <class T>
|
||||
class BOOST_PYTHON_DECL_TEMPLATE class_t
|
||||
class class_t
|
||||
: public boost::python::detail::class_base
|
||||
{
|
||||
public:
|
||||
class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space);
|
||||
~class_t();
|
||||
|
||||
// Standard Python functions.
|
||||
PyObject* call(PyObject* args, PyObject* keywords);
|
||||
@@ -195,26 +169,6 @@ class BOOST_PYTHON_DECL_TEMPLATE class_t
|
||||
PyObject* instance_number_float(PyObject*) const;
|
||||
PyObject* instance_number_oct(PyObject*) const;
|
||||
PyObject* instance_number_hex(PyObject*) const;
|
||||
|
||||
PyObject* instance_number_inplace_add(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_and(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_or(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const;
|
||||
|
||||
private: // Implement rich comparisons
|
||||
PyObject* instance_lt(PyObject*, PyObject*) const;
|
||||
PyObject* instance_le(PyObject*, PyObject*) const;
|
||||
PyObject* instance_eq(PyObject*, PyObject*) const;
|
||||
PyObject* instance_ne(PyObject*, PyObject*) const;
|
||||
PyObject* instance_gt(PyObject*, PyObject*) const;
|
||||
PyObject* instance_ge(PyObject*, PyObject*) const;
|
||||
|
||||
private: // Miscellaneous "special" methods
|
||||
PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const;
|
||||
@@ -223,11 +177,15 @@ class BOOST_PYTHON_DECL_TEMPLATE class_t
|
||||
|
||||
private: // Implementation of boost::python::detail::class_base required interface
|
||||
void delete_instance(PyObject*) const;
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
class_t(const class_t<T>&);
|
||||
void operator=(const class_t&);
|
||||
};
|
||||
|
||||
// The type of a class_t<T> object.
|
||||
template <class T>
|
||||
class BOOST_PYTHON_DECL_TEMPLATE meta_class
|
||||
class meta_class
|
||||
: public boost::python::detail::reprable<
|
||||
boost::python::detail::callable<
|
||||
boost::python::detail::getattrable<
|
||||
@@ -265,11 +223,6 @@ class_t<T>::class_t(meta_class<T>* meta_class_obj, string name, tuple bases, con
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class_t<T>::~class_t()
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void class_t<T>::delete_instance(PyObject* obj) const
|
||||
{
|
||||
@@ -350,7 +303,7 @@ int class_t<T>::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish);
|
||||
void adjust_slice_indices(PyObject* obj, int& start, int& finish);
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_sequence_slice(PyObject* obj, int start, int finish) const
|
||||
@@ -524,108 +477,6 @@ PyObject* class_t<T>::instance_number_hex(PyObject* obj) const
|
||||
return downcast<T>(obj)->hex();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_add(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_add(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_subtract(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_subtract(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_multiply(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_multiply(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_divide(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_divide(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_remainder(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_remainder(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_power(exponent, modulus);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_lshift(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_lshift(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_rshift(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_rshift(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_and(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_and(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_or(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_or(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_inplace_xor(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->inplace_xor(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_lt(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->lt(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_le(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->le(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_eq(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->eq(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_ne(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->ne(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_gt(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->gt(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_ge(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->ge(other);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
inline dictionary& class_base::dict()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
// producing this work.
|
||||
//
|
||||
// Revision History:
|
||||
// 31 Jul 01 convert int/double to complex (Peter Bienstman)
|
||||
// 04 Mar 01 Fixed std::complex<> stuff to work with MSVC (David Abrahams)
|
||||
// 03 Mar 01 added: converters for [plain] char and std::complex
|
||||
// (Ralf W. Grosse-Kunstleve)
|
||||
@@ -19,7 +18,7 @@
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <string>
|
||||
|
||||
@@ -74,17 +73,17 @@ inline void xdecref_impl(PyObject* p) { Py_XDECREF(p); }
|
||||
template <class T>
|
||||
inline void decref(T* p)
|
||||
{
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
decref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
decref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void xdecref(T* p)
|
||||
{
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
@@ -94,10 +93,6 @@ namespace detail {
|
||||
template <class T>
|
||||
std::complex<T> complex_from_python(PyObject* p, boost::python::type<T>)
|
||||
{
|
||||
if (PyInt_Check(p)) return std::complex<T>(PyInt_AS_LONG(p));
|
||||
if (PyLong_Check(p)) return std::complex<T>(PyLong_AsDouble(p));
|
||||
if (PyFloat_Check(p)) return std::complex<T>(PyFloat_AS_DOUBLE(p));
|
||||
|
||||
expect_complex(p);
|
||||
|
||||
return std::complex<T>(
|
||||
@@ -122,68 +117,61 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
// Converters
|
||||
//
|
||||
PyObject* to_python(long);
|
||||
BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type<long>);
|
||||
long from_python(PyObject* p, boost::python::type<long>);
|
||||
long from_python(PyObject* p, boost::python::type<const long&>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned long);
|
||||
BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
|
||||
PyObject* to_python(unsigned long);
|
||||
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);
|
||||
BOOST_PYTHON_DECL int from_python(PyObject*, boost::python::type<int>);
|
||||
int from_python(PyObject*, boost::python::type<int>);
|
||||
int from_python(PyObject*, boost::python::type<const int&>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned int);
|
||||
BOOST_PYTHON_DECL unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
|
||||
PyObject* to_python(unsigned int);
|
||||
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);
|
||||
BOOST_PYTHON_DECL short from_python(PyObject*, boost::python::type<short>);
|
||||
short from_python(PyObject*, boost::python::type<short>);
|
||||
short from_python(PyObject*, boost::python::type<const short&>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned short);
|
||||
BOOST_PYTHON_DECL unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
|
||||
PyObject* to_python(unsigned short);
|
||||
unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
|
||||
unsigned short from_python(PyObject*, boost::python::type<const unsigned short&>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(char);
|
||||
BOOST_PYTHON_DECL char from_python(PyObject*, boost::python::type<char>);
|
||||
PyObject* to_python(char);
|
||||
char from_python(PyObject*, boost::python::type<char>);
|
||||
char from_python(PyObject*, boost::python::type<const char&>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(signed char);
|
||||
BOOST_PYTHON_DECL signed char from_python(PyObject*, boost::python::type<signed char>);
|
||||
PyObject* to_python(signed char);
|
||||
signed char from_python(PyObject*, boost::python::type<signed char>);
|
||||
signed char from_python(PyObject*, boost::python::type<const signed char&>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(unsigned char);
|
||||
BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
|
||||
PyObject* to_python(unsigned char);
|
||||
unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
|
||||
unsigned char from_python(PyObject*, boost::python::type<const unsigned char&>);
|
||||
|
||||
# ifndef BOOST_MSVC6_OR_EARLIER
|
||||
PyObject* to_python(float);
|
||||
float from_python(PyObject*, boost::python::type<float>);
|
||||
PyObject* to_python(double);
|
||||
double from_python(PyObject*, boost::python::type<double>);
|
||||
# else
|
||||
BOOST_PYTHON_DECL PyObject* to_python(float);
|
||||
BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type<float>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(double);
|
||||
BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type<double>);
|
||||
# endif
|
||||
float from_python(PyObject*, boost::python::type<const float&>);
|
||||
|
||||
PyObject* to_python(double);
|
||||
double from_python(PyObject*, boost::python::type<double>);
|
||||
double from_python(PyObject*, boost::python::type<const double&>);
|
||||
|
||||
PyObject* to_python(bool);
|
||||
BOOST_PYTHON_DECL bool from_python(PyObject*, boost::python::type<bool>);
|
||||
bool from_python(PyObject*, boost::python::type<bool>);
|
||||
bool from_python(PyObject*, boost::python::type<const bool&>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(void);
|
||||
BOOST_PYTHON_DECL void from_python(PyObject*, boost::python::type<void>);
|
||||
PyObject* to_python(void);
|
||||
void from_python(PyObject*, boost::python::type<void>);
|
||||
|
||||
PyObject* to_python(const char* s);
|
||||
BOOST_PYTHON_DECL const char* from_python(PyObject*, boost::python::type<const char*>);
|
||||
const char* from_python(PyObject*, boost::python::type<const char*>);
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* to_python(const std::string& s);
|
||||
BOOST_PYTHON_DECL std::string from_python(PyObject*, boost::python::type<std::string>);
|
||||
PyObject* to_python(const std::string& s);
|
||||
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)
|
||||
@@ -301,22 +289,22 @@ inline PyObject* to_python(float f)
|
||||
|
||||
inline PyObject* to_python(long l)
|
||||
{
|
||||
return PyInt_FromLong(l);
|
||||
return PyInt_FromLong(l);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(int x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(short x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(bool b)
|
||||
{
|
||||
return PyInt_FromLong(b);
|
||||
return PyInt_FromLong(b);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(void)
|
||||
@@ -326,7 +314,7 @@ inline PyObject* to_python(void)
|
||||
|
||||
inline PyObject* to_python(const char* s)
|
||||
{
|
||||
return PyString_FromString(s);
|
||||
return PyString_FromString(s);
|
||||
}
|
||||
|
||||
inline std::string from_python(PyObject* p, boost::python::type<const std::string&>)
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef BODY_DWA2001127_HPP
|
||||
# define BODY_DWA2001127_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace registry
|
||||
{
|
||||
class entry;
|
||||
}
|
||||
|
||||
struct BOOST_PYTHON_DECL body
|
||||
{
|
||||
public:
|
||||
body(type_id_t key);
|
||||
virtual ~body() {}
|
||||
|
||||
type_id_t key() const;
|
||||
|
||||
protected:
|
||||
// true iff the registry is still alive
|
||||
bool can_unregister() const;
|
||||
|
||||
private:
|
||||
// called when the registry is destroyed, to prevent it from being
|
||||
// unregistered.
|
||||
void do_not_unregister();
|
||||
friend class registry::entry;
|
||||
|
||||
private:
|
||||
type_id_t m_key;
|
||||
bool m_can_unregister;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline body::body(type_id_t key)
|
||||
: m_key(key)
|
||||
, m_can_unregister(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline type_id_t body::key() const
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
|
||||
inline bool body::can_unregister() const
|
||||
{
|
||||
return m_can_unregister;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // BODY_DWA2001127_HPP
|
||||
@@ -1,69 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# define BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <string>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Provide specializations of to_python_value
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct builtin_to_python
|
||||
{
|
||||
static bool convertible() { return true; }
|
||||
};
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
template <> struct to_python_value<T&> \
|
||||
: detail::builtin_to_python \
|
||||
{ \
|
||||
PyObject* operator()(T const& x) const \
|
||||
{ \
|
||||
return (expr); \
|
||||
} \
|
||||
}; \
|
||||
template <> struct to_python_value<T const&> \
|
||||
: detail::builtin_to_python \
|
||||
{ \
|
||||
PyObject* operator()(T const& x) const \
|
||||
{ \
|
||||
return (expr); \
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
# define BOOST_PYTHON_TO_INT(T) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x))
|
||||
|
||||
BOOST_PYTHON_TO_INT(char)
|
||||
BOOST_PYTHON_TO_INT(short)
|
||||
BOOST_PYTHON_TO_INT(int)
|
||||
BOOST_PYTHON_TO_INT(long)
|
||||
# undef BOOST_TO_PYTHON_INT
|
||||
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x)
|
||||
|
||||
namespace converter
|
||||
{
|
||||
|
||||
void initialize_builtin_converters();
|
||||
|
||||
}
|
||||
|
||||
}} // namespace boost::python::converter
|
||||
|
||||
#endif // BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CLASS_DWA20011215_HPP
|
||||
# define CLASS_DWA20011215_HPP
|
||||
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T>
|
||||
struct class_from_python_converter
|
||||
{
|
||||
class_from_python_converter();
|
||||
|
||||
static void* convertible(PyObject*);
|
||||
static T& convert_ref(PyObject*, from_python_data&);
|
||||
static T const& convert_cref(PyObject*, from_python_data&);
|
||||
static T* convert_ptr(PyObject*, from_python_data&);
|
||||
static T const* convert_cptr(PyObject*, from_python_data&);
|
||||
|
||||
from_python_converter<T&> to_ref;
|
||||
from_python_converter<T const&> to_cref;
|
||||
from_python_converter<T*> to_ptr;
|
||||
from_python_converter<T const*> to_cptr;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
class_from_python_converter<T>::class_from_python_converter()
|
||||
: to_ref(convertible, convert_ref)
|
||||
, to_cref(convertible, convert_cref)
|
||||
, to_ptr(convertible, convert_ptr)
|
||||
, to_cptr(convertible, convert_cptr)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
T& class_from_python_converter<T>::convert_ref(PyObject*, from_python_data& x)
|
||||
{
|
||||
return *static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const& class_from_python_converter<T>::convert_cref(PyObject*, from_python_data& x)
|
||||
{
|
||||
return *static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
T* class_from_python_converter<T>::convert_ptr(PyObject*, from_python_data& x)
|
||||
{
|
||||
return static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const* class_from_python_converter<T>::convert_cptr(PyObject*, from_python_data& x)
|
||||
{
|
||||
return static_cast<T*>(x.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void* class_from_python_converter<T>::convertible(PyObject* p)
|
||||
{
|
||||
return objects::find_instance<T>(p);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CLASS_DWA20011215_HPP
|
||||
@@ -1,198 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef FROM_PYTHON_DWA2002127_HPP
|
||||
# define FROM_PYTHON_DWA2002127_HPP
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/converter/body.hpp>
|
||||
# include <boost/python/converter/from_python_function.hpp>
|
||||
# include <boost/python/converter/from_python_data.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// The type of convertibility checking functions
|
||||
typedef void* (*from_python_check)(PyObject*);
|
||||
typedef void (*from_python_destructor)(from_python_data&);
|
||||
|
||||
// forward declaration
|
||||
template <class T> struct from_python_lookup;
|
||||
|
||||
// from_python --
|
||||
// A body class representing a conversion from python to C++.
|
||||
|
||||
struct BOOST_PYTHON_DECL from_python_converter_base : body
|
||||
{
|
||||
from_python_converter_base(type_id_t, from_python_check); // registers
|
||||
|
||||
// Must return non-null iff the conversion will be successful. Any
|
||||
// non-null pointer is acceptable, and will be passed on to the
|
||||
// convert() function, so useful data can be stored there.
|
||||
inline void* convertible(PyObject*) const;
|
||||
|
||||
// Given the head of a from_python converter chain, find the
|
||||
// converter which can convert p, leaving its intermediate data in
|
||||
// data.
|
||||
inline static from_python_converter_base const*
|
||||
find(from_python_converter_base const*chain, PyObject* p, void*& data);
|
||||
|
||||
private:
|
||||
from_python_check m_convertible;
|
||||
from_python_converter_base* m_next;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct from_python_converter : from_python_converter_base
|
||||
{
|
||||
public: // types
|
||||
typedef typename from_python_function<T>::type conversion_function;
|
||||
|
||||
public: // member functions
|
||||
from_python_converter(from_python_check, conversion_function, from_python_destructor = 0);
|
||||
T convert(PyObject*, from_python_data&) const;
|
||||
void destroy(from_python_data&) const;
|
||||
|
||||
// Find a converter for converting p to a T.
|
||||
static from_python_converter<T> const* find(PyObject* p, void*& data);
|
||||
|
||||
private: // data members
|
||||
conversion_function m_convert;
|
||||
from_python_destructor m_destroy;
|
||||
|
||||
// Keeps the chain of converters which convert from PyObject* to T
|
||||
static from_python_converter_base*const& chain;
|
||||
};
|
||||
|
||||
// Initialized to refer to a common place in the registry.
|
||||
template <class T>
|
||||
from_python_converter_base*const&
|
||||
from_python_converter<T>::chain = registry::from_python_chain(type_id<T>());
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// A class which implements from_python with a registry lookup.
|
||||
template <class T>
|
||||
struct from_python_lookup // : from_python_base
|
||||
{
|
||||
public: // types
|
||||
|
||||
public: // member functions
|
||||
from_python_lookup(PyObject* source);
|
||||
~from_python_lookup();
|
||||
|
||||
bool convertible() const;
|
||||
T operator()(PyObject*);
|
||||
|
||||
public: // functions for use by conversion implementations
|
||||
// Get the converter object
|
||||
from_python_converter<T> const* converter() const;
|
||||
|
||||
private: // data members
|
||||
typedef typename from_python_intermediate_data<T>::type intermediate_t;
|
||||
mutable intermediate_t m_intermediate_data;
|
||||
from_python_converter<T> const* m_converter;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline void* from_python_converter_base::convertible(PyObject* o) const
|
||||
{
|
||||
return m_convertible(o);
|
||||
}
|
||||
|
||||
inline from_python_converter_base const*
|
||||
from_python_converter_base::find(
|
||||
from_python_converter_base const* chain, PyObject* p, void*& data)
|
||||
{
|
||||
for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next)
|
||||
{
|
||||
void* d = q->convertible(p);
|
||||
if (d != 0)
|
||||
{
|
||||
data = d;
|
||||
return q;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T>::from_python_converter(
|
||||
from_python_check checker
|
||||
, conversion_function converter
|
||||
, from_python_destructor destructor // = 0
|
||||
)
|
||||
: from_python_converter_base(type_id<T>(), checker)
|
||||
, m_convert(converter)
|
||||
, m_destroy(destructor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T> const*
|
||||
from_python_converter<T>::find(PyObject* p, void*& data)
|
||||
{
|
||||
return static_cast<from_python_converter<T> const*>(
|
||||
from_python_converter_base::find(chain, p, data));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T from_python_converter<T>::convert(PyObject* src, from_python_data& data) const
|
||||
{
|
||||
return this->m_convert(src, data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void from_python_converter<T>::destroy(from_python_data& data) const
|
||||
{
|
||||
if (this->m_destroy)
|
||||
{
|
||||
this->m_destroy(data);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_lookup<T>::from_python_lookup(PyObject* src)
|
||||
: m_converter(
|
||||
from_python_converter<T>::find(
|
||||
src, m_intermediate_data.stage1))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_lookup<T>::~from_python_lookup()
|
||||
{
|
||||
if (m_converter != 0)
|
||||
m_converter->destroy(m_intermediate_data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool from_python_lookup<T>::convertible() const
|
||||
{
|
||||
return this->m_converter != 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T from_python_lookup<T>::operator()(PyObject* obj)
|
||||
{
|
||||
return this->m_converter->convert(obj, m_intermediate_data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T> const*
|
||||
from_python_lookup<T>::converter() const
|
||||
{
|
||||
return this->m_converter;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_DWA2002127_HPP
|
||||
@@ -1,206 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/char_array.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
// Keep these for the metaprogram which EDG is choking on.
|
||||
# if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/type_traits/alignment_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// A POD which is layout-compatible with the real intermediate data
|
||||
// for all from_python conversions. There may be additional storage if
|
||||
// we are converting a reference type.
|
||||
struct from_python_data
|
||||
{
|
||||
void* stage1;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T> struct referent_alignment;
|
||||
template <class T> struct referent_size;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
struct referent_alignment<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = alignment_of<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct referent_size<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = sizeof(T));
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
template <class U>
|
||||
struct alignment_chars
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_T, n = alignment_of<U>::value);
|
||||
char elements[n + 1];
|
||||
};
|
||||
|
||||
template <class T> struct referent_alignment
|
||||
{
|
||||
template <class U>
|
||||
static alignment_chars<U> helper(U&);
|
||||
|
||||
static T t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = sizeof(helper(t).elements) - 1);
|
||||
};
|
||||
|
||||
|
||||
template <class T> struct referent_size
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t));
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
struct unknown_alignment
|
||||
{
|
||||
void* p;
|
||||
};
|
||||
|
||||
// EDG is too slow to handle this metaprogram :(
|
||||
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
struct alignment_dummy;
|
||||
|
||||
template <std::size_t target_alignment>
|
||||
struct best_alignment_type
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, align1 = alignment_of<T1>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, align2 = alignment_of<T2>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, aligned2 = (
|
||||
(align2 >= target_alignment)
|
||||
& (align2 % target_alignment == 0))
|
||||
);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, choose_t2 = (
|
||||
aligned2 && (
|
||||
is_same<T1,unknown_alignment>::value
|
||||
| (align2 < alignment_of<T1>::value)
|
||||
| (sizeof(T2) < sizeof(T1)))
|
||||
));
|
||||
|
||||
typedef mpl::select_type<choose_t2, T2, T1>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
typedef mpl::type_list<
|
||||
char,short,int,long,float,double,long double
|
||||
,void*
|
||||
,void(*)()
|
||||
,void (alignment_dummy::*)()
|
||||
, char (alignment_dummy::*)
|
||||
>
|
||||
align_types;
|
||||
#endif // EDG is too slow
|
||||
|
||||
template <class Align, std::size_t size>
|
||||
struct aligned_storage
|
||||
{
|
||||
typedef Align align_t;
|
||||
union
|
||||
{
|
||||
Align align;
|
||||
char bytes[size
|
||||
// this is just a STATIC_ASSERT. For some reason
|
||||
// MSVC was barfing on the boost one.
|
||||
- (is_same<align_t,unknown_alignment>::value ? size : 0)];
|
||||
};
|
||||
};
|
||||
|
||||
template <class Reference>
|
||||
struct referent_storage
|
||||
{
|
||||
// EDG is too slow to handle this metaprogram :(
|
||||
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
typedef mpl::for_each<
|
||||
align_types
|
||||
, unknown_alignment
|
||||
, best_alignment_type<referent_alignment<Reference>::value>
|
||||
> loop;
|
||||
typedef typename loop::state align_t;
|
||||
#else
|
||||
// The Python source makes the assumption that double has
|
||||
// maximal alignment anyway
|
||||
typedef double align_t;
|
||||
#endif
|
||||
|
||||
typedef aligned_storage<align_t,referent_size<Reference>::value> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct intermediate_data : from_python_data
|
||||
{
|
||||
typename referent_storage<T>::type stage2;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct intermediate_data<void> : from_python_data
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Auxiliary POD storage where the convertible and/or convert functions of a
|
||||
// from_python object may place arbitrary data.
|
||||
//
|
||||
// Always starts with a void*
|
||||
//
|
||||
// For references, we produce additional aligned storage sufficient to
|
||||
// store the referent
|
||||
|
||||
template <class T>
|
||||
struct from_python_intermediate_data
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_reference<T>::value, T, void>::type just_reference_t;
|
||||
|
||||
typedef detail::intermediate_data<just_reference_t> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void* get_storage(from_python_data& x, boost::type<T>* = 0)
|
||||
{
|
||||
typedef typename from_python_intermediate_data<T>::type layout;
|
||||
return static_cast<layout*>(&x)->stage2.bytes;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
@@ -1,23 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
# define FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct from_python_data;
|
||||
|
||||
template <class T>
|
||||
struct from_python_function
|
||||
{
|
||||
typedef T (*type)(PyObject*, from_python_data&);
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
@@ -1,108 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef HANDLE_DWA20011130_HPP
|
||||
# define HANDLE_DWA20011130_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL body;
|
||||
|
||||
// The common base class for unwrap_ and wrap_ handle objects. They
|
||||
// share a common base so that handles can be linked into a chain
|
||||
// within a function wrapper which is managed by a single object.
|
||||
struct BOOST_PYTHON_DECL handle : boost::noncopyable
|
||||
{
|
||||
public: // member functions
|
||||
|
||||
// All constructors take a body* passed from the derived class.
|
||||
//
|
||||
// Constructors taking a handle links this into a chain of
|
||||
// handles, for more efficient management in function wrappers
|
||||
handle();
|
||||
handle(body* body);
|
||||
handle(body* body, handle& prev);
|
||||
|
||||
// returns true iff all handles in the chain can convert their
|
||||
// arguments
|
||||
bool convertible() const;
|
||||
|
||||
// safe_bool idiom from Peter Dimov: provides handles to/from
|
||||
// bool without enabling handles to integer types/void*.
|
||||
private:
|
||||
struct dummy { inline void nonnull() {} };
|
||||
typedef void (dummy::*safe_bool)();
|
||||
public:
|
||||
inline operator safe_bool() const;
|
||||
inline safe_bool operator!() const;
|
||||
|
||||
protected: // member functions for derived classes
|
||||
// Get the body we hold
|
||||
inline body* get_body() const;
|
||||
|
||||
inline void set_body(body*);
|
||||
inline void set_prev(handle&);
|
||||
|
||||
// Release all bodies in the chain, in reverse order of
|
||||
// initialization. Only actually called for the head of the chain.
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
// Holds implementation
|
||||
body* m_body;
|
||||
|
||||
// handle for next argument, if any.
|
||||
handle* m_next;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline handle::handle()
|
||||
: m_next(0)
|
||||
{}
|
||||
|
||||
inline handle::handle(body* body, handle& prev)
|
||||
: m_body(body), m_next(0)
|
||||
{
|
||||
prev.m_next = this;
|
||||
}
|
||||
|
||||
inline handle::handle(body* body)
|
||||
: m_body(body), m_next(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline handle::operator handle::safe_bool() const
|
||||
{
|
||||
return convertible() ? &dummy::nonnull : 0;
|
||||
}
|
||||
|
||||
inline handle::safe_bool handle::operator!() const
|
||||
{
|
||||
return convertible() ? 0 : &dummy::nonnull;
|
||||
}
|
||||
|
||||
inline body* handle::get_body() const
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
||||
inline void handle::set_body(body* body)
|
||||
{
|
||||
m_body = body;
|
||||
}
|
||||
|
||||
inline void handle::set_prev(handle& prev)
|
||||
{
|
||||
prev.m_next = this;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // HANDLE_DWA20011130_HPP
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef REGISTRY_DWA20011127_HPP
|
||||
# define REGISTRY_DWA20011127_HPP
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/to_python_function.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL from_python_converter_base;
|
||||
|
||||
// This namespace acts as a sort of singleton
|
||||
namespace registry
|
||||
{
|
||||
BOOST_PYTHON_DECL to_python_value_function const&
|
||||
to_python_function(undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // REGISTRY_DWA20011127_HPP
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef SMART_PTR_DWA2002123_HPP
|
||||
# define SMART_PTR_DWA2002123_HPP
|
||||
|
||||
# include <boost/python/converter/class.hpp>
|
||||
# include <boost/python/object/pointer_holder.hpp>
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class Pointer, class Value>
|
||||
class smart_ptr_wrapper
|
||||
: wrapper<Pointer const&>
|
||||
{
|
||||
smart_ptr_wrapper(ref const& type_)
|
||||
: m_class_object(type_)
|
||||
{
|
||||
assert(type_->ob_type == (PyTypeObject*)class_metatype().get());
|
||||
}
|
||||
|
||||
PyObject* convert(Pointer x) const;
|
||||
|
||||
private:
|
||||
ref m_class_object;
|
||||
|
||||
smart_ptr_converters();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
template <class Pointer, class Value>
|
||||
PyObject* smart_ptr_wrapper<Pointer,Value>::convert(Pointer x) const
|
||||
{
|
||||
if (x.operator->() == 0)
|
||||
return detail::none();
|
||||
|
||||
// Don't call the type to do the construction, since that
|
||||
// would require the registration of an __init__ copy
|
||||
// constructor. Instead, just construct the object in place.
|
||||
PyObject* raw_result = (PyObject*)PyObject_New(
|
||||
instance, (PyTypeObject*)m_class_object.get());
|
||||
|
||||
if (raw_result == 0)
|
||||
return 0;
|
||||
|
||||
// Everything's OK; Bypass NULL checks but guard against
|
||||
// exceptions.
|
||||
ref result(raw_result, ref::allow_null());
|
||||
|
||||
// Build a value_holder to contain the object using the copy
|
||||
// constructor
|
||||
objects::pointer_holder<Pointer,Value>*
|
||||
p = new objects::pointer_holder<Pointer,Value>(x);
|
||||
|
||||
// Install it in the instance
|
||||
p->install(raw_result);
|
||||
|
||||
// Return the new result
|
||||
return result.release();
|
||||
}
|
||||
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // SMART_PTR_DWA2002123_HPP
|
||||
@@ -1,191 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#ifndef TARGET_DWA20011119_HPP
|
||||
# define TARGET_DWA20011119_HPP
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// target --
|
||||
//
|
||||
// This type generator (see
|
||||
// ../../../more/generic_programming.html#type_generator) is used
|
||||
// to select the return type of the appropriate converter for
|
||||
// unwrapping a given type.
|
||||
|
||||
// Strategy:
|
||||
//
|
||||
// 1. reduce everything to a common, un-cv-qualified reference
|
||||
// type where possible. This will save on registering many different
|
||||
// converter types.
|
||||
//
|
||||
// 2. Treat built-in types specially: when unwrapping a value or
|
||||
// constant reference to one of these, use a value for the target
|
||||
// type. It will bind to a const reference if neccessary, and more
|
||||
// importantly, avoids having to dynamically allocate room for
|
||||
// an lvalue of types which can be cheaply copied.
|
||||
//
|
||||
|
||||
// Target Source
|
||||
// int int
|
||||
// int const& int
|
||||
// int& int&
|
||||
// int volatile& int volatile&
|
||||
// int const volatile& int const volatile&
|
||||
|
||||
// On compilers supporting partial specialization:
|
||||
//
|
||||
// Target Source
|
||||
// T T const&
|
||||
// T& T&
|
||||
// T const& T const&
|
||||
// T volatile T&
|
||||
// T const volatile& T const&
|
||||
// T* T*
|
||||
// T const* T const*
|
||||
// T volatile T*
|
||||
// T const volatile* T const*
|
||||
// T cv*const& same as T cv*
|
||||
// T cv*& T*& <- should this be legal?
|
||||
// T cv*volatile& T*& <- should this be legal?
|
||||
// T cv*const volatile& T*& <- should this be legal?
|
||||
|
||||
// On others:
|
||||
//
|
||||
// Target Source
|
||||
// T T&
|
||||
// T cv& T cv&
|
||||
// T cv* T cv*
|
||||
// T cv*cv& T cv*cv&
|
||||
|
||||
// As you can see, in order to handle the same range of types without
|
||||
// partial specialization, more converters need to be registered.
|
||||
|
||||
template <class T>
|
||||
struct target
|
||||
{
|
||||
// Some pointer types are handled in a more sophisticated way on
|
||||
// compilers supporting partial specialization.
|
||||
BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_scalar<T>::value));
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
use_identity
|
||||
, T
|
||||
, typename add_reference<
|
||||
typename add_const<
|
||||
typename remove_volatile<T>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// When partial specialization is not present, we'll simply need to
|
||||
// register many more converters.
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
struct target<T&>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type& type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T const&>
|
||||
{
|
||||
typedef typename boost::mpl::select_type<
|
||||
is_scalar<T>::value
|
||||
, typename remove_cv<T>::type
|
||||
, typename remove_volatile<T>::type const&
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T*>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
// Handle T*-cv for completeness. Function arguments in a signature
|
||||
// are never actually cv-qualified, but who knows how these converters
|
||||
// might be used, or whether compiler bugs lurk which make it seem
|
||||
// otherwise?
|
||||
template <class T>
|
||||
struct target<T* const>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T* volatile>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct target<T* const volatile>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
|
||||
// non-const references to pointers should be handled by the
|
||||
// specialization for T&, above.
|
||||
template <class T>
|
||||
struct target<T* const&>
|
||||
{
|
||||
typedef typename remove_volatile<T>::type* type;
|
||||
};
|
||||
# endif
|
||||
|
||||
// Fortunately, we can handle T const& where T is an arithmetic type
|
||||
// by explicit specialization. These specializations will cause value
|
||||
// and const& arguments to be converted to values, rather than to
|
||||
// references.
|
||||
# define BOOST_PYTHON_UNWRAP_VALUE(T) \
|
||||
template <> \
|
||||
struct target<T> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T const> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T volatile> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T const volatile> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}; \
|
||||
template <> \
|
||||
struct target<T const&> \
|
||||
{ \
|
||||
typedef T type; \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_UNWRAP_VALUE(char);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned char);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed char);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned int);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed int);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned short);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed short);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(unsigned long);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(signed long);
|
||||
BOOST_PYTHON_UNWRAP_VALUE(char const*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TARGET_DWA20011119_HPP
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
# define TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// The type of stored function pointers which actually do conversion
|
||||
// by-value. The void* points to the object to be converted, and
|
||||
// type-safety is preserved through runtime registration.
|
||||
typedef PyObject* (*to_python_value_function)(void const*);
|
||||
|
||||
// Given a typesafe to_python conversion function, produces a
|
||||
// to_python_value_function which can be registered in the usual way.
|
||||
template <class T, class ToPython>
|
||||
struct as_to_python_value_function
|
||||
{
|
||||
static PyObject* convert(void const* x)
|
||||
{
|
||||
return ToPython::convert(*(T const*)x);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
@@ -1,176 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef TYPE_ID_DWA20011127_HPP
|
||||
# define TYPE_ID_DWA20011127_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/python/detail/msvc_typeinfo.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
# include <boost/type.hpp>
|
||||
# include <typeinfo>
|
||||
# include <iosfwd>
|
||||
# include <cstring>
|
||||
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// for this compiler at least, cross-shared-library type_info
|
||||
// comparisons don't work, so use typeid(x).name() instead. It's not
|
||||
// yet clear what the best default strategy is.
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3
|
||||
# define BOOST_PYTHON_TYPE_ID_NAME
|
||||
# endif
|
||||
|
||||
// type ids which represent the same information as std::type_info
|
||||
// (i.e. the top-level reference and cv-qualifiers are stripped), but
|
||||
// which works across shared libraries.
|
||||
struct undecorated_type_id_t : totally_ordered<undecorated_type_id_t>
|
||||
{
|
||||
undecorated_type_id_t(std::type_info const&);
|
||||
|
||||
// default constructor needed to build arrays, etc.
|
||||
undecorated_type_id_t();
|
||||
|
||||
bool operator<(undecorated_type_id_t const& rhs) const;
|
||||
bool operator==(undecorated_type_id_t const& rhs) const;
|
||||
|
||||
char const* name() const;
|
||||
friend BOOST_PYTHON_DECL std::ostream& operator<<(
|
||||
std::ostream&, undecorated_type_id_t const&);
|
||||
|
||||
private: // data members
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
typedef char const* base_id_t;
|
||||
# else
|
||||
typedef std::type_info const* base_id_t;
|
||||
# endif
|
||||
|
||||
base_id_t m_base_type;
|
||||
};
|
||||
|
||||
struct type_id_t : totally_ordered<type_id_t>
|
||||
{
|
||||
enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 };
|
||||
|
||||
type_id_t(undecorated_type_id_t, decoration = decoration());
|
||||
|
||||
bool operator<(type_id_t const& rhs) const;
|
||||
bool operator==(type_id_t const& rhs) const;
|
||||
|
||||
friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&);
|
||||
|
||||
operator undecorated_type_id_t const&() const;
|
||||
private: // type
|
||||
typedef undecorated_type_id_t base_id_t;
|
||||
|
||||
private: // data members
|
||||
decoration m_decoration;
|
||||
base_id_t m_base_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline undecorated_type_id_t undecorated_type_id(boost::type<T>* = 0)
|
||||
{
|
||||
return undecorated_type_id_t(
|
||||
# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600)
|
||||
typeid(T)
|
||||
# else // strip the decoration which msvc and Intel mistakenly leave in
|
||||
python::detail::msvc_typeid<T>()
|
||||
# endif
|
||||
);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline type_id_t type_id(boost::type<T>* = 0)
|
||||
{
|
||||
return type_id_t(
|
||||
undecorated_type_id<T>()
|
||||
, type_id_t::decoration(
|
||||
(is_const<T>::value || python::detail::is_reference_to_const<T>::value
|
||||
? type_id_t::const_ : 0)
|
||||
| (is_volatile<T>::value || python::detail::is_reference_to_volatile<T>::value
|
||||
? type_id_t::volatile_ : 0)
|
||||
| (is_reference<T>::value ? type_id_t::reference : 0)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
inline undecorated_type_id_t::undecorated_type_id_t(std::type_info const& id)
|
||||
: m_base_type(
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
id.name()
|
||||
# else
|
||||
&id
|
||||
# endif
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
inline undecorated_type_id_t::undecorated_type_id_t()
|
||||
: m_base_type()
|
||||
{
|
||||
}
|
||||
|
||||
inline type_id_t::type_id_t(undecorated_type_id_t base_t, decoration decoration)
|
||||
: m_decoration(decoration)
|
||||
, m_base_type(base_t)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool undecorated_type_id_t::operator<(undecorated_type_id_t const& rhs) const
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
return std::strcmp(m_base_type, rhs.m_base_type) < 0;
|
||||
# else
|
||||
return m_base_type->before(*rhs.m_base_type);
|
||||
# endif
|
||||
}
|
||||
|
||||
inline bool type_id_t::operator<(type_id_t const& rhs) const
|
||||
{
|
||||
return m_decoration < rhs.m_decoration
|
||||
|| m_decoration == rhs.m_decoration
|
||||
&& m_base_type < rhs.m_base_type;
|
||||
}
|
||||
|
||||
inline bool undecorated_type_id_t::operator==(undecorated_type_id_t const& rhs) const
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
return !std::strcmp(m_base_type, rhs.m_base_type);
|
||||
# else
|
||||
return *m_base_type == *rhs.m_base_type;
|
||||
# endif
|
||||
}
|
||||
|
||||
inline bool type_id_t::operator==(type_id_t const& rhs) const
|
||||
{
|
||||
return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type;
|
||||
}
|
||||
|
||||
inline type_id_t::operator undecorated_type_id_t const&() const
|
||||
{
|
||||
return m_base_type;
|
||||
}
|
||||
|
||||
inline char const* undecorated_type_id_t::name() const
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TYPE_ID_NAME
|
||||
return m_base_type;
|
||||
# else
|
||||
return m_base_type->name();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, undecorated_type_id_t const&);
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TYPE_ID_DWA20011127_HPP
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef UNWRAPPER_BASE_DWA20011215_HPP
|
||||
# define UNWRAPPER_BASE_DWA20011215_HPP
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/body.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL unwrapper_base : body
|
||||
{
|
||||
public:
|
||||
unwrapper_base(type_id_t); // registers
|
||||
~unwrapper_base(); // unregisters
|
||||
|
||||
// Must return non-null iff the conversion will be successful. Any
|
||||
// non-null pointer is acceptable, and will be passed on to the
|
||||
// convert() function, so useful data can be stored there.
|
||||
virtual void* can_convert(PyObject*) const = 0;
|
||||
|
||||
protected:
|
||||
// this is an arbitrary non-null pointer you can use to indicate success
|
||||
static void* const non_null;
|
||||
|
||||
private: // body required interface implementation
|
||||
void destroy_handle(handle*) const {}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // UNWRAPPER_BASE_DWA20011215_HPP
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
# define UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T> struct unwrapper;
|
||||
|
||||
// Select the type returned by unwrapper objects when unwrapping a
|
||||
// given type. When unwrapping T const&, the unwrapper returns T&, so
|
||||
// that the same unwrapper object can be used for both conversions (on
|
||||
// a conforming compiler).
|
||||
template <class T>
|
||||
struct unwrapper_select
|
||||
{
|
||||
typedef unwrapper<T> type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct unwrapper_select<T const&>
|
||||
{
|
||||
typedef unwrapper<T&> type;
|
||||
};
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef COPY_CONST_REFERENCE_DWA2002131_HPP
|
||||
# define COPY_CONST_REFERENCE_DWA2002131_HPP
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/to_python_value.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct copy_const_reference_expects_a_const_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
struct copy_const_reference
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
detail::is_reference_to_const<T>::value
|
||||
, to_python_value<T>
|
||||
, detail::copy_const_reference_expects_a_const_reference_return_type<T>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // COPY_CONST_REFERENCE_DWA2002131_HPP
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef COPY_NON_CONST_REFERENCE_DWA2002131_HPP
|
||||
# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/to_python_value.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct copy_non_const_reference_expects_a_non_const_reference_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
struct copy_non_const_reference
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
boost::python::detail::is_reference_to_non_const<T>::value
|
||||
, to_python_value<T>
|
||||
, detail::copy_non_const_reference_expects_a_non_const_reference_return_type<T>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // COPY_NON_CONST_REFERENCE_DWA2002131_HPP
|
||||
@@ -18,28 +18,26 @@
|
||||
# include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
struct BOOST_PYTHON_DECL import_error: error_already_set {};
|
||||
struct BOOST_PYTHON_DECL export_error : error_already_set {};
|
||||
struct import_error : error_already_set {};
|
||||
struct export_error : error_already_set {};
|
||||
}}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
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 BOOST_PYTHON_DECL const char* converters_attribute_name;
|
||||
BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name,
|
||||
const std::string& py_class_name,
|
||||
const std::string& attribute_name);
|
||||
BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major,
|
||||
const int importing_minor,
|
||||
const int imported_major,
|
||||
const int imported_minor);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
}}}
|
||||
|
||||
// forward declaration
|
||||
namespace boost { namespace python { namespace detail {
|
||||
@@ -171,9 +169,6 @@ struct export_converter_object_noncopyable : export_converter_object_base<T>
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"to_python(const T&) converter not exported");
|
||||
throw import_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual T* from_python_Ts(PyObject* p, boost::python::type<T*> t) {
|
||||
@@ -234,56 +229,56 @@ struct export_converter_object : export_converter_object_noncopyable<T>
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace detail {
|
||||
|
||||
/* This class template is instantiated by import_converters<T>.
|
||||
Its purpose is to import the converter_object via the Python API.
|
||||
The actual import is only done once. The pointer to the
|
||||
imported converter object is kept in the static data member
|
||||
imported_converters.
|
||||
*/
|
||||
template <class T>
|
||||
class import_extension_class
|
||||
: public python_import_extension_class_converters<T>
|
||||
{
|
||||
public:
|
||||
inline import_extension_class(const char* module, const char* py_class) {
|
||||
m_module = module;
|
||||
m_py_class = py_class;
|
||||
}
|
||||
*/
|
||||
template <class T>
|
||||
class import_extension_class
|
||||
: public python_import_extension_class_converters<T>
|
||||
{
|
||||
public:
|
||||
inline import_extension_class(const char* module, const char* py_class) {
|
||||
m_module = module;
|
||||
m_py_class = py_class;
|
||||
}
|
||||
|
||||
static boost::python::export_converter_object_base<T>* get_converters();
|
||||
static boost::python::export_converter_object_base<T>* get_converters();
|
||||
|
||||
private:
|
||||
static std::string m_module;
|
||||
static std::string m_py_class;
|
||||
static boost::python::export_converter_object_base<T>* imported_converters;
|
||||
};
|
||||
private:
|
||||
static std::string m_module;
|
||||
static std::string m_py_class;
|
||||
static boost::python::export_converter_object_base<T>* imported_converters;
|
||||
};
|
||||
|
||||
template <class T> std::string import_extension_class<T>::m_module;
|
||||
template <class T> std::string import_extension_class<T>::m_py_class;
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::imported_converters = 0;
|
||||
template <class T> std::string import_extension_class<T>::m_module;
|
||||
template <class T> std::string import_extension_class<T>::m_py_class;
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::imported_converters = 0;
|
||||
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::get_converters() {
|
||||
if (imported_converters == 0) {
|
||||
void* cobject
|
||||
= import_converter_object(m_module, m_py_class,
|
||||
converters_attribute_name);
|
||||
imported_converters
|
||||
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
|
||||
check_export_converters_api(
|
||||
export_converters_api_major,
|
||||
export_converters_api_minor,
|
||||
imported_converters->get_api_major(),
|
||||
imported_converters->get_api_minor());
|
||||
}
|
||||
return imported_converters;
|
||||
template <class T>
|
||||
boost::python::export_converter_object_base<T>*
|
||||
import_extension_class<T>::get_converters() {
|
||||
if (imported_converters == 0) {
|
||||
void* cobject
|
||||
= import_converter_object(m_module, m_py_class,
|
||||
converters_attribute_name);
|
||||
imported_converters
|
||||
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
|
||||
check_export_converters_api(
|
||||
export_converters_api_major,
|
||||
export_converters_api_minor,
|
||||
imported_converters->get_api_major(),
|
||||
imported_converters->get_api_minor());
|
||||
}
|
||||
return imported_converters;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP
|
||||
# define DEFAULT_CALL_POLICIES_DWA2002131_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/to_python_value.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T> struct to_python_value;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// for "readable" error messages
|
||||
template <class T> struct specify_a_result_policy_to_wrap_functions_returning
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
struct default_result_converter;
|
||||
|
||||
struct default_call_policies
|
||||
{
|
||||
// Nothing to do
|
||||
static bool precall(PyObject*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pass the result through
|
||||
static PyObject* postcall(PyObject*, PyObject* result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef default_result_converter result_converter;
|
||||
};
|
||||
|
||||
struct default_result_converter
|
||||
{
|
||||
template <class R>
|
||||
struct apply
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference<R>::value || is_pointer<R>::value);
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
is_illegal
|
||||
, detail::specify_a_result_policy_to_wrap_functions_returning<R>
|
||||
, boost::python::to_python_value<
|
||||
typename add_reference<typename add_const<R>::type>::type
|
||||
>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
// Exceptions for c strings an PyObject*s
|
||||
template <>
|
||||
struct default_result_converter::apply<char const*>
|
||||
{
|
||||
typedef boost::python::to_python_value<char const*const&> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct default_result_converter::apply<PyObject*>
|
||||
{
|
||||
typedef boost::python::to_python_value<PyObject*const&> type;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // DEFAULT_CALL_POLICIES_DWA2002131_HPP
|
||||
@@ -1,341 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// This work was funded in part by Lawrence Berkeley National Labs
|
||||
//
|
||||
// This file generated for 5-argument member functions and 6-argument free
|
||||
// functions by gen_arg_tuple_size.python
|
||||
|
||||
#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
# define ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
|
||||
# include <boost/python/detail/char_array.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// Computes (at compile-time) the number of elements that a Python
|
||||
// argument tuple must have in order to be passed to a wrapped C++
|
||||
// (member) function of the given type.
|
||||
template <class F> struct arg_tuple_size;
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__)
|
||||
|
||||
template <class R>
|
||||
struct arg_tuple_size<R (*)()>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 0);
|
||||
};
|
||||
|
||||
template <class R, class A1>
|
||||
struct arg_tuple_size<R (*)(A1)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2>
|
||||
struct arg_tuple_size<R (*)(A1, A2)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5, A6)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)()>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
// Metrowerks thinks this creates ambiguities
|
||||
# if !defined(__MWERKS__) || __MWERKS__ > 0x2406
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)() const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) const>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)() volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)() const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) const volatile>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
# endif // __MWERKS__
|
||||
# else
|
||||
|
||||
// We will use the "sizeof() trick" to work around the lack of
|
||||
// partial specialization in MSVC6 and its broken-ness in borland.
|
||||
// See http://opensource.adobe.com or
|
||||
// http://groups.yahoo.com/group/boost/message/5441 for
|
||||
// more examples
|
||||
|
||||
// The following helper functions are never actually called, since
|
||||
// they are only used within a sizeof() expression, but the type of
|
||||
// their return value is used to discriminate between various free
|
||||
// and member function pointers at compile-time.
|
||||
|
||||
template <class R>
|
||||
char_array<0> arg_tuple_size_helper(R (*)());
|
||||
|
||||
template <class R, class A1>
|
||||
char_array<1> arg_tuple_size_helper(R (*)(A1));
|
||||
|
||||
template <class R, class A1, class A2>
|
||||
char_array<2> arg_tuple_size_helper(R (*)(A1, A2));
|
||||
|
||||
template <class R, class A1, class A2, class A3>
|
||||
char_array<3> arg_tuple_size_helper(R (*)(A1, A2, A3));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4>
|
||||
char_array<4> arg_tuple_size_helper(R (*)(A1, A2, A3, A4));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<5> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
char_array<6> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5, A6));
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)());
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1));
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5));
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() const);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const);
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() volatile);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) volatile);
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() const volatile);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const volatile);
|
||||
|
||||
|
||||
template <class F>
|
||||
struct arg_tuple_size
|
||||
{
|
||||
// The sizeof() magic happens here
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value
|
||||
= sizeof(arg_tuple_size_helper(F(0)).elements) - 1);
|
||||
};
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# define BASE_OBJECT_DWA051600_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/signatures.hpp> // really just for type<>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <cstring>
|
||||
|
||||
@@ -20,10 +21,10 @@ namespace boost { namespace python { namespace detail {
|
||||
|
||||
// base_object - adds a constructor and non-virtual destructor to a
|
||||
// base Python type (e.g. PyObject, PyTypeObject).
|
||||
template <class PythonType>
|
||||
struct base_object : PythonType
|
||||
template <class python_type>
|
||||
struct base_object : python_type
|
||||
{
|
||||
typedef PythonType base_python_type;
|
||||
typedef python_type base_python_type;
|
||||
|
||||
// Initializes type and reference count. All other fields of base_python_type are 0
|
||||
base_object(PyTypeObject* type_obj);
|
||||
@@ -38,19 +39,22 @@ typedef base_object<PyTypeObject> python_type;
|
||||
|
||||
|
||||
//
|
||||
// base_object member function implementations
|
||||
// class_t template member function implementations
|
||||
//
|
||||
template <class PythonType>
|
||||
base_object<PythonType>::base_object(PyTypeObject* type_obj)
|
||||
template <class python_type>
|
||||
base_object<python_type>::base_object(PyTypeObject* type_obj)
|
||||
{
|
||||
base_python_type* bp = this;
|
||||
BOOST_CSTD_::memset(bp, 0, sizeof(base_python_type));
|
||||
#if !defined(_MSC_VER) || defined(__STLPORT)
|
||||
std::
|
||||
#endif
|
||||
memset(bp, 0, sizeof(base_python_type));
|
||||
Py_INCREF(type_obj);
|
||||
PyObject_INIT(bp, type_obj);
|
||||
}
|
||||
|
||||
template <class PythonType>
|
||||
inline base_object<PythonType>::~base_object()
|
||||
template <class python_type>
|
||||
inline base_object<python_type>::~base_object()
|
||||
{
|
||||
Py_DECREF(ob_type);
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CALL_OBJECT_DWA20011222_HPP
|
||||
# define CALL_OBJECT_DWA20011222_HPP
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/detail/types.hpp>
|
||||
# include <boost/bind.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// A function object adaptor which turns a function returning R into
|
||||
// an "equivalent" function returning void, but taking an R& in
|
||||
// which the adapted function's result is stored.
|
||||
template <class R, class F>
|
||||
struct return_by_reference
|
||||
{
|
||||
typedef void return_type;
|
||||
|
||||
return_by_reference(R& result, F f)
|
||||
: m_result(result)
|
||||
, m_f(f)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
m_result = m_f();
|
||||
}
|
||||
|
||||
R& m_result;
|
||||
F m_f;
|
||||
};
|
||||
|
||||
// An object generator for the above adaptors
|
||||
template <class R, class F>
|
||||
return_by_reference<R,F> bind_return(R& result, F f)
|
||||
{
|
||||
return return_by_reference<R,F>(result, f);
|
||||
}
|
||||
|
||||
// Given a function object f with signature
|
||||
//
|
||||
// R f(PyTypeObject*,PyObject*)
|
||||
//
|
||||
// calls f inside of handle_exception_impl, placing f's result in
|
||||
// ret. Returns true iff an exception is thrown by f, leaving ret
|
||||
// unmodified.
|
||||
template <class R, class F>
|
||||
bool call_object(R& ret, PyObject* obj, F f)
|
||||
{
|
||||
return handle_exception(
|
||||
detail::bind_return(
|
||||
ret
|
||||
, boost::bind<R>(
|
||||
f, static_cast<type_object_base*>(obj->ob_type), obj)));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CALL_OBJECT_DWA20011222_HPP
|
||||
@@ -1,217 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CALLER_DWA20011214_HPP
|
||||
# define CALLER_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/eval.hpp>
|
||||
# include <boost/python/detail/returning.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <class T> struct to_python;
|
||||
}}
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct caller
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
|
||||
template <class P, class R>
|
||||
PyObject* operator()(R (*f)(), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (*f)(A0), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (*f)(A0, A1), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)(), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)() const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)() volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0>
|
||||
PyObject* operator()(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1>
|
||||
PyObject* operator()(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
|
||||
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
|
||||
{
|
||||
return returning<R>::call(f, args, keywords, policies);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CALLER_DWA20011214_HPP
|
||||
@@ -9,13 +9,20 @@
|
||||
#ifndef CAST_DWA052500_H_
|
||||
# define CAST_DWA052500_H_
|
||||
|
||||
# ifndef BOOST_PYTHON_V2
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail {
|
||||
// The default way of converting a PyObject* or PyTypeObject* to a T*
|
||||
template <class T>
|
||||
struct downcast_traits
|
||||
{
|
||||
template <class U>
|
||||
static T* cast(U* p) { return static_cast<T*>(p); }
|
||||
};
|
||||
|
||||
inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p)
|
||||
{
|
||||
return reinterpret_cast<PyTypeObject*>(p);
|
||||
@@ -44,30 +51,25 @@ inline PyObject* as_object(PyTypeObject* p) { return reinterpret_cast<PyObject*>
|
||||
// If I didn't have to support stupid MSVC6 we could just use a simple template function:
|
||||
// template <class T> T* downcast(PyObject*).
|
||||
template <class T>
|
||||
struct downcast
|
||||
struct downcast : boost::dereferenceable<downcast<T>, T*>
|
||||
{
|
||||
downcast(PyObject* p)
|
||||
: m_p(static_cast<T*>(detail::as_base_object((T*)0, p)))
|
||||
: m_p(detail::downcast_traits<T>::cast(detail::as_base_object((T*)0, p)))
|
||||
{}
|
||||
|
||||
downcast(const PyObject* p)
|
||||
: m_p(static_cast<T*>(detail::as_base_object((const T*)0, p)))
|
||||
: m_p(detail::downcast_traits<T>::cast(detail::as_base_object((const T*)0, p)))
|
||||
{}
|
||||
|
||||
downcast(PyTypeObject* p)
|
||||
: m_p(static_cast<T*>(p))
|
||||
: m_p(detail::downcast_traits<T>::cast(p))
|
||||
{}
|
||||
|
||||
downcast(const PyTypeObject* p)
|
||||
: m_p(static_cast<T*>(p))
|
||||
: m_p(detail::downcast_traits<T>::cast(p))
|
||||
{}
|
||||
|
||||
operator T*() const { return m_p; }
|
||||
|
||||
// MSVC doesn't like boost::dereferencable unless T has a default
|
||||
// constructor, so operator-> must be defined by hand :(
|
||||
T* operator->() const { return &**this; }
|
||||
|
||||
T* get() const { return m_p; }
|
||||
T& operator*() const { return *m_p; }
|
||||
private:
|
||||
@@ -76,6 +78,4 @@ struct downcast
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
# endif // BOOST_PYTHON_V2
|
||||
|
||||
#endif // CAST_DWA052500_H_
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CHAR_ARRAY_DWA2002129_HPP
|
||||
# define CHAR_ARRAY_DWA2002129_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// This little package is used to transmit the number of arguments
|
||||
// from the helper functions below to the sizeof() expression below.
|
||||
// Because we can never have an array of fewer than 1 element, we
|
||||
// add 1 to n and then subtract 1 from the result of sizeof() below.
|
||||
template <int n>
|
||||
struct char_array
|
||||
{
|
||||
char elements[n+1];
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CHAR_ARRAY_DWA2002129_HPP
|
||||
@@ -57,113 +57,10 @@
|
||||
# define BOOST_CSTD_ std
|
||||
# endif
|
||||
|
||||
# ifndef BOOST_PYTHON_MODULE_INIT
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
|
||||
# else
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Set up dll import/export options:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
// backwards compatibility:
|
||||
#ifdef BOOST_PYTHON_STATIC_LIB
|
||||
# define BOOST_PYTHON_STATIC_LINK
|
||||
#endif
|
||||
|
||||
#if defined(__MWERKS__) \
|
||||
|| (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730)
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern
|
||||
#endif
|
||||
|
||||
// Handle default cases
|
||||
#ifndef BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
|
||||
# ifdef _WIN32
|
||||
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
|
||||
# else
|
||||
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32)
|
||||
# if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_DECL __declspec(dllexport)
|
||||
# define BOOST_PYTHON_BUILD_DLL
|
||||
# else
|
||||
# define BOOST_PYTHON_DECL __declspec(dllimport)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_DECL
|
||||
# define BOOST_PYTHON_DECL
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_DECL_TEMPLATE
|
||||
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
# define BOOST_PYTHON_DECL_TEMPLATE BOOST_PYTHON_DECL
|
||||
# else
|
||||
# define BOOST_PYTHON_DECL_TEMPLATE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
|
||||
#ifdef _WIN32
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name()
|
||||
#else
|
||||
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
|
||||
#endif
|
||||
|
||||
# ifndef BOOST_PYTHON_EXPORT_TEMPLATE
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template
|
||||
# endif
|
||||
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL
|
||||
|
||||
// Borland C++ Fix/error check:
|
||||
#if defined(__BORLANDC__)
|
||||
# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
|
||||
// problems with std::basic_string and dll RTL:
|
||||
# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)
|
||||
# ifdef BOOST_PYTHON_BUILD_DLL
|
||||
# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL
|
||||
# else
|
||||
# pragma warn defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!
|
||||
# endif
|
||||
# endif
|
||||
# ifndef _RTLDLL
|
||||
// this is harmless for a static link:
|
||||
# define _RWSTD_COMPILE_INSTANTIATE
|
||||
# endif
|
||||
# endif
|
||||
//
|
||||
// VCL support:
|
||||
// if we're building a console app then there can't be any VCL (can there?)
|
||||
# if !defined(__CONSOLE__) && !defined(_NO_VCL)
|
||||
# define BOOST_PYTHON_USE_VCL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
|
||||
// Work around a compiler bug.
|
||||
// boost::python::detail::function has to be seen by the compiler before the
|
||||
// boost::function class template.
|
||||
namespace boost { namespace python { namespace detail {
|
||||
class function;
|
||||
}}}
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name()
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_DWA052200_H_
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CV_CATEGORY_DWA200222_HPP
|
||||
# define CV_CATEGORY_DWA200222_HPP
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <bool is_const_, bool is_volatile_>
|
||||
struct cv_tag
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_const = is_const_);
|
||||
BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_);
|
||||
};
|
||||
|
||||
typedef cv_tag<false,false> cv_unqualified;
|
||||
typedef cv_tag<true,false> const_;
|
||||
typedef cv_tag<false,true> volatile_;
|
||||
typedef cv_tag<true,true> const_volatile_;
|
||||
|
||||
template <class T>
|
||||
struct cv_category
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
|
||||
typedef cv_tag<c,v> type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CV_CATEGORY_DWA200222_HPP
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef EVAL_DWA2002124_HPP
|
||||
# define EVAL_DWA2002124_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class T> struct undefined;
|
||||
template <class UnaryMetaFunction, class T>
|
||||
struct eval
|
||||
{
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
|
||||
// based on the (non-conforming) MSVC trick from MPL
|
||||
template<bool>
|
||||
struct unarymetafunction_vc : UnaryMetaFunction {};
|
||||
|
||||
// illegal C++ which causes VC to admit that unarymetafunction_vc
|
||||
// can have a nested template:
|
||||
template<>
|
||||
struct unarymetafunction_vc<true>
|
||||
{
|
||||
template<class> struct apply;
|
||||
};
|
||||
|
||||
typedef typename unarymetafunction_vc<
|
||||
::boost::mpl::detail::msvc_never_true<UnaryMetaFunction>::value
|
||||
>::template apply<T>::type type;
|
||||
# else
|
||||
typedef typename UnaryMetaFunction::template apply<T>::type type;
|
||||
# endif
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // EVAL_DWA2002124_HPP
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
@@ -26,7 +26,7 @@
|
||||
# include <memory>
|
||||
# include <boost/python/detail/init_function.hpp>
|
||||
# include <typeinfo>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
# include <boost/type_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
@@ -38,51 +38,26 @@ template <class T> struct right_operand;
|
||||
|
||||
enum without_downcast_t { without_downcast };
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace detail {
|
||||
|
||||
// forward declarations
|
||||
class extension_instance;
|
||||
class extension_class_base;
|
||||
template <class T> class instance_holder;
|
||||
template <class T, class U> class instance_value_holder;
|
||||
template <class ref, class T> class instance_ptr_holder;
|
||||
template <class Specified> struct operand_select;
|
||||
class extension_instance;
|
||||
class extension_class_base;
|
||||
template <class T> class instance_holder;
|
||||
template <class T, class U> class instance_value_holder;
|
||||
template <class ref, class T> class instance_ptr_holder;
|
||||
template <class Specified> struct operand_select;
|
||||
template <long> struct choose_op;
|
||||
template <long> struct choose_rop;
|
||||
template <long> struct choose_unary_op;
|
||||
template <long> struct define_operator;
|
||||
|
||||
class BOOST_PYTHON_DECL extension_instance : public instance
|
||||
{
|
||||
public:
|
||||
extension_instance(PyTypeObject* class_);
|
||||
~extension_instance();
|
||||
|
||||
void add_implementation(std::auto_ptr<instance_holder_base> holder);
|
||||
|
||||
typedef std::vector<instance_holder_base*> held_objects;
|
||||
const held_objects& wrapped_objects() const
|
||||
{ return m_wrapped_objects; }
|
||||
private:
|
||||
held_objects m_wrapped_objects;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t<detail::extension_instance>;
|
||||
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class<detail::extension_instance>;
|
||||
# endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
BOOST_PYTHON_DECL meta_class<extension_instance>* extension_meta_class();
|
||||
BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p);
|
||||
BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&);
|
||||
BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&);
|
||||
meta_class<extension_instance>* extension_meta_class();
|
||||
extension_instance* get_extension_instance(PyObject* p);
|
||||
void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
|
||||
void report_missing_class_object(const std::type_info&);
|
||||
void report_released_smart_pointer(const std::type_info&);
|
||||
|
||||
template <class T>
|
||||
T* check_non_null(T* p)
|
||||
@@ -96,7 +71,7 @@ template <class Held> class held_instance;
|
||||
|
||||
typedef void* (*conversion_function_ptr)(void*);
|
||||
|
||||
struct BOOST_PYTHON_DECL base_class_info
|
||||
struct base_class_info
|
||||
{
|
||||
base_class_info(extension_class_base* t, conversion_function_ptr f)
|
||||
:class_object(t), convert(f)
|
||||
@@ -110,7 +85,7 @@ typedef base_class_info derived_class_info;
|
||||
|
||||
struct add_operator_base;
|
||||
|
||||
class BOOST_PYTHON_DECL extension_class_base : public class_t<extension_instance>
|
||||
class extension_class_base : public class_t<extension_instance>
|
||||
{
|
||||
public:
|
||||
extension_class_base(const char* name);
|
||||
@@ -258,9 +233,6 @@ class python_extension_class_converters
|
||||
}
|
||||
boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::python::argument_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Convert to T*
|
||||
@@ -289,9 +261,6 @@ class python_extension_class_converters
|
||||
}
|
||||
boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::python::argument_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return *(PtrType*)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Extract from obj a reference to the PtrType object which is holding a
|
||||
@@ -403,7 +372,7 @@ namespace detail {
|
||||
|
||||
template <class T> class instance_holder;
|
||||
|
||||
class BOOST_PYTHON_DECL read_only_setattr_function : public function
|
||||
class read_only_setattr_function : public function
|
||||
{
|
||||
public:
|
||||
read_only_setattr_function(const char* name);
|
||||
@@ -647,12 +616,6 @@ class extension_class
|
||||
choose_op<(which & op_and)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_xor)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_or)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_gt)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_ge)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_lt)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_le)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_eq)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_ne)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
|
||||
@@ -682,12 +645,6 @@ class extension_class
|
||||
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_gt)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_ge)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_lt)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_le)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_eq)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_ne)>::template args<Left,Right>::add(this);
|
||||
}
|
||||
|
||||
template <long which, class Left, class Right>
|
||||
@@ -727,85 +684,30 @@ class held_instance : public Held
|
||||
public:
|
||||
held_instance(PyObject*) : Held() {}
|
||||
template <class A1>
|
||||
held_instance(PyObject*, A1 a1) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)) {}
|
||||
held_instance(PyObject*, A1 a1) : Held(a1) {}
|
||||
template <class A1, class A2>
|
||||
held_instance(PyObject*, A1 a1, A2 a2) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {}
|
||||
template <class A1, class A2, class A3>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {}
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)
|
||||
, typename unwrap_parameter<A8>::type(a8)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(a1, a2, a3, a4, a5, a6, a7, a8) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)
|
||||
, typename unwrap_parameter<A8>::type(a8)
|
||||
, typename unwrap_parameter<A9>::type(a9)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(
|
||||
typename unwrap_parameter<A1>::type(a1)
|
||||
, typename unwrap_parameter<A2>::type(a2)
|
||||
, typename unwrap_parameter<A3>::type(a3)
|
||||
, typename unwrap_parameter<A4>::type(a4)
|
||||
, typename unwrap_parameter<A5>::type(a5)
|
||||
, typename unwrap_parameter<A6>::type(a6)
|
||||
, typename unwrap_parameter<A7>::type(a7)
|
||||
, typename unwrap_parameter<A8>::type(a8)
|
||||
, typename unwrap_parameter<A9>::type(a9)
|
||||
, typename unwrap_parameter<A10>::type(a10)) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
|
||||
};
|
||||
|
||||
// Abstract base class for all obj holders. Base for template class
|
||||
// instance_holder<>, below.
|
||||
class BOOST_PYTHON_DECL instance_holder_base
|
||||
class instance_holder_base
|
||||
{
|
||||
public:
|
||||
virtual ~instance_holder_base() {}
|
||||
@@ -893,6 +795,21 @@ class instance_ptr_holder : public instance_holder<HeldType>
|
||||
PtrType m_ptr;
|
||||
};
|
||||
|
||||
class extension_instance : public instance
|
||||
{
|
||||
public:
|
||||
extension_instance(PyTypeObject* class_);
|
||||
~extension_instance();
|
||||
|
||||
void add_implementation(std::auto_ptr<instance_holder_base> holder);
|
||||
|
||||
typedef std::vector<instance_holder_base*> held_objects;
|
||||
const held_objects& wrapped_objects() const
|
||||
{ return m_wrapped_objects; }
|
||||
private:
|
||||
held_objects m_wrapped_objects;
|
||||
};
|
||||
|
||||
//
|
||||
// Template function implementations
|
||||
//
|
||||
|
||||
@@ -29,7 +29,7 @@ class extension_instance;
|
||||
// function --
|
||||
// the common base class for all overloadable function and method objects
|
||||
// supplied by the library.
|
||||
class BOOST_PYTHON_DECL function : public python_object
|
||||
class function : public python_object
|
||||
{
|
||||
public:
|
||||
function();
|
||||
@@ -46,7 +46,7 @@ class BOOST_PYTHON_DECL function : public python_object
|
||||
private:
|
||||
struct type_object;
|
||||
private:
|
||||
reference<function> m_overloads; // A linked list of the function overloads
|
||||
reference<function> m_overloads;
|
||||
};
|
||||
|
||||
// wrapped_function_pointer<> --
|
||||
@@ -59,25 +59,20 @@ class BOOST_PYTHON_DECL function : public python_object
|
||||
template <class R, class F>
|
||||
struct wrapped_function_pointer : function
|
||||
{
|
||||
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
|
||||
|
||||
wrapped_function_pointer(ptr_fun pf)
|
||||
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
|
||||
|
||||
wrapped_function_pointer(ptr_fun pf)
|
||||
: m_pf(pf) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
// This is where the boundary between the uniform Python function
|
||||
// interface and the statically-checked C++ function interface is
|
||||
// crossed.
|
||||
return caller<R>::call(m_pf, args, keywords);
|
||||
}
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{ return caller<R>::call(m_pf, args, keywords); }
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(F).name(); }
|
||||
|
||||
private:
|
||||
const ptr_fun m_pf;
|
||||
const ptr_fun m_pf;
|
||||
};
|
||||
|
||||
// raw_arguments_function
|
||||
@@ -87,13 +82,13 @@ struct wrapped_function_pointer : function
|
||||
template <class Ret, class Args, class Keywords>
|
||||
struct raw_arguments_function : function
|
||||
{
|
||||
typedef Ret (*ptr_fun)(Args, Keywords);
|
||||
|
||||
raw_arguments_function(ptr_fun pf)
|
||||
typedef Ret (*ptr_fun)(Args, Keywords);
|
||||
|
||||
raw_arguments_function(ptr_fun pf)
|
||||
: m_pf(pf) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
ref dict(keywords ?
|
||||
ref(keywords, ref::increment_count) :
|
||||
@@ -108,7 +103,7 @@ struct raw_arguments_function : function
|
||||
{ return typeid(ptr_fun).name(); }
|
||||
|
||||
private:
|
||||
const ptr_fun m_pf;
|
||||
const ptr_fun m_pf;
|
||||
};
|
||||
|
||||
// virtual_function<> --
|
||||
@@ -127,19 +122,19 @@ template <class T, class R, class V, class D>
|
||||
class virtual_function : public function
|
||||
{
|
||||
public:
|
||||
virtual_function(V virtual_function_ptr, D default_implementation)
|
||||
virtual_function(V virtual_function_ptr, D default_implementation)
|
||||
: m_virtual_function_ptr(virtual_function_ptr),
|
||||
m_default_implementation(default_implementation)
|
||||
{}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(V).name(); }
|
||||
|
||||
private:
|
||||
const V m_virtual_function_ptr;
|
||||
const V m_virtual_function_ptr;
|
||||
const D m_default_implementation;
|
||||
};
|
||||
|
||||
@@ -160,7 +155,7 @@ template <class F>
|
||||
inline function* new_wrapped_function(F pmf)
|
||||
{
|
||||
// Deduce the return type and pass it off to the helper function above
|
||||
return new_wrapped_function_aux(return_value(pmf), pmf);
|
||||
return new_wrapped_function_aux(return_value(pmf), pmf);
|
||||
}
|
||||
|
||||
template <class R, class Args, class keywords>
|
||||
@@ -201,7 +196,7 @@ inline function* new_virtual_function(
|
||||
// the expression a.b where a is an instance or extension_instance object and b
|
||||
// is a callable object not found in the obj namespace but on its class or
|
||||
// a base class.
|
||||
class BOOST_PYTHON_DECL bound_function : public python_object
|
||||
class bound_function : public python_object
|
||||
{
|
||||
public:
|
||||
static bound_function* create(const ref& target, const ref& fn);
|
||||
@@ -220,7 +215,7 @@ class BOOST_PYTHON_DECL bound_function : public python_object
|
||||
private: // data members for allocation/deallocation optimization
|
||||
bound_function* m_free_list_link;
|
||||
|
||||
static bound_function* free_list;
|
||||
static bound_function* free_list;
|
||||
};
|
||||
|
||||
// Special functions designed to access data members of a wrapped C++ object.
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef INDIRECT_TRAITS_DWA2002131_HPP
|
||||
# define INDIRECT_TRAITS_DWA2002131_HPP
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_reference_to_const
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_const<T const&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_volatile
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_volatile<T volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T*&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T* const&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T* volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer<T* const volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
# else
|
||||
|
||||
typedef char (&inner_yes_type)[3];
|
||||
typedef char (&inner_no_type)[2];
|
||||
typedef char (&outer_no_type)[1];
|
||||
|
||||
template <typename V>
|
||||
struct is_const_help
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_const<V>::value
|
||||
, inner_yes_type
|
||||
, inner_no_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct is_volatile_help
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_volatile<V>::value
|
||||
, inner_yes_type
|
||||
, inner_no_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct is_pointer_help
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_pointer<V>::value
|
||||
, inner_yes_type
|
||||
, inner_no_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
typename is_const_help<V>::type reference_to_const_helper(V&);
|
||||
outer_no_type
|
||||
reference_to_const_helper(...);
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_const
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)));
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)));
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
typename is_volatile_help<V>::type reference_to_volatile_helper(V&);
|
||||
outer_no_type reference_to_volatile_helper(...);
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_volatile
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)));
|
||||
};
|
||||
|
||||
|
||||
template <typename V>
|
||||
typename is_pointer_help<V>::type reference_to_pointer_helper(V&);
|
||||
outer_no_type reference_to_pointer_helper(...);
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_pointer_helper(t)) == sizeof(inner_yes_type))
|
||||
);
|
||||
};
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // INDIRECT_TRAITS_DWA2002131_HPP
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
@@ -73,8 +73,7 @@ namespace detail {
|
||||
struct parameter_traits
|
||||
{
|
||||
private:
|
||||
enum { is_ref = boost::is_reference<T>::value };
|
||||
typedef const_ref_selector<is_ref> selector;
|
||||
typedef const_ref_selector<boost::is_reference<T>::value> selector;
|
||||
public:
|
||||
typedef typename selector::template const_ref<T>::type const_reference;
|
||||
};
|
||||
@@ -89,14 +88,11 @@ namespace detail {
|
||||
typedef void const_reference;
|
||||
};
|
||||
|
||||
struct reference_parameter_base {};
|
||||
|
||||
template <class T>
|
||||
class reference_parameter
|
||||
: public reference_parameter_base
|
||||
{
|
||||
public:
|
||||
typedef typename parameter_traits<T>::const_reference const_reference;
|
||||
public:
|
||||
reference_parameter(const_reference value)
|
||||
: value(value) {}
|
||||
operator const_reference() { return value; }
|
||||
@@ -104,51 +100,6 @@ namespace detail {
|
||||
const_reference value;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct unwrap_parameter
|
||||
{
|
||||
typedef typename boost::add_reference<T>::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unwrap_parameter<reference_parameter<T> >
|
||||
{
|
||||
typedef typename reference_parameter<T>::const_reference type;
|
||||
};
|
||||
# else
|
||||
template <bool is_wrapped>
|
||||
struct unwrap_parameter_helper
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::const_reference type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwrap_parameter_helper<false>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename add_reference<T>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unwrap_parameter
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, is_wrapped = (is_base_and_derived<T,reference_parameter_base>::value));
|
||||
|
||||
typedef typename unwrap_parameter_helper<
|
||||
is_wrapped
|
||||
>::template apply<T>::type type;
|
||||
};
|
||||
# endif
|
||||
|
||||
class extension_instance;
|
||||
class instance_holder_base;
|
||||
|
||||
@@ -278,7 +229,7 @@ struct init_function
|
||||
}
|
||||
};
|
||||
|
||||
class BOOST_PYTHON_DECL init : public function
|
||||
class init : public function
|
||||
{
|
||||
private: // override function hook
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef MAP_ENTRY_DWA2002118_HPP
|
||||
# define MAP_ENTRY_DWA2002118_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// A trivial type that works well as the value_type of associative
|
||||
// vector maps
|
||||
template <class Key, class Value>
|
||||
struct map_entry
|
||||
{
|
||||
map_entry() {}
|
||||
map_entry(Key k) : key(k), value() {}
|
||||
map_entry(Key k, Value v) : key(k), value(v) {}
|
||||
|
||||
bool operator<(map_entry const& rhs) const
|
||||
{
|
||||
return this->key < rhs.key;
|
||||
}
|
||||
|
||||
Key key;
|
||||
Value value;
|
||||
};
|
||||
|
||||
template <class Key, class Value>
|
||||
bool operator<(map_entry<Key,Value> const& e, Key const& k)
|
||||
{
|
||||
return e.key < k;
|
||||
}
|
||||
|
||||
template <class Key, class Value>
|
||||
bool operator<(Key const& k, map_entry<Key,Value> const& e)
|
||||
{
|
||||
return k < e.key;
|
||||
}
|
||||
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // MAP_ENTRY_DWA2002118_HPP
|
||||
@@ -1,99 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef MSVC_TYPEINFO_DWA200222_HPP
|
||||
# define MSVC_TYPEINFO_DWA200222_HPP
|
||||
|
||||
#include <boost/type.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
//
|
||||
// Fix for MSVC's broken typeid() implementation which doesn't strip
|
||||
// decoration. This fix doesn't handle cv-qualified array types. It
|
||||
// could probably be done, but I haven't figured it out yet.
|
||||
//
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
typedef std::type_info const& typeinfo;
|
||||
|
||||
template<int>struct value_id_accessor;
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<0>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<1>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T const*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<2>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T volatile*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<3>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T const volatile*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template <bool> struct bool_t{};
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_nonref(boost::type<T>* = 0)
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
|
||||
return value_id_accessor<(2 * v + c)>::get((T*)0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_ref(boost::type<T>*, ...)
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class U, class T>
|
||||
inline typeinfo typeid_ref(boost::type<U>*, T& (*)())
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_array(bool_t<false>, boost::type<T>* = 0)
|
||||
{
|
||||
typedef T (*x)();
|
||||
return typeid_ref((boost::type<T>*)0, x(0));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_array(bool_t<true>, boost::type<T>* = 0)
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo msvc_typeid(boost::type<T>* = 0)
|
||||
{
|
||||
typedef bool_t<is_array<T>::value> tag;
|
||||
return typeid_array(tag(), (boost::type<T>*)0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
# endif // BOOST_MSVC
|
||||
#endif // MSVC_TYPEINFO_DWA200222_HPP
|
||||
@@ -1,183 +0,0 @@
|
||||
#error obsolete
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2000
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_libary_include.hpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers.
|
||||
* Note this is an internal header file included
|
||||
* by regex.hpp, do not include on its own.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
#define BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
#ifndef BOOST_REGEX_NO_LIB
|
||||
|
||||
#if defined(BOOST_MSVC) && !defined(BOOST_REGEX_BUILD_DLL)
|
||||
#ifdef __SGI_STL_PORT
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#if defined(_DEBUG) && defined(__STL_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300ddl.lib")
|
||||
#elif defined(_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc6-stlport-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc6-stlport-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#if defined(_DEBUG) && defined(__STL_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300ddm.lib")
|
||||
#elif defined(_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-stlport-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
// STLPort does not support single threaded builds:
|
||||
#error STLPort does not support single threaded builds
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#elif _MSC_VER < 1300
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc6-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc6-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300d.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-re300.lib")
|
||||
#endif //_DEBUG
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#else
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc7-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc7-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc7-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300d.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc7-re300.lib")
|
||||
#endif //_DEBUG
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#endif // __SGI_STL_PORT
|
||||
#endif //BOOST_MSVC
|
||||
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(BOOST_REGEX_BUILD_DLL)
|
||||
|
||||
#if __BORLANDC__ < 0x550
|
||||
|
||||
#ifdef BOOST_REGEX_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "bcb4re300lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "bcb4re300v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb4re300lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb4re300l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb4re300m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb4re300.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#else // C++ Builder 5:
|
||||
|
||||
#ifdef BOOST_REGEX_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "bcb5re300lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "bcb5re300v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb5re300lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb5re300l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb5re300m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb5re300.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#endif
|
||||
|
||||
#endif //__BORLANDC__
|
||||
|
||||
#endif //BOOST_REGEX_NO_LIB
|
||||
|
||||
#endif // BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user