2
0
mirror of https://github.com/boostorg/python.git synced 2026-02-02 09:02:15 +00:00

Compare commits

...

101 Commits

Author SHA1 Message Date
nobody
ca162434ca This commit was manufactured by cvs2svn to create branch 'RC_1_27_0'.
[SVN r12739]
2002-02-06 03:32:50 +00:00
Dave Abrahams
8ff5450ece moved contents of builtin_to_python_converters.hpp to builtin_converters.hpp
[SVN r12705]
2002-02-04 20:14:53 +00:00
Dave Abrahams
5d30ddac22 cxx 6.5 fixes
[SVN r12689]
2002-02-04 14:49:43 +00:00
Dave Abrahams
80f697ef2a more bug fixes for really conformant compilers
[SVN r12682]
2002-02-04 01:58:08 +00:00
Dave Abrahams
47c7748707 bug fix
[SVN r12681]
2002-02-04 01:42:47 +00:00
Dave Abrahams
9f33aa2afc bug fix
[SVN r12680]
2002-02-03 23:58:10 +00:00
Dave Abrahams
1dc6600b59 kill extra ;
[SVN r12679]
2002-02-03 23:51:16 +00:00
Dave Abrahams
1ec58c1161 bug fix
[SVN r12678]
2002-02-03 23:21:48 +00:00
Ralf W. Grosse-Kunstleve
d023d577b2 extra semicolon removed (cxx 6.3 diag.)
[SVN r12677]
2002-02-03 22:33:11 +00:00
Dave Abrahams
21d65ca0bf arbitrary argument/result adoption
[SVN r12664]
2002-02-03 06:34:15 +00:00
Dave Abrahams
bcf4401858 KCC ice workaround
[SVN r12663]
2002-02-03 05:09:31 +00:00
Dave Abrahams
262396d48b Object life support
[SVN r12662]
2002-02-03 05:03:05 +00:00
Dave Abrahams
0a9d5f680f initial checkin
[SVN r12661]
2002-02-03 05:02:46 +00:00
Dave Abrahams
64239f1c04 Allow indirect reference/pointer returns
[SVN r12659]
2002-02-03 03:05:39 +00:00
Dave Abrahams
7590d546f1 initial checkin
[SVN r12657]
2002-02-03 03:05:01 +00:00
Dave Abrahams
021070f066 Prepare to generalize
[SVN r12656]
2002-02-03 01:07:29 +00:00
Dave Abrahams
55a4318839 Handle references too
[SVN r12655]
2002-02-03 01:07:10 +00:00
Dave Abrahams
90647f30f8 Initial pointer adoption tests
Have instances actually dispose of their held C++ objects!


[SVN r12653]
2002-02-02 20:54:06 +00:00
Dave Abrahams
8cc9080d36 Initial pointer adoption tests
Have instances actually dispose of their held C++ objects!


[SVN r12652]
2002-02-02 20:48:37 +00:00
Darin Adler
6e5fc91885 New smart pointer documentation. Related clean-up of the smart pointer
library. Changing includes to include the new individual smart pointer
headers. Replacing old smart pointer library with an include of the new
smart pointer headers. Simplify ifdefs that involve the member templates
macros now that BOOST_MSVC6_MEMBER_TEMPLATES is also guaranteed to bet
set for platforms that have full member templates.


[SVN r12647]
2002-02-02 18:36:12 +00:00
Ralf W. Grosse-Kunstleve
71de2b5ec5 /Zm upgrade
[SVN r12637]
2002-02-02 15:19:59 +00:00
Ralf W. Grosse-Kunstleve
7703f91ee2 fix typo
[SVN r12636]
2002-02-02 15:17:37 +00:00
Dave Abrahams
ecc8abcc50 ice_ fixes for KCC
[SVN r12634]
2002-02-02 14:34:02 +00:00
Dave Abrahams
14917c9791 initial checkin
[SVN r12633]
2002-02-02 14:31:07 +00:00
Dave Abrahams
25c56164b0 Last rewrite of the type conversion mechanism, I hope
[SVN r12631]
2002-02-02 14:04:48 +00:00
Dave Abrahams
12988b879e *** empty log message ***
[SVN r12627]
2002-02-02 08:31:11 +00:00
Dave Abrahams
684e391a9a remove local rule usage for the time being.
[SVN r12626]
2002-02-02 00:49:24 +00:00
Dave Abrahams
7a16cd4c37 remove local rule usage for the time being.
[SVN r12625]
2002-02-02 00:46:38 +00:00
Dave Abrahams
b3117c2b02 Use call policies
[SVN r12618]
2002-02-01 04:36:46 +00:00
Dave Abrahams
6a75fa83b5 New conversion methods, builtin converters
----------------------------------------------------------------------

Committing in .

Modified Files:
	boost/python/reference_from_python.hpp
	boost/python/value_from_python.hpp
	boost/python/converter/body.hpp
	boost/python/converter/handle.hpp
	libs/python/src/converter/builtin_converters.cpp
	libs/python/test/m1.cpp libs/python/test/m2.cpp
Added Files:
	boost/python/converter/builtin_converters.hpp
	boost/python/converter/builtin_to_python_converters.hpp
	boost/python/converter/from_python.hpp
	boost/python/converter/from_python_data.hpp
	boost/python/converter/from_python_function.hpp
	boost/python/converter/to_python.hpp
	boost/python/converter/to_python_function.hpp
	boost/python/object/auto_ptr_generator.hpp
	boost/python/object/pointer_holder.hpp
	libs/python/src/converter/from_python.cpp
	libs/python/src/converter/to_python.cpp
	libs/python/test/test_builtin_converters.cpp
	libs/python/test/test_builtin_converters.py
Removed Files:
	boost/python/convert.hpp boost/python/converter/unwrap.hpp
	boost/python/converter/unwrapper.hpp
	boost/python/converter/wrap.hpp
	boost/python/converter/wrapper.hpp
	boost/python/object/class_unwrapper.hpp
----------------------------------------------------------------------


[SVN r12596]
2002-01-31 05:53:54 +00:00
Dave Abrahams
88a8721b89 initial checkin
[SVN r12592]
2002-01-30 22:18:50 +00:00
Dave Abrahams
1f12857551 initial checkin
[SVN r12591]
2002-01-30 22:12:07 +00:00
Dave Abrahams
71032f6c4c New conversion mechanism, builtin converters
[SVN r12590]
2002-01-30 20:18:39 +00:00
Dave Abrahams
088b1cab83 workarounds for KCC's reservation of 'overload' as a keyword
[SVN r12451]
2002-01-23 06:08:46 +00:00
Dave Abrahams
f40a534bfb cleanup
[SVN r12449]
2002-01-22 21:55:08 +00:00
Dave Abrahams
f278530239 Nicer syntactic sugar
[SVN r12448]
2002-01-22 19:56:36 +00:00
Dave Abrahams
0389aab0a3 Nicer syntactic sugar
[SVN r12447]
2002-01-22 19:51:04 +00:00
Dave Abrahams
51a66a3202 Fixes for gcc-2.95.3
[SVN r12442]
2002-01-22 13:52:05 +00:00
Dave Abrahams
248985e51a ICL compatibility
[SVN r12435]
2002-01-22 13:12:41 +00:00
Dave Abrahams
996d83eae0 fix for EDG
[SVN r12415]
2002-01-22 02:32:48 +00:00
Ralf W. Grosse-Kunstleve
98a1329dd7 default argument moved to declaration.
[SVN r12414]
2002-01-22 01:43:40 +00:00
Ralf W. Grosse-Kunstleve
ed2ebc7d3d added: missing // after #endif
[SVN r12405]
2002-01-21 21:18:47 +00:00
Dave Abrahams
41634f9998 Use ref everywhere for reliability
[SVN r12394]
2002-01-21 06:56:27 +00:00
Dave Abrahams
93501af046 always use ref (counting) for safety
[SVN r12393]
2002-01-21 06:23:33 +00:00
Dave Abrahams
078585db28 fixed transfer-of-ownership counting to avoid problems
[SVN r12392]
2002-01-21 06:20:15 +00:00
Dave Abrahams
03e9e4c1d9 Added class wrapping
[SVN r12387]
2002-01-21 00:47:05 +00:00
Dave Abrahams
4a1d077238 Added implicit conversion tests
[SVN r12386]
2002-01-20 23:54:26 +00:00
Dave Abrahams
f7a5e6deb8 Moved add_overload functionality to function::add_to_namespace
[SVN r12385]
2002-01-20 23:52:52 +00:00
Dave Abrahams
dabb22bb6a added class wrapping
[SVN r12384]
2002-01-20 23:52:36 +00:00
Dave Abrahams
3d03ca3d10 made it possible to initialize from type_info
[SVN r12383]
2002-01-20 23:50:52 +00:00
Dave Abrahams
386992c3b8 suppress gcc warning
[SVN r12382]
2002-01-20 23:43:36 +00:00
Dave Abrahams
a48f252cfa Moved add_overload functionality to function::add_to_namespace
[SVN r12381]
2002-01-20 23:41:56 +00:00
Dave Abrahams
c3a311ab85 Explicit qualifications help MSVC6
[SVN r12380]
2002-01-20 23:07:05 +00:00
Dave Abrahams
7926e1bc3c Fixes for reference parameters to constructors
[SVN r12364]
2002-01-20 03:08:08 +00:00
Dave Abrahams
b796db648a added default constructor for use with BGL
[SVN r12318]
2002-01-14 21:28:49 +00:00
Dave Abrahams
0964ecac8c cxx fixes
[SVN r12272]
2002-01-10 20:10:32 +00:00
Dave Abrahams
dd1ac7952b Modified Files:
boost/graph/breadth_first_search.hpp

		MSVC workaround

	boost/python/reference.hpp boost/python/converter/type_id.hpp
	boost/python/converter/unwrap.hpp
	boost/python/converter/wrap.hpp
	boost/python/converter/wrapper.hpp
	boost/python/detail/config.hpp libs/python/Jamfile
	libs/python/src/converter/registry.cpp
	libs/python/src/converter/type_id.cpp
	libs/python/src/converter/unwrap.cpp libs/python/test/m1.cpp
Added Files:
	boost/python/converter/wrapper_base.hpp


		CXX 6.x fixes


[SVN r12271]
2002-01-10 19:28:16 +00:00
Dave Abrahams
7d1cbcb0c1 Possible workaround for cxx 6.2
[SVN r12270]
2002-01-10 19:07:18 +00:00
Dave Abrahams
98c9e67625 Fixed mistaken "C" linkage
[SVN r12268]
2002-01-10 13:59:14 +00:00
Dave Abrahams
aeef66ce35 Handle cv-qualified member functions
[SVN r12265]
2002-01-10 02:32:47 +00:00
Dave Abrahams
8cff66e8c6 initial checkin
[SVN r12264]
2002-01-09 23:23:44 +00:00
Ralf W. Grosse-Kunstleve
10a04acf41 Missing this-> inserted (due to EDG 245 diagnostics)
[SVN r12261]
2002-01-09 21:20:51 +00:00
Dave Abrahams
9923a4c4ff More "realism"
[SVN r12239]
2002-01-07 06:47:22 +00:00
Dave Abrahams
0dafa9e229 check number of arguments
[SVN r12238]
2002-01-07 06:46:32 +00:00
Dave Abrahams
e83e8a8f1c object::->objects::
[SVN r12237]
2002-01-07 06:45:53 +00:00
Dave Abrahams
72aa768235 Added overload capability
[SVN r12236]
2002-01-06 14:41:51 +00:00
Dave Abrahams
65c74e3976 avoiding naming conflict, object:: -> objects::
[SVN r12235]
2002-01-06 14:40:53 +00:00
Dave Abrahams
cdac34efea Added wrapper for PyObject*
[SVN r12234]
2002-01-06 14:40:33 +00:00
Dave Abrahams
03fef3106d Bug fix: convertability checks were missed in one case
[SVN r12233]
2002-01-06 14:39:52 +00:00
Dave Abrahams
d598d0a4db added inlines
[SVN r12232]
2002-01-06 14:39:34 +00:00
Dave Abrahams
ab22e1b3a9 Added most of the module_builder interface
[SVN r12231]
2002-01-06 14:36:28 +00:00
Dave Abrahams
26d520af3c avoiding naming conflict, object:: -> objects::
[SVN r12230]
2002-01-06 14:35:27 +00:00
Dave Abrahams
fb333f3641 Bug fix: convertability checks were missed in one case
[SVN r12229]
2002-01-06 14:34:14 +00:00
Dave Abrahams
1cc65a47eb Added wrapper for PyObject*
[SVN r12228]
2002-01-06 14:33:33 +00:00
Dave Abrahams
8d56c52991 simplification: I didn't really understand what I was dealing with, so I pared things down.
[SVN r12227]
2002-01-06 14:32:51 +00:00
Dave Abrahams
4b88b9eed1 Added most of the module_builder interface
[SVN r12226]
2002-01-06 14:31:27 +00:00
Dave Abrahams
462b91fb08 Added min/max argument count checking
[SVN r12225]
2002-01-06 14:30:46 +00:00
Dave Abrahams
b65f4ff963 added inlines
[SVN r12224]
2002-01-06 14:29:54 +00:00
Ralf W. Grosse-Kunstleve
8d27b48225 update for cxx 6.5 and irix_CC
[SVN r12222]
2002-01-05 02:18:00 +00:00
Dave Abrahams
e2623c5e82 fixes for gcc-3.0.3
[SVN r12221]
2002-01-04 23:32:23 +00:00
Ralf W. Grosse-Kunstleve
acdae42fc5 work-around for cxx
[SVN r12215]
2002-01-04 20:49:20 +00:00
Ralf W. Grosse-Kunstleve
451aac806e remove extra semicolons
[SVN r12214]
2002-01-04 20:15:49 +00:00
Dave Abrahams
586e6178b4 commented
[SVN r12209]
2002-01-04 02:06:21 +00:00
Dave Abrahams
1201761ff3 initial checkin
[SVN r12198]
2002-01-02 17:53:34 +00:00
Dave Abrahams
bdf68f092e Accounting for by-value conversions
Convertibility checks now collect the auxiliary conversion data


[SVN r12193]
2002-01-01 18:55:23 +00:00
Dave Abrahams
a179f87d54 BOOST_PYTHON_EXPORT -> BOOST_PYTHON_DECL
[SVN r12192]
2002-01-01 18:53:12 +00:00
Dave Abrahams
b2944a12de Convertibility checks now collect the auxiliary conversion data
BOOST_PYTHON_EXPORT -> BOOST_PYTHON_DECL


[SVN r12191]
2002-01-01 18:52:04 +00:00
Dave Abrahams
bfcb36927c Accounting for by-value conversions
[SVN r12190]
2002-01-01 18:49:20 +00:00
Dave Abrahams
ccd21d5254 Accounting for by-value conversions
Convertibility checks now collect the auxiliary conversion data


[SVN r12189]
2002-01-01 18:47:32 +00:00
Dave Abrahams
a7b8448107 obsolete now that Boost.Python is in a shared lib.
[SVN r12188]
2002-01-01 18:45:49 +00:00
Dave Abrahams
e934be2d99 BOOST_PYTHON_EXPORT -> BOOST_PYTHON_DECL
[SVN r12187]
2002-01-01 18:21:31 +00:00
Dave Abrahams
015b875a9e Convertibility checks now collect the auxiliary conversion data
[SVN r12186]
2002-01-01 18:21:06 +00:00
Dave Abrahams
1247ff2543 *** empty log message ***
[SVN r12177]
2001-12-31 17:02:43 +00:00
Dave Abrahams
dc831fb3f6 Stuck the extension_class code in the DLL whenever possible
[SVN r12168]
2001-12-29 00:00:19 +00:00
Dave Abrahams
94c0e947f5 Stuck the extension_class code in the DLL whenever possible
Removed copyability restriction in class_base to enable the above


[SVN r12167]
2001-12-28 23:59:02 +00:00
Dave Abrahams
ed9bc835a2 Stuck the extension_class code in the DLL whenever possible
Removed some flotsam


[SVN r12166]
2001-12-28 23:56:10 +00:00
Dave Abrahams
2eb2e52a79 workaround some compiler limitations
[SVN r12165]
2001-12-28 23:52:01 +00:00
Ralf W. Grosse-Kunstleve
14f6f88526 irix_CC workaround; updated makefiles
[SVN r12163]
2001-12-28 13:26:36 +00:00
Dave Abrahams
1f78c74085 fixes
[SVN r12146]
2001-12-24 19:27:39 +00:00
Dave Abrahams
c494649dde fix a bug with instance::power reported by Scott Snyder.
[SVN r12119]
2001-12-18 21:00:07 +00:00
Dave Abrahams
460f3aebe9 inital checkin
[SVN r12086]
2001-12-17 17:24:41 +00:00
133 changed files with 11435 additions and 908 deletions

70
Jamfile Normal file
View File

@@ -0,0 +1,70 @@
subproject libs/python ;
# bring in the rules for python
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
PYTHON_PROPERTIES
+= <metrowerks><*><cxxflags>"-inline deferred"
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
<define>BOOST_PYTHON_DYNAMIC_LIB
<define>BOOST_PYTHON_V2
;
{
dll bpl
:
src/converter/from_python.cpp
src/converter/registry.cpp
src/converter/type_id.cpp
src/object/class.cpp
src/object/function.cpp
src/object/inheritance.cpp
src/object/life_support.cpp
src/errors.cpp
src/module.cpp
src/objects.cpp
src/converter/builtin_converters.cpp
:
$(PYTHON_PROPERTIES)
<define>BOOST_PYTHON_SOURCE
;
# -------- general test -------
extension m1 : test/m1.cpp <lib>bpl
:
: debug-python
;
extension m2 : test/m2.cpp <lib>bpl
:
: debug-python ;
boost-python-runtest try : test/newtest.py <lib>m1 <lib>m2 : : debug-python ;
# ----------- builtin converters -----------
extension builtin_converters_ext : test/test_builtin_converters.cpp <lib>bpl
:
: debug-python
;
boost-python-runtest test_builtin_converters : test/test_builtin_converters.py
<lib>builtin_converters_ext
:
: debug-python
;
# ----------- pointer adoption -----------
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <lib>bpl
:
: debug-python
;
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
<lib>test_pointer_adoption_ext
:
: debug-python
;
}

View File

@@ -61,8 +61,10 @@ subproject libs/python/build ;
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_DYNAMIC_LIB ;
#######################
local rule bpl-test ( test-name : sources + )
rule bpl-test ( test-name : sources + )
{
boost-python-test $(test-name) : $(sources) <lib>libboost_python ;
}
@@ -75,21 +77,27 @@ local rule bpl-test ( test-name : sources + )
# Base names of the source files for libboost_python
local CPP_SOURCES =
types classes conversions extension_class functions
init_function module_builder objects cross_module ;
types classes conversions extension_class functions
init_function module_builder objects cross_module errors
;
lib libboost_python : ../src/$(CPP_SOURCES).cpp
lib libboost_python_static : ../src/$(CPP_SOURCES).cpp
# requirements
: $(BOOST_PYTHON_INCLUDES)
<shared-linkable>true
<define>BOOST_PYTHON_STATIC_LIB=1
$(PYTHON_PROPERTIES) ;
dll libboost_python$(SUFDLL[1]) : ../src/$(CPP_SOURCES).cpp
dll libboost_python
# $(SUFDLL[1])
: ../src/$(CPP_SOURCES).cpp
# requirements
: $(BOOST_PYTHON_INCLUDES)
: $(BOOST_PYTHON_INCLUDES)
<shared-linkable>true
<define>BOOST_RE_BUILD_DLL=1
$(PYTHON_PROPERTIES) ;
<runtime-link>dynamic
<define>BOOST_PYTHON_HAS_DLL_RUNTIME=1
$(PYTHON_PROPERTIES)
;
############# comprehensive module and test ###########
bpl-test boost_python_test
@@ -100,7 +108,7 @@ boost-python-runtest comprehensive
############# simple tests from ../example ############
local rule boost-python-example-runtest ( name )
rule boost-python-example-runtest ( name )
{
bpl-test $(name)
: ../example/$(name).cpp ;
@@ -128,7 +136,7 @@ bpl-test noncopyable_import : ../example/noncopyable_import.cpp ;
############## cross-module tests from ../example ##########
# A simple rule to build a test which depends on multiple modules in the PYTHONPATH
local rule boost-python-multi-example-runtest ( test-name : modules + )
rule boost-python-multi-example-runtest ( test-name : modules + )
{
boost-python-runtest $(test-name)
: ../example/tst_$(test-name).py <lib>$(modules) <lib>libboost_python

View File

@@ -7,6 +7,7 @@ LIBSRC = \
classes.cpp \
conversions.cpp \
cross_module.cpp \
errors.cpp \
extension_class.cpp \
functions.cpp \
init_function.cpp \

View File

@@ -8,6 +8,7 @@ bpl_exa = "/libs/python/example"
files = (
bpl_src + "/classes.cpp",
bpl_src + "/conversions.cpp",
bpl_src + "/errors.cpp",
bpl_src + "/extension_class.cpp",
bpl_src + "/functions.cpp",
bpl_src + "/init_function.cpp",

View File

@@ -11,6 +11,7 @@ LIBSRC = \
classes.cpp \
conversions.cpp \
cross_module.cpp \
errors.cpp \
extension_class.cpp \
functions.cpp \
init_function.cpp \

View File

@@ -17,10 +17,10 @@
ROOT=$(HOME)
BOOST=$(ROOT)/boost
PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python
#PYINC=-I/usr/local/Python-2.1/include/python2.1
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
STDOPTS=
@@ -35,7 +35,7 @@ MAKEDEP=-M
LD=CC -LANG:std -n32 -mips4
LDOPTS=-shared
OBJ=classes.o conversions.o extension_class.o functions.o \
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
init_function.o module_builder.o \
objects.o types.o cross_module.o
DEPOBJ=$(OBJ) \

View File

@@ -17,12 +17,12 @@
ROOT=$(HOME)
BOOST=$(ROOT)/boost
PYEXE=PYTHONPATH=. /usr/bin/python
PYINC=-I/usr/include/python1.5
#PYEXE=PYTHONPATH=. /usr/bin/python
#PYINC=-I/usr/include/python1.5
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python
#PYINC=-I/usr/local/Python-2.1/include/python2.1
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
STDOPTS=-fPIC -ftemplate-depth-21
WARNOPTS=
@@ -36,7 +36,7 @@ MAKEDEP=-M
LD=$(CPP)
LDOPTS=-shared
OBJ=classes.o conversions.o extension_class.o functions.o \
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
init_function.o module_builder.o \
objects.o types.o cross_module.o
DEPOBJ=$(OBJ) \

View File

@@ -52,7 +52,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \
LD=g++
LDOPTS=-shared
OBJ=classes.o conversions.o extension_class.o functions.o \
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
init_function.o module_builder.o \
objects.o types.o cross_module.o

View File

@@ -17,10 +17,10 @@
ROOT=$(HOME)
BOOST=$(ROOT)/boost
PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python
#PYINC=-I/usr/local/Python-2.1/include/python2.1
#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python
PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1
#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport
#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport
#STLPORTOPTS= \
@@ -46,7 +46,7 @@ LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*'
#HIDDEN=-hidden
OBJ=classes.o conversions.o extension_class.o functions.o \
OBJ=classes.o conversions.o errors.o extension_class.o functions.o \
init_function.o module_builder.o \
objects.o types.o cross_module.o
DEPOBJ=$(OBJ) \

View File

@@ -14,14 +14,14 @@ ROOT=R:
BOOST_WIN="$(ROOT)\boost"
BOOST_UNIX=$(HOME)/boost
PYEXE="C:\Program files\Python\python.exe"
PYINC=/I"C:\Program files\Python\include"
PYLIB="C:\Program files\Python\libs\python15.lib"
#PYEXE="C:\Python21\python.exe"
#PYINC=/I"C:\Python21\include"
#PYLIB="C:\Python21\libs\python21.lib"
#PYEXE="C:\Program files\Python\python.exe"
#PYINC=/I"C:\Program files\Python\include"
#PYLIB="C:\Program files\Python\libs\python15.lib"
PYEXE="C:\Python21\python.exe"
PYINC=/I"C:\Python21\include"
PYLIB="C:\Python21\libs\python21.lib"
STDOPTS=/nologo /MD /GR /GX /Zm200
STDOPTS=/nologo /MD /GR /GX /Zm300 /DBOOST_PYTHON_STATIC_LIB
WARNOPTS=
OPTOPTS=
@@ -32,7 +32,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \
LD=link.exe
LDOPTS=/nologo /dll /incremental:no
OBJ=classes.obj conversions.obj extension_class.obj functions.obj \
OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \
init_function.obj module_builder.obj \
objects.obj types.obj cross_module.obj

View File

@@ -10,7 +10,7 @@
# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve)
ROOT=R:
BOOST_WIN="$(ROOT)\boostdev"
BOOST_WIN="$(ROOT)\boost"
BOOST_UNIX=$(HOME)/boost
#PYEXE="C:\Program files\Python\python.exe"
@@ -20,7 +20,7 @@ PYEXE="C:\Python21\python.exe"
PYINC=-I"C:\Python21\include"
PYLIB="C:\Python21\libs\python21.lib"
STDOPTS=-gccinc -prefix UseDLLPrefix.h
STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB
WARNOPTS=-warn on,nounusedexpr,nounused
OPTOPTS=-O
@@ -31,7 +31,7 @@ CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \
LD=mwld
LDOPTS=-export dllexport -shared
OBJ=classes.obj conversions.obj extension_class.obj functions.obj \
OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \
init_function.obj module_builder.obj \
objects.obj types.obj cross_module.obj

326
doc/new-conversions.html Normal file
View File

@@ -0,0 +1,326 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>A New Type Conversion Mechanism for Boost.Python</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p><img border="0" src="../../../c++boost.gif" width="277" height="86"
alt="boost logo"></p>
<h1>A New Type Conversion Mechanism for Boost.Python</h1>
<p>By <a href="../../../people/dave_abrahams.htm">David Abrahams</a>.
<h2>Introduction</h2>
This document describes a redesign of the mechanism for automatically
converting objects between C++ and Python. The current implementation
uses two functions for any type <tt>T</tt>:
<blockquote><pre>
U from_python(PyObject*, type&lt;T&gt;);
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 &lt;class Derived&gt;
struct add_some_functions
{
friend <i>return-type</i> some_function1(..., Derived <i>cv-*-&amp;-opt</i>, ...);
friend <i>return-type</i> some_function2(..., Derived <i>cv-*-&amp;-opt</i>, ...);
};
template &lt;class T&gt;
struct some_template : add_some_functions&lt;some_template&lt;T&gt; &gt;
{
};
</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 &quot;will the
conversion succeed?&quot; 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&lt;T&gt;</tt> and
<tt>unwrap&lt;T&gt;</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&lt;T&gt;</tt> object for efficiency. For
example, if the handle is an <tt>unwrap&lt;Foo&amp;&gt;</tt> object,
the <tt>entry</tt> for <tt>Foo&amp;</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&lt;double&gt;
const&amp;</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 &quot;active&quot;
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 &quot;dynamically-determined
vtable&quot; 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&amp;
T* const&amp;
T&amp;
T const&amp;
T
std::auto_ptr&lt;T&gt;&amp;
std::auto_ptr&lt;T&gt;
std::auto_ptr&lt;T&gt; const&amp;
boost::shared_ptr&lt;T&gt;&amp;
boost::shared_ptr&lt;T&gt;
boost::shared_ptr&lt;T&gt; const&amp;
</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&amp;</tt>. <font color="#ff0000">What about conversions
to values like the tuple-&gt;vector example above? It seems to me
that we don't want to make a <tt>vector&lt;double&gt;&amp;</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&lt;T&gt;::type</tt>. Unwrappers for
<tt>T&nbsp;const&amp;</tt> always return <tt>T&amp;</tt>, and are
registered under both <tt>T&nbsp;&amp;</tt> and
<tt>T&nbsp;const&amp;</tt>.
<p>For compilers not supporting partial specialization, unwrappers for
<tt>T&nbsp;const&amp;</tt> must return <tt>T&nbsp;const&amp;</tt>
(since constness can't be stripped), but a separate unwrapper object
need to be registered for <tt>T&nbsp;&amp;</tt> and
<tt>T&nbsp;const&amp;</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
&quot;<tt>_more</tt>&quot; class which does the same job, but has a
trivial destructor. Instead of asking each &quot;<tt>_more</tt>&quot;
handle to destroy its own body, it is linked into an endogenous list
managed by the first (ordinary) handle. The <tt>wrap</tt> and
<tt>unwrap</tt> destructors are responsible for traversing that list
and asking each <tt>body</tt> class to tear down its
<tt>handle</tt>. This mechanism is also used to determine if all of
the argument/return-value conversions can succeed with a single
function call in the function wrapping code. <font color="#ff0000">We
might need to handle return values in a separate step for Python
callbacks, since the availablility of a conversion won't be known
until the result object is retrieved.</font>
<br>
<hr>
<h2>References</h2>
<p><a name="ref_1">[1]</a>B. Stroustrup, The C++ Programming Language
Special Edition Addison-Wesley, ISBN 0-201-70073-5.
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->19 December 2001<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
<p>© Copyright David Abrahams, 2001</p>
</body>
</html>

111
doc/new-conversions.txt Normal file
View File

@@ -0,0 +1,111 @@
This hierarchy contains converter handle classes.
+-------------+
| noncopyable |
+-------------+
^
| A common base class used so that
+--------+--------+ conversions can be linked into a
| conversion_base | chain for efficient argument
+-----------------+ conversion
^
|
+---------+-----------+
| |
+-----------+----+ +------+-------+ only used for
| unwrap_more<T> | | wrap_more<T> | chaining, and don't manage any
+----------------+ +--------------+ resources.
^ ^
| |
+-----+-----+ +-------+-+ These converters are what users
| unwrap<T> | | wrap<T> | actually touch, but they do so
+-----------+ +---------+ through a type generator which
minimizes the number of converters
that must be generated, so they
Each unwrap<T>, unwrap_more<T>, wrap<T>, wrap_more<T> converter holds
a reference to an appropriate converter object
This hierarchy contains converter body classes
Exposes use/release which
are needed in case the converter
+-----------+ in the registry needs to be
| converter | cloned. That occurs when a
+-----------+ unwrap target type is not
^ contained within the Python object.
|
+------------------+-----+
| |
+--------+-------+ Exposes |
| unwrapper_base | convertible() |
+----------------+ |
^ |
| |
+--------+----+ +-----+-----+
| unwrapper<T>| | wrapper<T>|
+-------------+ +-----------+
Exposes T convert(PyObject*) Exposes PyObject* convert(T)
unwrap:
constructed with a PyObject*, whose reference count is
incremented.
find the registry entry for the target type
look in the collection of converters for one which claims to be
able to convert the PyObject to the target type.
stick a pointer to the unwrapper in the unwrap object
when unwrap is queried for convertibility, it checks to see
if it has a pointer to an unwrapper.
on conversion, the unwrapper is asked to allocate an
implementation if the unwrap object isn't already holding
one. The unwrap object "takes ownership" of the unwrapper's
implementation. No memory allocation will actually take place
unless this is a value conversion.
on destruction, the unwrapper is asked to free any implementation
held by the unwrap object. No memory deallocation actually
takes place unless this is a value conversion
on destruction, the reference count on the held PyObject is
decremented.
We need to make sure that by default, you can't instantiate
callback<> for reference and pointer return types: although the
unwrappers may exist, they may convert by-value, which would cause
the referent to be destroyed upon return.
wrap:
find the registry entry for the source type
see if there is a converter. If found, stick a pointer to it in
the wrap object.
when queried for convertibility, it checks to see if it has a
pointer to a converter.
on conversion, a reference to the target PyObject is held by the
converter. Generally, the PyObject will have been created by the
converter, but in certain cases it may be a pre-existing object,
whose reference count will have been incremented.
when a wrap<T> x is used to return from a C++ function,
x.release() is returned so that x no longer holds a reference to
the PyObject when destroyed.
Otherwise, on destruction, any PyObject still held has its
reference-count decremented.
When a converter is created by the user, the appropriate element must
be added to the registry; when it is destroyed, it must be removed
from the registry.

View File

@@ -1,50 +0,0 @@
#include <iostream>
#include <string>
namespace { // Avoid cluttering the global namespace.
// A friendly class.
class world
{
private:
std::string country;
public:
world(const std::string& country) { this->country = country; }
std::string greet() const { return "Hello from " + country + "!"; }
};
// A function taking a world object as an argument.
std::string invite(const world& w) {
return w.greet() + " Please come soon!";
}
}
#include <py_cpp/class_wrapper.h>
// Python requires an exported function called init<module-name> in every
// extension module. This is where we build the module contents.
BOOST_PYTHON_MODULE_INIT(example2)
{
// Create an object representing this extension module.
py::Module this_module("example2");
// Create the Python type object for our extension class.
py::ClassWrapper<world> world_class(this_module, "world");
// Add the __init__ function.
world_class.def(py::Constructor<std::string>());
// Add a regular member function.
world_class.def(&world::greet, "greet");
// Add invite() as a regular function to the module.
this_module.def(invite, "invite");
// Even better, invite() can also be made a member of world_class!!!
world_class.def(invite, "invite");
}
// Win32 DLL boilerplate
#if defined(_WIN32)
#include <windows.h>
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; }
#endif // _WIN32

View File

@@ -1,101 +0,0 @@
#include <py_cpp/class_wrapper.h>
#include <py_cpp/objects.h>
#define rangei(n) for (int i = 0; i < n; i++)
namespace { // Avoid cluttering the global namespace.
// A wrapper is used to define additional constructors.
//
struct vector_double_wrapper: std::vector<double>
{
// Tell the compiler how to convert a base class object to
// this wrapper object.
vector_double_wrapper(PyObject*, const std::vector<double>& vd)
: std::vector<double>(vd) {}
vector_double_wrapper(PyObject* self)
: std::vector<double>() {}
vector_double_wrapper(PyObject* self, const int n)
: std::vector<double>(n) {}
vector_double_wrapper(PyObject* self, py::Tuple tuple)
: std::vector<double>(tuple.size())
{
std::vector<double>::iterator vd = begin();
rangei(tuple.size())
vd[i] = from_python(tuple[i].get(), py::Type<double>()); // GCC BUG
}
};
double getitem(const std::vector<double>& vd, const std::size_t key) {
return vd[key];
}
void setitem(std::vector<double>& vd, const std::size_t key,
const double &d) {
std::vector<double>::iterator vditer = vd.begin();
vditer[key] = d;
}
void delitem(std::vector<double>& vd, const std::size_t key) {
std::vector<double>::iterator vditer = vd.begin();
vd.erase(&vditer[key]);
}
// Convert vector_double to a regular Python tuple.
//
py::Tuple as_tuple(const std::vector<double>& vd)
{
py::Tuple t(vd.size());
rangei(vd.size()) t.set_item(i, py::Ptr(py::to_python(vd[i]))); // GCC BUG
return t;
}
// Function returning a vector_double object to Python.
//
std::vector<double> foo(const int n)
{
std::vector<double> vd(n);
std::vector<double>::iterator vditer = vd.begin();
rangei(n) vditer[i] = double(i);
return vd;
}
// Same as foo(), but avoid copying on return.
//
std::auto_ptr<std::vector<double> > bar(const int n)
{
std::auto_ptr<std::vector<double> > vdptr(new std::vector<double>(n));
std::vector<double>::iterator vditer = vdptr->begin();
rangei(n) vditer[i] = double(10 * i);
return vdptr;
}
}
BOOST_PYTHON_MODULE_INIT(example3)
{
py::Module this_module("example3");
py::ClassWrapper<std::vector<double>, vector_double_wrapper>
vector_double(this_module, "vector_double");
vector_double.def(py::Constructor<>());
vector_double.def(py::Constructor<const int>());
vector_double.def(py::Constructor<py::Tuple>());
vector_double.def(&std::vector<double>::size, "__len__");
vector_double.def(getitem, "__getitem__");
vector_double.def(setitem, "__setitem__");
vector_double.def(delitem, "__delitem__");
vector_double.def(as_tuple, "as_tuple");
this_module.def(foo, "foo");
this_module.def(bar, "bar");
}
// Win32 DLL boilerplate
#if defined(_WIN32)
#include <windows.h>
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; }
#endif // _WIN32

View File

@@ -91,7 +91,7 @@ BOOST_PYTHON_MODULE_INIT(simple_vector)
vector_double(this_module, "vector_double");
vector_double.def(python::constructor<>());
vector_double.def(python::constructor<const int>());
vector_double.def(python::constructor<int>());
vector_double.def(python::constructor<python::tuple>());
vector_double.def(&std::vector<double>::size, "__len__");
vector_double.def(getitem, "__getitem__");

View File

@@ -0,0 +1,210 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
// This work was funded in part by Lawrence Berkeley National Labs
//
// This file generated for 5-argument member functions and 6-argument free
// functions by gen_call.py
#ifndef CALL_DWA20011214_HPP
# define CALL_DWA20011214_HPP
# include <boost/python/detail/returning.hpp>
namespace boost { namespace python {
template <class R>
inline PyObject* call(R (*f)(), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
// Member functions
template <class R, class A0>
inline PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0>
inline PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1>
inline PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2>
inline PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3>
inline PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
}} // namespace boost::python
#endif // CALL_DWA20011214_HPP

View File

@@ -0,0 +1,202 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_DWA200216_HPP
# define CLASS_DWA200216_HPP
# include <boost/python/class_fwd.hpp>
# include <boost/python/reference.hpp>
# include <boost/python/object/class.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/detail/wrap_function.hpp>
# include <boost/mpl/type_list.hpp>
# include <boost/python/object/class_converters.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/for_each.hpp>
# include <boost/python/detail/type_list.hpp>
namespace // put some convenience classes into the unnamed namespace for the user
{
// A type list for specifying bases
template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) >
struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type
{};
// A type list for specifying arguments
template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) >
struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type
{};
}
namespace boost { namespace python {
// Forward declarations
namespace objects
{
struct value_holder_generator;
}
namespace detail
{
// This is an mpl BinaryMetaFunction object with a runtime behavior,
// which is to write the id of the type which is passed as its 2nd
// compile-time argument into the iterator pointed to by its runtime
// argument
struct write_type_id
{
// The first argument is Ignored because mpl::for_each is still
// currently an accumulate (reduce) implementation.
template <class Ignored, class T> struct apply
{
// also an artifact of accumulate-based for_each
typedef void type;
// Here's the runtime behavior
static void execute(converter::undecorated_type_id_t** p)
{
*(*p)++ = converter::undecorated_type_id<T>();
}
};
};
}
//
// class_<T,Bases,HolderGenerator>
//
// This is the primary mechanism through which users will expose
// C++ classes to Python. The three template arguments are:
//
// T - The class being exposed to Python
//
// Bases - An MPL sequence of base classes
//
// HolderGenerator -
// An optional type generator for the "holder" which
// maintains the C++ object inside the Python instance. The
// default just holds the object "by-value", but other
// holders can be substituted which will hold the C++ object
// by smart pointer, for example.
//
template <
class T // class being wrapped
, class Bases
, class HolderGenerator
>
class class_ : private objects::class_base
{
typedef class_<T,Bases,HolderGenerator> self;
public:
// Automatically derive the class name - only works on some
// compilers because type_info::name is sometimes mangled (gcc)
class_();
// Construct with the class name. [ Would have used a default
// argument but gcc-2.95.2 choked on typeid(T).name() as a default
// parameter value]
class_(char const* name);
// Wrap a member function or a non-member function which can take
// a T, T cv&, or T cv* as its first parameter, or a callable
// python object.
template <class F>
self& def(char const* name, F f)
{
// Use function::add_to_namespace to achieve overloading if
// appropriate.
objects::function::add_to_namespace(
this->object(), name, ref(detail::wrap_function(f)));
return *this;
}
template <class Fn, class CallPolicy>
self& def(char const* name, Fn fn, CallPolicy policy)
{
this->def(name, boost::python::make_function(fn, policy));
return *this;
}
// Define the constructor with the given Args, which should be an
// MPL sequence of types.
template <class Args>
self& def_init(Args const& = Args())
{
def("__init__", make_constructor<T,Args,HolderGenerator>());
return *this;
}
// Define the default constructor.
self& def_init()
{
this->def_init(mpl::type_list<>::type());
return *this;
}
// return the underlying object
ref object() const;
private: // types
typedef objects::class_id class_id;
// A helper class which will contain an array of id objects to be
// passed to the base class constructor
struct id_vector
{
typedef objects::class_id class_id;
id_vector()
{
// Stick the derived class id into the first element of the array
ids[0] = converter::undecorated_type_id<T>();
// Write the rest of the elements into succeeding positions.
class_id* p = ids + 1;
mpl::for_each<Bases, void, detail::write_type_id>::execute(&p);
}
BOOST_STATIC_CONSTANT(
std::size_t, size = mpl::size<Bases>::value + 1);
class_id ids[size];
};
private: // helper functions
void initialize_converters();
};
//
// implementations
//
template <class T, class Bases, class HolderGenerator>
inline class_<T, Bases, HolderGenerator>::class_()
: class_base(typeid(T).name(), id_vector::size, id_vector().ids)
{
// Bring the class converters into existence. This static object
// will survive until the shared library this module lives in is
// unloaded (that doesn't happen until Python terminates).
static objects::class_converters<T,Bases> converters(object());
}
template <class T, class Bases, class HolderGenerator>
inline class_<T, Bases, HolderGenerator>::class_(char const* name)
: class_base(name, id_vector::size, id_vector().ids)
{
// Bring the class converters into existence. This static object
// will survive until the shared library this module lives in is
// unloaded (that doesn't happen until Python terminates).
static objects::class_converters<T,Bases> converters(object());
}
template <class T, class Bases, class HolderGenerator>
inline ref class_<T, Bases, HolderGenerator>::object() const
{
typedef objects::class_base base;
return this->base::object();
}
}} // namespace boost::python
#endif // CLASS_DWA200216_HPP

View File

@@ -0,0 +1,30 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_FWD_DWA200222_HPP
# define CLASS_FWD_DWA200222_HPP
namespace boost { namespace python {
namespace detail
{
struct empty_list;
}
namespace objects
{
struct value_holder_generator;
}
template <
class T // class being wrapped
, class Bases = detail::empty_list
, class HolderGenerator = objects::value_holder_generator
>
class class_;
}} // namespace boost::python
#endif // CLASS_FWD_DWA200222_HPP

View File

@@ -20,7 +20,7 @@
namespace boost { namespace python {
// A simple type which acts something like a built-in Python class obj.
class instance
class BOOST_PYTHON_DECL instance
: public boost::python::detail::python_object
{
public:
@@ -105,7 +105,7 @@ class instance
template <class T> class meta_class;
namespace detail {
class class_base : public type_object_base
class BOOST_PYTHON_DECL class_base : public type_object_base
{
public:
class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space);
@@ -128,6 +128,10 @@ namespace detail {
private: // boost::python::type_object_base required interface implementation
void instance_dealloc(PyObject*) const; // subclasses should not override this
private: // noncopyable, without the size bloat
class_base(const class_base&);
void operator=(const class_base&);
private:
string m_name;
@@ -141,11 +145,12 @@ namespace detail {
// A type which acts a lot like a built-in Python class. T is the obj type,
// so class_t<instance> is a very simple "class-alike".
template <class T>
class class_t
class BOOST_PYTHON_DECL_TEMPLATE class_t
: public boost::python::detail::class_base
{
public:
class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space);
~class_t();
// Standard Python functions.
PyObject* call(PyObject* args, PyObject* keywords);
@@ -218,15 +223,11 @@ class class_t
private: // Implementation of boost::python::detail::class_base required interface
void delete_instance(PyObject*) const;
private: // noncopyable, without the size bloat
class_t(const class_t<T>&);
void operator=(const class_t&);
};
// The type of a class_t<T> object.
template <class T>
class meta_class
class BOOST_PYTHON_DECL_TEMPLATE meta_class
: public boost::python::detail::reprable<
boost::python::detail::callable<
boost::python::detail::getattrable<
@@ -264,6 +265,11 @@ class_t<T>::class_t(meta_class<T>* meta_class_obj, string name, tuple bases, con
{
}
template <class T>
class_t<T>::~class_t()
{
}
template <class T>
void class_t<T>::delete_instance(PyObject* obj) const
{
@@ -344,7 +350,7 @@ int class_t<T>::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyO
return 0;
}
void adjust_slice_indices(PyObject* obj, int& start, int& finish);
void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish);
template <class T>
PyObject* class_t<T>::instance_sequence_slice(PyObject* obj, int start, int finish) const

View File

@@ -19,7 +19,7 @@
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/python/detail/signatures.hpp>
# include <boost/smart_ptr.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/python/errors.hpp>
# include <string>
@@ -122,61 +122,68 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
// Converters
//
PyObject* to_python(long);
long from_python(PyObject* p, boost::python::type<long>);
BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type<long>);
long from_python(PyObject* p, boost::python::type<const long&>);
PyObject* to_python(unsigned long);
unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned long);
BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
unsigned long from_python(PyObject* p, boost::python::type<const unsigned long&>);
PyObject* to_python(int);
int from_python(PyObject*, boost::python::type<int>);
BOOST_PYTHON_DECL int from_python(PyObject*, boost::python::type<int>);
int from_python(PyObject*, boost::python::type<const int&>);
PyObject* to_python(unsigned int);
unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned int);
BOOST_PYTHON_DECL unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
unsigned int from_python(PyObject*, boost::python::type<const unsigned int&>);
PyObject* to_python(short);
short from_python(PyObject*, boost::python::type<short>);
BOOST_PYTHON_DECL short from_python(PyObject*, boost::python::type<short>);
short from_python(PyObject*, boost::python::type<const short&>);
PyObject* to_python(unsigned short);
unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned short);
BOOST_PYTHON_DECL unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
unsigned short from_python(PyObject*, boost::python::type<const unsigned short&>);
PyObject* to_python(char);
char from_python(PyObject*, boost::python::type<char>);
BOOST_PYTHON_DECL PyObject* to_python(char);
BOOST_PYTHON_DECL char from_python(PyObject*, boost::python::type<char>);
char from_python(PyObject*, boost::python::type<const char&>);
PyObject* to_python(signed char);
signed char from_python(PyObject*, boost::python::type<signed char>);
BOOST_PYTHON_DECL PyObject* to_python(signed char);
BOOST_PYTHON_DECL signed char from_python(PyObject*, boost::python::type<signed char>);
signed char from_python(PyObject*, boost::python::type<const signed char&>);
PyObject* to_python(unsigned char);
unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned char);
BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
unsigned char from_python(PyObject*, boost::python::type<const unsigned char&>);
# ifndef BOOST_MSVC6_OR_EARLIER
PyObject* to_python(float);
float from_python(PyObject*, boost::python::type<float>);
float from_python(PyObject*, boost::python::type<const float&>);
PyObject* to_python(double);
double from_python(PyObject*, boost::python::type<double>);
# else
BOOST_PYTHON_DECL PyObject* to_python(float);
BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type<float>);
BOOST_PYTHON_DECL PyObject* to_python(double);
BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type<double>);
# endif
float from_python(PyObject*, boost::python::type<const float&>);
double from_python(PyObject*, boost::python::type<const double&>);
PyObject* to_python(bool);
bool from_python(PyObject*, boost::python::type<bool>);
BOOST_PYTHON_DECL bool from_python(PyObject*, boost::python::type<bool>);
bool from_python(PyObject*, boost::python::type<const bool&>);
PyObject* to_python(void);
void from_python(PyObject*, boost::python::type<void>);
BOOST_PYTHON_DECL PyObject* to_python(void);
BOOST_PYTHON_DECL void from_python(PyObject*, boost::python::type<void>);
PyObject* to_python(const char* s);
const char* from_python(PyObject*, boost::python::type<const char*>);
BOOST_PYTHON_DECL const char* from_python(PyObject*, boost::python::type<const char*>);
PyObject* to_python(const std::string& s);
std::string from_python(PyObject*, boost::python::type<std::string>);
BOOST_PYTHON_DECL PyObject* to_python(const std::string& s);
BOOST_PYTHON_DECL std::string from_python(PyObject*, boost::python::type<std::string>);
std::string from_python(PyObject*, boost::python::type<const std::string&>);
inline PyObject* to_python(const std::complex<float>& x)

View File

@@ -0,0 +1,62 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BODY_DWA2001127_HPP
# define BODY_DWA2001127_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/converter/type_id.hpp>
namespace boost { namespace python { namespace converter {
namespace registry
{
class entry;
}
struct BOOST_PYTHON_DECL body
{
public:
body(type_id_t key);
virtual ~body() {}
type_id_t key() const;
protected:
// true iff the registry is still alive
bool can_unregister() const;
private:
// called when the registry is destroyed, to prevent it from being
// unregistered.
void do_not_unregister();
friend class registry::entry;
private:
type_id_t m_key;
bool m_can_unregister;
};
//
// implementations
//
inline body::body(type_id_t key)
: m_key(key)
, m_can_unregister(true)
{
}
inline type_id_t body::key() const
{
return m_key;
}
inline bool body::can_unregister() const
{
return m_can_unregister;
}
}}} // namespace boost::python::converter
#endif // BODY_DWA2001127_HPP

View File

@@ -0,0 +1,69 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP
# define BUILTIN_CONVERTERS_DWA2002124_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <string>
namespace boost { namespace python {
// Provide specializations of to_python_value
template <class T> struct to_python_value;
namespace detail
{
struct builtin_to_python
{
static bool convertible() { return true; }
};
}
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
template <> struct to_python_value<T&> \
: detail::builtin_to_python \
{ \
PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
}; \
template <> struct to_python_value<T const&> \
: detail::builtin_to_python \
{ \
PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
};
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x))
BOOST_PYTHON_TO_INT(char)
BOOST_PYTHON_TO_INT(short)
BOOST_PYTHON_TO_INT(int)
BOOST_PYTHON_TO_INT(long)
# undef BOOST_TO_PYTHON_INT
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x)
namespace converter
{
void initialize_builtin_converters();
}
}} // namespace boost::python::converter
#endif // BUILTIN_CONVERTERS_DWA2002124_HPP

View File

@@ -0,0 +1,75 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_DWA20011215_HPP
# define CLASS_DWA20011215_HPP
# include <boost/python/object/class.hpp>
# include <boost/python/converter/from_python.hpp>
namespace boost { namespace python { namespace converter {
template <class T>
struct class_from_python_converter
{
class_from_python_converter();
static void* convertible(PyObject*);
static T& convert_ref(PyObject*, from_python_data&);
static T const& convert_cref(PyObject*, from_python_data&);
static T* convert_ptr(PyObject*, from_python_data&);
static T const* convert_cptr(PyObject*, from_python_data&);
from_python_converter<T&> to_ref;
from_python_converter<T const&> to_cref;
from_python_converter<T*> to_ptr;
from_python_converter<T const*> to_cptr;
};
//
// implementations
//
template <class T>
class_from_python_converter<T>::class_from_python_converter()
: to_ref(convertible, convert_ref)
, to_cref(convertible, convert_cref)
, to_ptr(convertible, convert_ptr)
, to_cptr(convertible, convert_cptr)
{}
template <class T>
T& class_from_python_converter<T>::convert_ref(PyObject*, from_python_data& x)
{
return *static_cast<T*>(x.stage1);
}
template <class T>
T const& class_from_python_converter<T>::convert_cref(PyObject*, from_python_data& x)
{
return *static_cast<T*>(x.stage1);
}
template <class T>
T* class_from_python_converter<T>::convert_ptr(PyObject*, from_python_data& x)
{
return static_cast<T*>(x.stage1);
}
template <class T>
T const* class_from_python_converter<T>::convert_cptr(PyObject*, from_python_data& x)
{
return static_cast<T*>(x.stage1);
}
template <class T>
void* class_from_python_converter<T>::convertible(PyObject* p)
{
return objects::find_instance<T>(p);
}
}}} // namespace boost::python::converter
#endif // CLASS_DWA20011215_HPP

View File

@@ -0,0 +1,198 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FROM_PYTHON_DWA2002127_HPP
# define FROM_PYTHON_DWA2002127_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/converter/body.hpp>
# include <boost/python/converter/from_python_function.hpp>
# include <boost/python/converter/from_python_data.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace converter {
// The type of convertibility checking functions
typedef void* (*from_python_check)(PyObject*);
typedef void (*from_python_destructor)(from_python_data&);
// forward declaration
template <class T> struct from_python_lookup;
// from_python --
// A body class representing a conversion from python to C++.
struct BOOST_PYTHON_DECL from_python_converter_base : body
{
from_python_converter_base(type_id_t, from_python_check); // registers
// Must return non-null iff the conversion will be successful. Any
// non-null pointer is acceptable, and will be passed on to the
// convert() function, so useful data can be stored there.
inline void* convertible(PyObject*) const;
// Given the head of a from_python converter chain, find the
// converter which can convert p, leaving its intermediate data in
// data.
inline static from_python_converter_base const*
find(from_python_converter_base const*chain, PyObject* p, void*& data);
private:
from_python_check m_convertible;
from_python_converter_base* m_next;
};
template <class T>
struct from_python_converter : from_python_converter_base
{
public: // types
typedef typename from_python_function<T>::type conversion_function;
public: // member functions
from_python_converter(from_python_check, conversion_function, from_python_destructor = 0);
T convert(PyObject*, from_python_data&) const;
void destroy(from_python_data&) const;
// Find a converter for converting p to a T.
static from_python_converter<T> const* find(PyObject* p, void*& data);
private: // data members
conversion_function m_convert;
from_python_destructor m_destroy;
// Keeps the chain of converters which convert from PyObject* to T
static from_python_converter_base*const& chain;
};
// Initialized to refer to a common place in the registry.
template <class T>
from_python_converter_base*const&
from_python_converter<T>::chain = registry::from_python_chain(type_id<T>());
// -------------------------------------------------------------------------
// A class which implements from_python with a registry lookup.
template <class T>
struct from_python_lookup // : from_python_base
{
public: // types
public: // member functions
from_python_lookup(PyObject* source);
~from_python_lookup();
bool convertible() const;
T operator()(PyObject*);
public: // functions for use by conversion implementations
// Get the converter object
from_python_converter<T> const* converter() const;
private: // data members
typedef typename from_python_intermediate_data<T>::type intermediate_t;
mutable intermediate_t m_intermediate_data;
from_python_converter<T> const* m_converter;
};
//
// implementations
//
inline void* from_python_converter_base::convertible(PyObject* o) const
{
return m_convertible(o);
}
inline from_python_converter_base const*
from_python_converter_base::find(
from_python_converter_base const* chain, PyObject* p, void*& data)
{
for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next)
{
void* d = q->convertible(p);
if (d != 0)
{
data = d;
return q;
}
}
return 0;
}
template <class T>
inline from_python_converter<T>::from_python_converter(
from_python_check checker
, conversion_function converter
, from_python_destructor destructor // = 0
)
: from_python_converter_base(type_id<T>(), checker)
, m_convert(converter)
, m_destroy(destructor)
{
}
template <class T>
inline from_python_converter<T> const*
from_python_converter<T>::find(PyObject* p, void*& data)
{
return static_cast<from_python_converter<T> const*>(
from_python_converter_base::find(chain, p, data));
}
template <class T>
inline T from_python_converter<T>::convert(PyObject* src, from_python_data& data) const
{
return this->m_convert(src, data);
}
template <class T>
inline void from_python_converter<T>::destroy(from_python_data& data) const
{
if (this->m_destroy)
{
this->m_destroy(data);
}
}
template <class T>
inline from_python_lookup<T>::from_python_lookup(PyObject* src)
: m_converter(
from_python_converter<T>::find(
src, m_intermediate_data.stage1))
{
}
template <class T>
inline from_python_lookup<T>::~from_python_lookup()
{
if (m_converter != 0)
m_converter->destroy(m_intermediate_data);
}
template <class T>
inline bool from_python_lookup<T>::convertible() const
{
return this->m_converter != 0;
}
template <class T>
inline T from_python_lookup<T>::operator()(PyObject* obj)
{
return this->m_converter->convert(obj, m_intermediate_data);
}
template <class T>
inline from_python_converter<T> const*
from_python_lookup<T>::converter() const
{
return this->m_converter;
}
}}} // namespace boost::python::converter
#endif // FROM_PYTHON_DWA2002127_HPP

View File

@@ -0,0 +1,206 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP
# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP
# include <boost/python/detail/char_array.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/type_traits/same_traits.hpp>
# include <boost/type.hpp>
// Keep these for the metaprogram which EDG is choking on.
# if !defined(__EDG__) || (__EDG_VERSION__ > 245)
# include <boost/mpl/type_list.hpp>
# include <boost/mpl/for_each.hpp>
# include <boost/type_traits/alignment_traits.hpp>
# include <boost/type_traits/composite_traits.hpp>
# endif
namespace boost { namespace python { namespace converter {
// A POD which is layout-compatible with the real intermediate data
// for all from_python conversions. There may be additional storage if
// we are converting a reference type.
struct from_python_data
{
void* stage1;
};
namespace detail
{
template <class T> struct referent_alignment;
template <class T> struct referent_size;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct referent_alignment<T&>
{
BOOST_STATIC_CONSTANT(
std::size_t, value = alignment_of<T>::value);
};
template <class T>
struct referent_size<T&>
{
BOOST_STATIC_CONSTANT(
std::size_t, value = sizeof(T));
};
# else
template <class U>
struct alignment_chars
{
BOOST_STATIC_CONSTANT(
std::size_T, n = alignment_of<U>::value);
char elements[n + 1];
};
template <class T> struct referent_alignment
{
template <class U>
static alignment_chars<U> helper(U&);
static T t;
BOOST_STATIC_CONSTANT(
std::size_t, value = sizeof(helper(t).elements) - 1);
};
template <class T> struct referent_size
{
static T t;
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t));
};
# endif
struct unknown_alignment
{
void* p;
};
// EDG is too slow to handle this metaprogram :(
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
struct alignment_dummy;
template <std::size_t target_alignment>
struct best_alignment_type
{
template <class T1, class T2>
struct apply
{
BOOST_STATIC_CONSTANT(
std::size_t, align1 = alignment_of<T1>::value);
BOOST_STATIC_CONSTANT(
std::size_t, align2 = alignment_of<T2>::value);
BOOST_STATIC_CONSTANT(
bool, aligned2 = (
(align2 >= target_alignment)
& (align2 % target_alignment == 0))
);
BOOST_STATIC_CONSTANT(
bool, choose_t2 = (
aligned2 && (
is_same<T1,unknown_alignment>::value
| (align2 < alignment_of<T1>::value)
| (sizeof(T2) < sizeof(T1)))
));
typedef mpl::select_type<choose_t2, T2, T1>::type type;
};
};
typedef mpl::type_list<
char,short,int,long,float,double,long double
,void*
,void(*)()
,void (alignment_dummy::*)()
, char (alignment_dummy::*)
>
align_types;
#endif // EDG is too slow
template <class Align, std::size_t size>
struct aligned_storage
{
typedef Align align_t;
union
{
Align align;
char bytes[size
// this is just a STATIC_ASSERT. For some reason
// MSVC was barfing on the boost one.
- (is_same<align_t,unknown_alignment>::value ? size : 0)];
};
};
template <class Reference>
struct referent_storage
{
// EDG is too slow to handle this metaprogram :(
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
typedef mpl::for_each<
align_types
, unknown_alignment
, best_alignment_type<referent_alignment<Reference>::value>
> loop;
typedef typename loop::state align_t;
#else
// The Python source makes the assumption that double has
// maximal alignment anyway
typedef double align_t;
#endif
typedef aligned_storage<align_t,referent_size<Reference>::value> type;
};
template <class T>
struct intermediate_data : from_python_data
{
typename referent_storage<T>::type stage2;
};
template <>
struct intermediate_data<void> : from_python_data
{
};
}
// -------------------------------------------------------------------------
// Auxiliary POD storage where the convertible and/or convert functions of a
// from_python object may place arbitrary data.
//
// Always starts with a void*
//
// For references, we produce additional aligned storage sufficient to
// store the referent
template <class T>
struct from_python_intermediate_data
{
typedef typename mpl::select_type<
is_reference<T>::value, T, void>::type just_reference_t;
typedef detail::intermediate_data<just_reference_t> type;
};
template <class T>
void* get_storage(from_python_data& x, boost::type<T>* = 0)
{
typedef typename from_python_intermediate_data<T>::type layout;
return static_cast<layout*>(&x)->stage2.bytes;
}
}}} // namespace boost::python::converter
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FROM_PYTHON_FUNCTION_DWA2002128_HPP
# define FROM_PYTHON_FUNCTION_DWA2002128_HPP
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace converter {
struct from_python_data;
template <class T>
struct from_python_function
{
typedef T (*type)(PyObject*, from_python_data&);
};
}}} // namespace boost::python::converter
#endif // FROM_PYTHON_FUNCTION_DWA2002128_HPP

View File

@@ -0,0 +1,108 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef HANDLE_DWA20011130_HPP
# define HANDLE_DWA20011130_HPP
# include <boost/python/detail/config.hpp>
# include <boost/utility.hpp>
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_DECL body;
// The common base class for unwrap_ and wrap_ handle objects. They
// share a common base so that handles can be linked into a chain
// within a function wrapper which is managed by a single object.
struct BOOST_PYTHON_DECL handle : boost::noncopyable
{
public: // member functions
// All constructors take a body* passed from the derived class.
//
// Constructors taking a handle links this into a chain of
// handles, for more efficient management in function wrappers
handle();
handle(body* body);
handle(body* body, handle& prev);
// returns true iff all handles in the chain can convert their
// arguments
bool convertible() const;
// safe_bool idiom from Peter Dimov: provides handles to/from
// bool without enabling handles to integer types/void*.
private:
struct dummy { inline void nonnull() {} };
typedef void (dummy::*safe_bool)();
public:
inline operator safe_bool() const;
inline safe_bool operator!() const;
protected: // member functions for derived classes
// Get the body we hold
inline body* get_body() const;
inline void set_body(body*);
inline void set_prev(handle&);
// Release all bodies in the chain, in reverse order of
// initialization. Only actually called for the head of the chain.
void destroy();
private:
// Holds implementation
body* m_body;
// handle for next argument, if any.
handle* m_next;
};
//
// implementations
//
inline handle::handle()
: m_next(0)
{}
inline handle::handle(body* body, handle& prev)
: m_body(body), m_next(0)
{
prev.m_next = this;
}
inline handle::handle(body* body)
: m_body(body), m_next(0)
{
}
inline handle::operator handle::safe_bool() const
{
return convertible() ? &dummy::nonnull : 0;
}
inline handle::safe_bool handle::operator!() const
{
return convertible() ? 0 : &dummy::nonnull;
}
inline body* handle::get_body() const
{
return m_body;
}
inline void handle::set_body(body* body)
{
m_body = body;
}
inline void handle::set_prev(handle& prev)
{
prev.m_next = this;
}
}}} // namespace boost::python::converter
#endif // HANDLE_DWA20011130_HPP

View File

@@ -0,0 +1,32 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REGISTRY_DWA20011127_HPP
# define REGISTRY_DWA20011127_HPP
# include <boost/python/converter/type_id.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/to_python_function.hpp>
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_DECL from_python_converter_base;
// This namespace acts as a sort of singleton
namespace registry
{
BOOST_PYTHON_DECL to_python_value_function const&
to_python_function(undecorated_type_id_t);
BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t);
BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t);
BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key);
}
}}} // namespace boost::python::converter
#endif // REGISTRY_DWA20011127_HPP

View File

@@ -0,0 +1,70 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef SMART_PTR_DWA2002123_HPP
# define SMART_PTR_DWA2002123_HPP
# include <boost/python/converter/class.hpp>
# include <boost/python/object/pointer_holder.hpp>
namespace boost { namespace python { namespace converter {
template <class Pointer, class Value>
class smart_ptr_wrapper
: wrapper<Pointer const&>
{
smart_ptr_wrapper(ref const& type_)
: m_class_object(type_)
{
assert(type_->ob_type == (PyTypeObject*)class_metatype().get());
}
PyObject* convert(Pointer x) const;
private:
ref m_class_object;
smart_ptr_converters();
}
//
// implementations
//
template <class Pointer, class Value>
PyObject* smart_ptr_wrapper<Pointer,Value>::convert(Pointer x) const
{
if (x.operator->() == 0)
return detail::none();
// Don't call the type to do the construction, since that
// would require the registration of an __init__ copy
// constructor. Instead, just construct the object in place.
PyObject* raw_result = (PyObject*)PyObject_New(
instance, (PyTypeObject*)m_class_object.get());
if (raw_result == 0)
return 0;
// Everything's OK; Bypass NULL checks but guard against
// exceptions.
ref result(raw_result, ref::allow_null());
// Build a value_holder to contain the object using the copy
// constructor
objects::pointer_holder<Pointer,Value>*
p = new objects::pointer_holder<Pointer,Value>(x);
// Install it in the instance
p->install(raw_result);
// Return the new result
return result.release();
}
}}} // namespace boost::python::converter
#endif // SMART_PTR_DWA2002123_HPP

View File

@@ -0,0 +1,191 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TARGET_DWA20011119_HPP
# define TARGET_DWA20011119_HPP
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/type_traits/same_traits.hpp>
namespace boost { namespace python { namespace converter {
// target --
//
// This type generator (see
// ../../../more/generic_programming.html#type_generator) is used
// to select the return type of the appropriate converter for
// unwrapping a given type.
// Strategy:
//
// 1. reduce everything to a common, un-cv-qualified reference
// type where possible. This will save on registering many different
// converter types.
//
// 2. Treat built-in types specially: when unwrapping a value or
// constant reference to one of these, use a value for the target
// type. It will bind to a const reference if neccessary, and more
// importantly, avoids having to dynamically allocate room for
// an lvalue of types which can be cheaply copied.
//
// Target Source
// int int
// int const& int
// int& int&
// int volatile& int volatile&
// int const volatile& int const volatile&
// On compilers supporting partial specialization:
//
// Target Source
// T T const&
// T& T&
// T const& T const&
// T volatile T&
// T const volatile& T const&
// T* T*
// T const* T const*
// T volatile T*
// T const volatile* T const*
// T cv*const& same as T cv*
// T cv*& T*& <- should this be legal?
// T cv*volatile& T*& <- should this be legal?
// T cv*const volatile& T*& <- should this be legal?
// On others:
//
// Target Source
// T T&
// T cv& T cv&
// T cv* T cv*
// T cv*cv& T cv*cv&
// As you can see, in order to handle the same range of types without
// partial specialization, more converters need to be registered.
template <class T>
struct target
{
// Some pointer types are handled in a more sophisticated way on
// compilers supporting partial specialization.
BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_scalar<T>::value));
typedef typename mpl::select_type<
use_identity
, T
, typename add_reference<
typename add_const<
typename remove_volatile<T>::type
>::type
>::type
>::type type;
};
// When partial specialization is not present, we'll simply need to
// register many more converters.
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct target<T&>
{
typedef typename remove_volatile<T>::type& type;
};
template <class T>
struct target<T const&>
{
typedef typename boost::mpl::select_type<
is_scalar<T>::value
, typename remove_cv<T>::type
, typename remove_volatile<T>::type const&
>::type type;
};
template <class T>
struct target<T*>
{
typedef typename remove_volatile<T>::type* type;
};
// Handle T*-cv for completeness. Function arguments in a signature
// are never actually cv-qualified, but who knows how these converters
// might be used, or whether compiler bugs lurk which make it seem
// otherwise?
template <class T>
struct target<T* const>
{
typedef typename remove_volatile<T>::type* type;
};
template <class T>
struct target<T* volatile>
{
typedef typename remove_volatile<T>::type* type;
};
template <class T>
struct target<T* const volatile>
{
typedef typename remove_volatile<T>::type* type;
};
// non-const references to pointers should be handled by the
// specialization for T&, above.
template <class T>
struct target<T* const&>
{
typedef typename remove_volatile<T>::type* type;
};
# endif
// Fortunately, we can handle T const& where T is an arithmetic type
// by explicit specialization. These specializations will cause value
// and const& arguments to be converted to values, rather than to
// references.
# define BOOST_PYTHON_UNWRAP_VALUE(T) \
template <> \
struct target<T> \
{ \
typedef T type; \
}; \
template <> \
struct target<T const> \
{ \
typedef T type; \
}; \
template <> \
struct target<T volatile> \
{ \
typedef T type; \
}; \
template <> \
struct target<T const volatile> \
{ \
typedef T type; \
}; \
template <> \
struct target<T const&> \
{ \
typedef T type; \
}
BOOST_PYTHON_UNWRAP_VALUE(char);
BOOST_PYTHON_UNWRAP_VALUE(unsigned char);
BOOST_PYTHON_UNWRAP_VALUE(signed char);
BOOST_PYTHON_UNWRAP_VALUE(unsigned int);
BOOST_PYTHON_UNWRAP_VALUE(signed int);
BOOST_PYTHON_UNWRAP_VALUE(unsigned short);
BOOST_PYTHON_UNWRAP_VALUE(signed short);
BOOST_PYTHON_UNWRAP_VALUE(unsigned long);
BOOST_PYTHON_UNWRAP_VALUE(signed long);
BOOST_PYTHON_UNWRAP_VALUE(char const*);
}}} // namespace boost::python::converter
#endif // TARGET_DWA20011119_HPP

View File

@@ -0,0 +1,32 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TO_PYTHON_FUNCTION_DWA2002128_HPP
# define TO_PYTHON_FUNCTION_DWA2002128_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/type_traits/transform_traits.hpp>
namespace boost { namespace python { namespace converter {
// The type of stored function pointers which actually do conversion
// by-value. The void* points to the object to be converted, and
// type-safety is preserved through runtime registration.
typedef PyObject* (*to_python_value_function)(void const*);
// Given a typesafe to_python conversion function, produces a
// to_python_value_function which can be registered in the usual way.
template <class T, class ToPython>
struct as_to_python_value_function
{
static PyObject* convert(void const* x)
{
return ToPython::convert(*(T const*)x);
}
};
}}} // namespace boost::python::converter
#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP

View File

@@ -0,0 +1,176 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TYPE_ID_DWA20011127_HPP
# define TYPE_ID_DWA20011127_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/python/detail/msvc_typeinfo.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/operators.hpp>
# include <boost/type.hpp>
# include <typeinfo>
# include <iosfwd>
# include <cstring>
namespace boost { namespace python { namespace converter {
// for this compiler at least, cross-shared-library type_info
// comparisons don't work, so use typeid(x).name() instead. It's not
// yet clear what the best default strategy is.
# if defined(__GNUC__) && __GNUC__ >= 3
# define BOOST_PYTHON_TYPE_ID_NAME
# endif
// type ids which represent the same information as std::type_info
// (i.e. the top-level reference and cv-qualifiers are stripped), but
// which works across shared libraries.
struct undecorated_type_id_t : totally_ordered<undecorated_type_id_t>
{
undecorated_type_id_t(std::type_info const&);
// default constructor needed to build arrays, etc.
undecorated_type_id_t();
bool operator<(undecorated_type_id_t const& rhs) const;
bool operator==(undecorated_type_id_t const& rhs) const;
char const* name() const;
friend BOOST_PYTHON_DECL std::ostream& operator<<(
std::ostream&, undecorated_type_id_t const&);
private: // data members
# ifdef BOOST_PYTHON_TYPE_ID_NAME
typedef char const* base_id_t;
# else
typedef std::type_info const* base_id_t;
# endif
base_id_t m_base_type;
};
struct type_id_t : totally_ordered<type_id_t>
{
enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 };
type_id_t(undecorated_type_id_t, decoration = decoration());
bool operator<(type_id_t const& rhs) const;
bool operator==(type_id_t const& rhs) const;
friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&);
operator undecorated_type_id_t const&() const;
private: // type
typedef undecorated_type_id_t base_id_t;
private: // data members
decoration m_decoration;
base_id_t m_base_type;
};
template <class T>
inline undecorated_type_id_t undecorated_type_id(boost::type<T>* = 0)
{
return undecorated_type_id_t(
# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600)
typeid(T)
# else // strip the decoration which msvc and Intel mistakenly leave in
python::detail::msvc_typeid<T>()
# endif
);
}
template <class T>
inline type_id_t type_id(boost::type<T>* = 0)
{
return type_id_t(
undecorated_type_id<T>()
, type_id_t::decoration(
(is_const<T>::value || python::detail::is_reference_to_const<T>::value
? type_id_t::const_ : 0)
| (is_volatile<T>::value || python::detail::is_reference_to_volatile<T>::value
? type_id_t::volatile_ : 0)
| (is_reference<T>::value ? type_id_t::reference : 0)
)
);
}
inline undecorated_type_id_t::undecorated_type_id_t(std::type_info const& id)
: m_base_type(
# ifdef BOOST_PYTHON_TYPE_ID_NAME
id.name()
# else
&id
# endif
)
{
}
inline undecorated_type_id_t::undecorated_type_id_t()
: m_base_type()
{
}
inline type_id_t::type_id_t(undecorated_type_id_t base_t, decoration decoration)
: m_decoration(decoration)
, m_base_type(base_t)
{
}
inline bool undecorated_type_id_t::operator<(undecorated_type_id_t const& rhs) const
{
# ifdef BOOST_PYTHON_TYPE_ID_NAME
return std::strcmp(m_base_type, rhs.m_base_type) < 0;
# else
return m_base_type->before(*rhs.m_base_type);
# endif
}
inline bool type_id_t::operator<(type_id_t const& rhs) const
{
return m_decoration < rhs.m_decoration
|| m_decoration == rhs.m_decoration
&& m_base_type < rhs.m_base_type;
}
inline bool undecorated_type_id_t::operator==(undecorated_type_id_t const& rhs) const
{
# ifdef BOOST_PYTHON_TYPE_ID_NAME
return !std::strcmp(m_base_type, rhs.m_base_type);
# else
return *m_base_type == *rhs.m_base_type;
# endif
}
inline bool type_id_t::operator==(type_id_t const& rhs) const
{
return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type;
}
inline type_id_t::operator undecorated_type_id_t const&() const
{
return m_base_type;
}
inline char const* undecorated_type_id_t::name() const
{
# ifdef BOOST_PYTHON_TYPE_ID_NAME
return m_base_type;
# else
return m_base_type->name();
# endif
}
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, undecorated_type_id_t const&);
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&);
}}} // namespace boost::python::converter
#endif // TYPE_ID_DWA20011127_HPP

View File

@@ -0,0 +1,36 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef UNWRAPPER_BASE_DWA20011215_HPP
# define UNWRAPPER_BASE_DWA20011215_HPP
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/body.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_DECL unwrapper_base : body
{
public:
unwrapper_base(type_id_t); // registers
~unwrapper_base(); // unregisters
// Must return non-null iff the conversion will be successful. Any
// non-null pointer is acceptable, and will be passed on to the
// convert() function, so useful data can be stored there.
virtual void* can_convert(PyObject*) const = 0;
protected:
// this is an arbitrary non-null pointer you can use to indicate success
static void* const non_null;
private: // body required interface implementation
void destroy_handle(handle*) const {}
};
}}} // namespace boost::python::converter
#endif // UNWRAPPER_BASE_DWA20011215_HPP

View File

@@ -0,0 +1,33 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef UNWRAPPER_SELECT_DWA20011229_HPP
# define UNWRAPPER_SELECT_DWA20011229_HPP
namespace boost { namespace python { namespace converter {
template <class T> struct unwrapper;
// Select the type returned by unwrapper objects when unwrapping a
// given type. When unwrapping T const&, the unwrapper returns T&, so
// that the same unwrapper object can be used for both conversions (on
// a conforming compiler).
template <class T>
struct unwrapper_select
{
typedef unwrapper<T> type;
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct unwrapper_select<T const&>
{
typedef unwrapper<T&> type;
};
# endif
}}} // namespace boost::python::converter
#endif // UNWRAPPER_SELECT_DWA20011229_HPP

View File

@@ -0,0 +1,42 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef COPY_CONST_REFERENCE_DWA2002131_HPP
# define COPY_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/to_python_value.hpp>
namespace boost { namespace python {
namespace detail
{
template <class R>
struct copy_const_reference_expects_a_const_reference_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
template <class T> struct to_python_value;
struct copy_const_reference
{
template <class T>
struct apply
{
typedef typename mpl::select_type<
detail::is_reference_to_const<T>::value
, to_python_value<T>
, detail::copy_const_reference_expects_a_const_reference_return_type<T>
>::type type;
};
};
}} // namespace boost::python
#endif // COPY_CONST_REFERENCE_DWA2002131_HPP

View File

@@ -0,0 +1,42 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef COPY_NON_CONST_REFERENCE_DWA2002131_HPP
# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/to_python_value.hpp>
namespace boost { namespace python {
namespace detail
{
template <class R>
struct copy_non_const_reference_expects_a_non_const_reference_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
template <class T> struct to_python_value;
struct copy_non_const_reference
{
template <class T>
struct apply
{
typedef typename mpl::select_type<
boost::python::detail::is_reference_to_non_const<T>::value
, to_python_value<T>
, detail::copy_non_const_reference_expects_a_non_const_reference_return_type<T>
>::type type;
};
};
}} // namespace boost::python
#endif // COPY_NON_CONST_REFERENCE_DWA2002131_HPP

View File

@@ -18,26 +18,28 @@
# include <boost/python/class_builder.hpp>
namespace boost { namespace python {
struct import_error : error_already_set {};
struct export_error : error_already_set {};
}}
struct BOOST_PYTHON_DECL import_error: error_already_set {};
struct BOOST_PYTHON_DECL export_error : error_already_set {};
namespace boost { namespace python { namespace detail {
namespace detail
{
// Concept: throw exception if api_major is changed
// show warning on stderr if api_minor is changed
const int export_converters_api_major = 4;
const int export_converters_api_minor = 1;
extern const char* converters_attribute_name;
void* import_converter_object(const std::string& module_name,
const std::string& py_class_name,
const std::string& attribute_name);
void check_export_converters_api(const int importing_major,
const int importing_minor,
const int imported_major,
const int imported_minor);
const int export_converters_api_major = 4;
const int export_converters_api_minor = 1;
extern BOOST_PYTHON_DECL const char* converters_attribute_name;
BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name,
const std::string& py_class_name,
const std::string& attribute_name);
BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major,
const int importing_minor,
const int imported_major,
const int imported_minor);
}}}
}
}} // namespace boost::python
// forward declaration
namespace boost { namespace python { namespace detail {
@@ -232,56 +234,56 @@ struct export_converter_object : export_converter_object_noncopyable<T>
}
};
namespace detail {
namespace detail
{
/* This class template is instantiated by import_converters<T>.
Its purpose is to import the converter_object via the Python API.
The actual import is only done once. The pointer to the
imported converter object is kept in the static data member
imported_converters.
*/
template <class T>
class import_extension_class
: public python_import_extension_class_converters<T>
{
public:
inline import_extension_class(const char* module, const char* py_class) {
m_module = module;
m_py_class = py_class;
}
*/
template <class T>
class import_extension_class
: public python_import_extension_class_converters<T>
{
public:
inline import_extension_class(const char* module, const char* py_class) {
m_module = module;
m_py_class = py_class;
}
static boost::python::export_converter_object_base<T>* get_converters();
static boost::python::export_converter_object_base<T>* get_converters();
private:
static std::string m_module;
static std::string m_py_class;
static boost::python::export_converter_object_base<T>* imported_converters;
};
private:
static std::string m_module;
static std::string m_py_class;
static boost::python::export_converter_object_base<T>* imported_converters;
};
template <class T> std::string import_extension_class<T>::m_module;
template <class T> std::string import_extension_class<T>::m_py_class;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::imported_converters = 0;
template <class T> std::string import_extension_class<T>::m_module;
template <class T> std::string import_extension_class<T>::m_py_class;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::imported_converters = 0;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::get_converters() {
if (imported_converters == 0) {
void* cobject
= import_converter_object(m_module, m_py_class,
converters_attribute_name);
imported_converters
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
check_export_converters_api(
export_converters_api_major,
export_converters_api_minor,
imported_converters->get_api_major(),
imported_converters->get_api_minor());
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::get_converters() {
if (imported_converters == 0) {
void* cobject
= import_converter_object(m_module, m_py_class,
converters_attribute_name);
imported_converters
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
check_export_converters_api(
export_converters_api_major,
export_converters_api_minor,
imported_converters->get_api_major(),
imported_converters->get_api_minor());
}
return imported_converters;
}
return imported_converters;
}
}}} // namespace boost::python::detail
namespace boost { namespace python {

View File

@@ -0,0 +1,78 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP
# define DEFAULT_CALL_POLICIES_DWA2002131_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/to_python_value.hpp>
# include <boost/type_traits/transform_traits.hpp>
namespace boost { namespace python {
template <class T> struct to_python_value;
namespace detail
{
// for "readable" error messages
template <class T> struct specify_a_result_policy_to_wrap_functions_returning
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
struct default_result_converter;
struct default_call_policies
{
// Nothing to do
static bool precall(PyObject*)
{
return true;
}
// Pass the result through
static PyObject* postcall(PyObject*, PyObject* result)
{
return result;
}
typedef default_result_converter result_converter;
};
struct default_result_converter
{
template <class R>
struct apply
{
BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference<R>::value || is_pointer<R>::value);
typedef typename mpl::select_type<
is_illegal
, detail::specify_a_result_policy_to_wrap_functions_returning<R>
, boost::python::to_python_value<
typename add_reference<typename add_const<R>::type>::type
>
>::type type;
};
};
// Exceptions for c strings an PyObject*s
template <>
struct default_result_converter::apply<char const*>
{
typedef boost::python::to_python_value<char const*const&> type;
};
template <>
struct default_result_converter::apply<PyObject*>
{
typedef boost::python::to_python_value<PyObject*const&> type;
};
}} // namespace boost::python
#endif // DEFAULT_CALL_POLICIES_DWA2002131_HPP

View File

@@ -0,0 +1,341 @@
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// This work was funded in part by Lawrence Berkeley National Labs
//
// This file generated for 5-argument member functions and 6-argument free
// functions by gen_arg_tuple_size.python
#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP
# define ARG_TUPLE_SIZE_DWA20011201_HPP
# include <boost/python/detail/char_array.hpp>
namespace boost { namespace python { namespace detail {
// Computes (at compile-time) the number of elements that a Python
// argument tuple must have in order to be passed to a wrapped C++
// (member) function of the given type.
template <class F> struct arg_tuple_size;
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__)
template <class R>
struct arg_tuple_size<R (*)()>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 0);
};
template <class R, class A1>
struct arg_tuple_size<R (*)(A1)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
};
template <class R, class A1, class A2>
struct arg_tuple_size<R (*)(A1, A2)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
};
template <class R, class A1, class A2, class A3>
struct arg_tuple_size<R (*)(A1, A2, A3)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
};
template <class R, class A1, class A2, class A3, class A4>
struct arg_tuple_size<R (*)(A1, A2, A3, A4)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
};
template <class R, class A1, class A2, class A3, class A4, class A5>
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
};
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5, A6)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
};
template <class R, class A0>
struct arg_tuple_size<R (A0::*)()>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
};
template <class R, class A0, class A1>
struct arg_tuple_size<R (A0::*)(A1)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
};
template <class R, class A0, class A1, class A2>
struct arg_tuple_size<R (A0::*)(A1, A2)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
};
template <class R, class A0, class A1, class A2, class A3>
struct arg_tuple_size<R (A0::*)(A1, A2, A3)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
};
template <class R, class A0, class A1, class A2, class A3, class A4>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
};
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5)>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
};
// Metrowerks thinks this creates ambiguities
# if !defined(__MWERKS__) || __MWERKS__ > 0x2406
template <class R, class A0>
struct arg_tuple_size<R (A0::*)() const>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
};
template <class R, class A0, class A1>
struct arg_tuple_size<R (A0::*)(A1) const>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
};
template <class R, class A0, class A1, class A2>
struct arg_tuple_size<R (A0::*)(A1, A2) const>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
};
template <class R, class A0, class A1, class A2, class A3>
struct arg_tuple_size<R (A0::*)(A1, A2, A3) const>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
};
template <class R, class A0, class A1, class A2, class A3, class A4>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) const>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
};
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) const>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
};
template <class R, class A0>
struct arg_tuple_size<R (A0::*)() volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
};
template <class R, class A0, class A1>
struct arg_tuple_size<R (A0::*)(A1) volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
};
template <class R, class A0, class A1, class A2>
struct arg_tuple_size<R (A0::*)(A1, A2) volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
};
template <class R, class A0, class A1, class A2, class A3>
struct arg_tuple_size<R (A0::*)(A1, A2, A3) volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
};
template <class R, class A0, class A1, class A2, class A3, class A4>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
};
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
};
template <class R, class A0>
struct arg_tuple_size<R (A0::*)() const volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
};
template <class R, class A0, class A1>
struct arg_tuple_size<R (A0::*)(A1) const volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
};
template <class R, class A0, class A1, class A2>
struct arg_tuple_size<R (A0::*)(A1, A2) const volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
};
template <class R, class A0, class A1, class A2, class A3>
struct arg_tuple_size<R (A0::*)(A1, A2, A3) const volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
};
template <class R, class A0, class A1, class A2, class A3, class A4>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4) const volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
};
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) const volatile>
{
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
};
# endif // __MWERKS__
# else
// We will use the "sizeof() trick" to work around the lack of
// partial specialization in MSVC6 and its broken-ness in borland.
// See http://opensource.adobe.com or
// http://groups.yahoo.com/group/boost/message/5441 for
// more examples
// The following helper functions are never actually called, since
// they are only used within a sizeof() expression, but the type of
// their return value is used to discriminate between various free
// and member function pointers at compile-time.
template <class R>
char_array<0> arg_tuple_size_helper(R (*)());
template <class R, class A1>
char_array<1> arg_tuple_size_helper(R (*)(A1));
template <class R, class A1, class A2>
char_array<2> arg_tuple_size_helper(R (*)(A1, A2));
template <class R, class A1, class A2, class A3>
char_array<3> arg_tuple_size_helper(R (*)(A1, A2, A3));
template <class R, class A1, class A2, class A3, class A4>
char_array<4> arg_tuple_size_helper(R (*)(A1, A2, A3, A4));
template <class R, class A1, class A2, class A3, class A4, class A5>
char_array<5> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5));
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
char_array<6> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5, A6));
template <class R, class A0>
char_array<1> arg_tuple_size_helper(R (A0::*)());
template <class R, class A0, class A1>
char_array<2> arg_tuple_size_helper(R (A0::*)(A1));
template <class R, class A0, class A1, class A2>
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2));
template <class R, class A0, class A1, class A2, class A3>
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3));
template <class R, class A0, class A1, class A2, class A3, class A4>
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4));
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5));
template <class R, class A0>
char_array<1> arg_tuple_size_helper(R (A0::*)() const);
template <class R, class A0, class A1>
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const);
template <class R, class A0, class A1, class A2>
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const);
template <class R, class A0, class A1, class A2, class A3>
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const);
template <class R, class A0, class A1, class A2, class A3, class A4>
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const);
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const);
template <class R, class A0>
char_array<1> arg_tuple_size_helper(R (A0::*)() volatile);
template <class R, class A0, class A1>
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) volatile);
template <class R, class A0, class A1, class A2>
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) volatile);
template <class R, class A0, class A1, class A2, class A3>
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) volatile);
template <class R, class A0, class A1, class A2, class A3, class A4>
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) volatile);
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) volatile);
template <class R, class A0>
char_array<1> arg_tuple_size_helper(R (A0::*)() const volatile);
template <class R, class A0, class A1>
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const volatile);
template <class R, class A0, class A1, class A2>
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const volatile);
template <class R, class A0, class A1, class A2, class A3>
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const volatile);
template <class R, class A0, class A1, class A2, class A3, class A4>
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const volatile);
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const volatile);
template <class F>
struct arg_tuple_size
{
// The sizeof() magic happens here
BOOST_STATIC_CONSTANT(std::size_t, value
= sizeof(arg_tuple_size_helper(F(0)).elements) - 1);
};
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}}} // namespace boost::python::detail
#endif // ARG_TUPLE_SIZE_DWA20011201_HPP

View File

@@ -13,7 +13,6 @@
# define BASE_OBJECT_DWA051600_H_
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/signatures.hpp> // really just for type<>
# include <boost/python/detail/wrap_python.hpp>
# include <cstring>
@@ -45,10 +44,7 @@ template <class PythonType>
base_object<PythonType>::base_object(PyTypeObject* type_obj)
{
base_python_type* bp = this;
#if !defined(_MSC_VER) || defined(__STLPORT)
std::
#endif
memset(bp, 0, sizeof(base_python_type));
BOOST_CSTD_::memset(bp, 0, sizeof(base_python_type));
Py_INCREF(type_obj);
PyObject_INIT(bp, type_obj);
}

View File

@@ -0,0 +1,66 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CALL_OBJECT_DWA20011222_HPP
# define CALL_OBJECT_DWA20011222_HPP
# include <boost/python/errors.hpp>
# include <boost/python/detail/types.hpp>
# include <boost/bind.hpp>
namespace boost { namespace python {
namespace detail
{
// A function object adaptor which turns a function returning R into
// an "equivalent" function returning void, but taking an R& in
// which the adapted function's result is stored.
template <class R, class F>
struct return_by_reference
{
typedef void return_type;
return_by_reference(R& result, F f)
: m_result(result)
, m_f(f)
{
}
void operator()() const
{
m_result = m_f();
}
R& m_result;
F m_f;
};
// An object generator for the above adaptors
template <class R, class F>
return_by_reference<R,F> bind_return(R& result, F f)
{
return return_by_reference<R,F>(result, f);
}
// Given a function object f with signature
//
// R f(PyTypeObject*,PyObject*)
//
// calls f inside of handle_exception_impl, placing f's result in
// ret. Returns true iff an exception is thrown by f, leaving ret
// unmodified.
template <class R, class F>
bool call_object(R& ret, PyObject* obj, F f)
{
return handle_exception(
detail::bind_return(
ret
, boost::bind<R>(
f, static_cast<type_object_base*>(obj->ob_type), obj)));
}
} // namespace detail
}} // namespace boost::python
#endif // CALL_OBJECT_DWA20011222_HPP

View File

@@ -0,0 +1,217 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CALLER_DWA20011214_HPP
# define CALLER_DWA20011214_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/eval.hpp>
# include <boost/python/detail/returning.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/type_traits/same_traits.hpp>
namespace boost { namespace python
{
template <class T> struct to_python;
}}
namespace boost { namespace python { namespace detail {
struct caller
{
typedef PyObject* result_type;
template <class P, class R>
PyObject* operator()(R (*f)(), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0>
PyObject* operator()(R (*f)(A0), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1>
PyObject* operator()(R (*f)(A0, A1), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2>
PyObject* operator()(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3>
PyObject* operator()(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
PyObject* operator()(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
PyObject* operator()(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
// Member functions
template <class P, class R, class A0>
PyObject* operator()(R (A0::*f)(), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1>
PyObject* operator()(R (A0::*f)(A1), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2>
PyObject* operator()(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3>
PyObject* operator()(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0>
PyObject* operator()(R (A0::*f)() const, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1>
PyObject* operator()(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2>
PyObject* operator()(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3>
PyObject* operator()(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0>
PyObject* operator()(R (A0::*f)() volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1>
PyObject* operator()(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2>
PyObject* operator()(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3>
PyObject* operator()(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0>
PyObject* operator()(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1>
PyObject* operator()(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2>
PyObject* operator()(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3>
PyObject* operator()(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
template <class P, class R, class A0, class A1, class A2, class A3, class A4, class A5>
PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords, P const& policies) const
{
return returning<R>::call(f, args, keywords, policies);
}
};
}}} // namespace boost::python::detail
#endif // CALLER_DWA20011214_HPP

View File

@@ -9,8 +9,9 @@
#ifndef CAST_DWA052500_H_
# define CAST_DWA052500_H_
# include <boost/python/detail/wrap_python.hpp>
# include <boost/operators.hpp>
# ifndef BOOST_PYTHON_V2
# include <boost/python/detail/wrap_python.hpp>
# include <boost/operators.hpp>
namespace boost { namespace python {
@@ -75,4 +76,6 @@ struct downcast
}} // namespace boost::python
# endif // BOOST_PYTHON_V2
#endif // CAST_DWA052500_H_

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CHAR_ARRAY_DWA2002129_HPP
# define CHAR_ARRAY_DWA2002129_HPP
namespace boost { namespace python { namespace detail {
// This little package is used to transmit the number of arguments
// from the helper functions below to the sizeof() expression below.
// Because we can never have an array of fewer than 1 element, we
// add 1 to n and then subtract 1 from the result of sizeof() below.
template <int n>
struct char_array
{
char elements[n+1];
};
}}} // namespace boost::python::detail
#endif // CHAR_ARRAY_DWA2002129_HPP

View File

@@ -59,9 +59,9 @@
# ifndef BOOST_PYTHON_MODULE_INIT
# if defined(_WIN32) || defined(__CYGWIN__)
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name()
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
# else
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name()
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
# endif
# endif
@@ -72,23 +72,35 @@
****************************************************************************/
// backwards compatibility:
#ifdef BOOST_RE_STATIC_LIB
#ifdef BOOST_PYTHON_STATIC_LIB
# define BOOST_PYTHON_STATIC_LINK
#endif
#if defined(BOOST_MSVC) && defined(_DLL)
# define BOOST_PYTHON_HAS_DLL_RUNTIME
#if defined(__MWERKS__) \
|| (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730)
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
#endif
#if defined(__BORLANDC__) && defined(_RTLDLL)
# define BOOST_PYTHON_HAS_DLL_RUNTIME
#if defined(__GNUC__)
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern
#endif
#if defined(__ICL) && defined(_DLL)
# define BOOST_PYTHON_HAS_DLL_RUNTIME
// Handle default cases
#ifndef BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
# ifdef _WIN32
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
# else
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
# endif
#endif
#if defined(BOOST_PYTHON_HAS_DLL_RUNTIME) && !defined(BOOST_PYTHON_STATIC_LINK)
#ifndef BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
#endif
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32)
# if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_DECL __declspec(dllexport)
# define BOOST_PYTHON_BUILD_DLL
@@ -101,10 +113,26 @@
# define BOOST_PYTHON_DECL
#endif
#if (defined(BOOST_MSVC) || defined(__BORLANDC__)) && !defined(BOOST_PYTHON_NO_LIB) && !defined(BOOST_PYTHON_SOURCE)
# include <boost/python/detail/python_library_include.hpp>
#ifndef BOOST_PYTHON_DECL_TEMPLATE
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
# define BOOST_PYTHON_DECL_TEMPLATE BOOST_PYTHON_DECL
# else
# define BOOST_PYTHON_DECL_TEMPLATE
# endif
#endif
#if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
#else
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
#endif
# ifndef BOOST_PYTHON_EXPORT_TEMPLATE
# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template
# endif
# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL
// Borland C++ Fix/error check:
#if defined(__BORLANDC__)
# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
@@ -117,7 +145,7 @@
# endif
# endif
# ifndef _RTLDLL
// this is harmless for a staic link:
// this is harmless for a static link:
# define _RWSTD_COMPILE_INSTANTIATE
# endif
# endif
@@ -129,4 +157,13 @@
# endif
#endif
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
// Work around a compiler bug.
// boost::python::detail::function has to be seen by the compiler before the
// boost::function class template.
namespace boost { namespace python { namespace detail {
class function;
}}}
#endif
#endif // CONFIG_DWA052200_H_

View File

@@ -0,0 +1,34 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CV_CATEGORY_DWA200222_HPP
# define CV_CATEGORY_DWA200222_HPP
# include <boost/type_traits/cv_traits.hpp>
namespace boost { namespace python { namespace detail {
template <bool is_const_, bool is_volatile_>
struct cv_tag
{
BOOST_STATIC_CONSTANT(bool, is_const = is_const_);
BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_);
};
typedef cv_tag<false,false> cv_unqualified;
typedef cv_tag<true,false> const_;
typedef cv_tag<false,true> volatile_;
typedef cv_tag<true,true> const_volatile_;
template <class T>
struct cv_category
{
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
typedef cv_tag<c,v> type;
};
}}} // namespace boost::python::detail
#endif // CV_CATEGORY_DWA200222_HPP

View File

@@ -0,0 +1,38 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef EVAL_DWA2002124_HPP
# define EVAL_DWA2002124_HPP
namespace boost { namespace python { namespace detail {
template <class T> struct undefined;
template <class UnaryMetaFunction, class T>
struct eval
{
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
// based on the (non-conforming) MSVC trick from MPL
template<bool>
struct unarymetafunction_vc : UnaryMetaFunction {};
// illegal C++ which causes VC to admit that unarymetafunction_vc
// can have a nested template:
template<>
struct unarymetafunction_vc<true>
{
template<class> struct apply;
};
typedef typename unarymetafunction_vc<
::boost::mpl::detail::msvc_never_true<UnaryMetaFunction>::value
>::template apply<T>::type type;
# else
typedef typename UnaryMetaFunction::template apply<T>::type type;
# endif
};
}}} // namespace boost::python::detail
#endif // EVAL_DWA2002124_HPP

View File

@@ -1,4 +1,4 @@
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
@@ -26,7 +26,7 @@
# include <memory>
# include <boost/python/detail/init_function.hpp>
# include <typeinfo>
# include <boost/smart_ptr.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/type_traits.hpp>
namespace boost { namespace python {
@@ -38,20 +38,45 @@ template <class T> struct right_operand;
enum without_downcast_t { without_downcast };
namespace detail {
namespace detail
{
// forward declarations
class extension_instance;
class extension_class_base;
template <class T> class instance_holder;
template <class T, class U> class instance_value_holder;
template <class ref, class T> class instance_ptr_holder;
template <class Specified> struct operand_select;
class extension_instance;
class extension_class_base;
template <class T> class instance_holder;
template <class T, class U> class instance_value_holder;
template <class ref, class T> class instance_ptr_holder;
template <class Specified> struct operand_select;
template <long> struct choose_op;
template <long> struct choose_rop;
template <long> struct choose_unary_op;
template <long> struct define_operator;
class BOOST_PYTHON_DECL extension_instance : public instance
{
public:
extension_instance(PyTypeObject* class_);
~extension_instance();
void add_implementation(std::auto_ptr<instance_holder_base> holder);
typedef std::vector<instance_holder_base*> held_objects;
const held_objects& wrapped_objects() const
{ return m_wrapped_objects; }
private:
held_objects m_wrapped_objects;
};
} // namespace detail
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t<detail::extension_instance>;
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class<detail::extension_instance>;
# endif
namespace detail {
BOOST_PYTHON_DECL meta_class<extension_instance>* extension_meta_class();
BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p);
BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
@@ -702,25 +727,80 @@ class held_instance : public Held
public:
held_instance(PyObject*) : Held() {}
template <class A1>
held_instance(PyObject*, A1 a1) : Held(a1) {}
held_instance(PyObject*, A1 a1) : Held(
typename unwrap_parameter<A1>::type(a1)) {}
template <class A1, class A2>
held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {}
held_instance(PyObject*, A1 a1, A2 a2) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)) {}
template <class A1, class A2, class A3>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)) {}
template <class A1, class A2, class A3, class A4>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)) {}
template <class A1, class A2, class A3, class A4, class A5>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(a1, a2, a3, a4, a5, a6, a7, a8) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)
, typename unwrap_parameter<A8>::type(a8)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)
, typename unwrap_parameter<A8>::type(a8)
, typename unwrap_parameter<A9>::type(a9)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)
, typename unwrap_parameter<A8>::type(a8)
, typename unwrap_parameter<A9>::type(a9)
, typename unwrap_parameter<A10>::type(a10)) {}
};
// Abstract base class for all obj holders. Base for template class
@@ -813,21 +893,6 @@ class instance_ptr_holder : public instance_holder<HeldType>
PtrType m_ptr;
};
class BOOST_PYTHON_DECL extension_instance : public instance
{
public:
extension_instance(PyTypeObject* class_);
~extension_instance();
void add_implementation(std::auto_ptr<instance_holder_base> holder);
typedef std::vector<instance_holder_base*> held_objects;
const held_objects& wrapped_objects() const
{ return m_wrapped_objects; }
private:
held_objects m_wrapped_objects;
};
//
// Template function implementations
//

View File

@@ -0,0 +1,174 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef INDIRECT_TRAITS_DWA2002131_HPP
# define INDIRECT_TRAITS_DWA2002131_HPP
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/mpl/select_type.hpp>
namespace boost { namespace python { namespace detail {
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct is_reference_to_const
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
template <class T>
struct is_reference_to_const<T const&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_reference_to_non_const
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
template <class T>
struct is_reference_to_non_const<T&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_reference_to_volatile
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
template <class T>
struct is_reference_to_volatile<T volatile&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_reference_to_pointer
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
template <class T>
struct is_reference_to_pointer<T*&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_reference_to_pointer<T* const&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_reference_to_pointer<T* volatile&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_reference_to_pointer<T* const volatile&>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
# else
typedef char (&inner_yes_type)[3];
typedef char (&inner_no_type)[2];
typedef char (&outer_no_type)[1];
template <typename V>
struct is_const_help
{
typedef typename mpl::select_type<
is_const<V>::value
, inner_yes_type
, inner_no_type
>::type type;
};
template <typename V>
struct is_volatile_help
{
typedef typename mpl::select_type<
is_volatile<V>::value
, inner_yes_type
, inner_no_type
>::type type;
};
template <typename V>
struct is_pointer_help
{
typedef typename mpl::select_type<
is_pointer<V>::value
, inner_yes_type
, inner_no_type
>::type type;
};
template <typename V>
typename is_const_help<V>::type reference_to_const_helper(V&);
outer_no_type
reference_to_const_helper(...);
template <class T>
struct is_reference_to_const
{
static T t;
BOOST_STATIC_CONSTANT(
bool, value
= (is_reference<T>::value
&& sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)));
};
template <class T>
struct is_reference_to_non_const
{
static T t;
BOOST_STATIC_CONSTANT(
bool, value
= (is_reference<T>::value
&& sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)));
};
template <typename V>
typename is_volatile_help<V>::type reference_to_volatile_helper(V&);
outer_no_type reference_to_volatile_helper(...);
template <class T>
struct is_reference_to_volatile
{
static T t;
BOOST_STATIC_CONSTANT(
bool, value
= (is_reference<T>::value
&& sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)));
};
template <typename V>
typename is_pointer_help<V>::type reference_to_pointer_helper(V&);
outer_no_type reference_to_pointer_helper(...);
template <class T>
struct is_reference_to_pointer
{
static T t;
BOOST_STATIC_CONSTANT(
bool, value
= (is_reference<T>::value
&& sizeof(reference_to_pointer_helper(t)) == sizeof(inner_yes_type))
);
};
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}}} // namespace boost::python::detail
#endif // INDIRECT_TRAITS_DWA2002131_HPP

View File

@@ -1,4 +1,4 @@
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
@@ -89,11 +89,14 @@ namespace detail {
typedef void const_reference;
};
struct reference_parameter_base {};
template <class T>
class reference_parameter
: public reference_parameter_base
{
typedef typename parameter_traits<T>::const_reference const_reference;
public:
typedef typename parameter_traits<T>::const_reference const_reference;
reference_parameter(const_reference value)
: value(value) {}
operator const_reference() { return value; }
@@ -101,6 +104,51 @@ namespace detail {
const_reference value;
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct unwrap_parameter
{
typedef typename boost::add_reference<T>::type type;
};
template <class T>
struct unwrap_parameter<reference_parameter<T> >
{
typedef typename reference_parameter<T>::const_reference type;
};
# else
template <bool is_wrapped>
struct unwrap_parameter_helper
{
template <class T>
struct apply
{
typedef typename T::const_reference type;
};
};
template <>
struct unwrap_parameter_helper<false>
{
template <class T>
struct apply
{
typedef typename add_reference<T>::type type;
};
};
template <class T>
struct unwrap_parameter
{
BOOST_STATIC_CONSTANT(
bool, is_wrapped = (is_base_and_derived<T,reference_parameter_base>::value));
typedef typename unwrap_parameter_helper<
is_wrapped
>::template apply<T>::type type;
};
# endif
class extension_instance;
class instance_holder_base;

View File

@@ -0,0 +1,44 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MAP_ENTRY_DWA2002118_HPP
# define MAP_ENTRY_DWA2002118_HPP
namespace boost { namespace python { namespace detail {
// A trivial type that works well as the value_type of associative
// vector maps
template <class Key, class Value>
struct map_entry
{
map_entry() {}
map_entry(Key k) : key(k), value() {}
map_entry(Key k, Value v) : key(k), value(v) {}
bool operator<(map_entry const& rhs) const
{
return this->key < rhs.key;
}
Key key;
Value value;
};
template <class Key, class Value>
bool operator<(map_entry<Key,Value> const& e, Key const& k)
{
return e.key < k;
}
template <class Key, class Value>
bool operator<(Key const& k, map_entry<Key,Value> const& e)
{
return k < e.key;
}
}}} // namespace boost::python::detail
#endif // MAP_ENTRY_DWA2002118_HPP

View File

@@ -0,0 +1,99 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MSVC_TYPEINFO_DWA200222_HPP
# define MSVC_TYPEINFO_DWA200222_HPP
#include <boost/type.hpp>
#include <typeinfo>
//
// Fix for MSVC's broken typeid() implementation which doesn't strip
// decoration. This fix doesn't handle cv-qualified array types. It
// could probably be done, but I haven't figured it out yet.
//
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600
namespace boost { namespace python { namespace detail {
typedef std::type_info const& typeinfo;
template<int>struct value_id_accessor;
template<>
struct value_id_accessor<0>
{
template <class T>
static typeinfo get(T*) { return typeid(T); }
};
template<>
struct value_id_accessor<1>
{
template <class T>
static typeinfo get(T const*) { return typeid(T); }
};
template<>
struct value_id_accessor<2>
{
template <class T>
static typeinfo get(T volatile*) { return typeid(T); }
};
template<>
struct value_id_accessor<3>
{
template <class T>
static typeinfo get(T const volatile*) { return typeid(T); }
};
template <bool> struct bool_t{};
template <class T>
inline typeinfo typeid_nonref(boost::type<T>* = 0)
{
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
return value_id_accessor<(2 * v + c)>::get((T*)0);
}
template <class T>
inline typeinfo typeid_ref(boost::type<T>*, ...)
{
return typeid_nonref<T>();
}
template <class U, class T>
inline typeinfo typeid_ref(boost::type<U>*, T& (*)())
{
return typeid_nonref<T>();
}
template <class T>
inline typeinfo typeid_array(bool_t<false>, boost::type<T>* = 0)
{
typedef T (*x)();
return typeid_ref((boost::type<T>*)0, x(0));
}
template <class T>
inline typeinfo typeid_array(bool_t<true>, boost::type<T>* = 0)
{
return typeid_nonref<T>();
}
template <class T>
inline typeinfo msvc_typeid(boost::type<T>* = 0)
{
typedef bool_t<is_array<T>::value> tag;
return typeid_array(tag(), (boost::type<T>*)0);
}
}}} // namespace boost::python::detail
# endif // BOOST_MSVC
#endif // MSVC_TYPEINFO_DWA200222_HPP

View File

@@ -0,0 +1,183 @@
#error obsolete
/*
*
* Copyright (c) 1998-2000
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_libary_include.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers.
* Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_LIBRARY_INCLUDE_HPP
#define BOOST_REGEX_LIBRARY_INCLUDE_HPP
#ifndef BOOST_REGEX_NO_LIB
#if defined(BOOST_MSVC) && !defined(BOOST_REGEX_BUILD_DLL)
#ifdef __SGI_STL_PORT
#ifdef _DLL
// All these are multithreaded:
#if defined(_DEBUG) && defined(__STL_DEBUG)
#pragma comment(lib, "vc6-stlport-re300ddl.lib")
#elif defined(_DEBUG)
#pragma comment(lib, "vc6-stlport-re300dl.lib")
#elif defined(BOOST_REGEX_STATIC_LINK)
// static regex lib, dll runtime
#pragma comment(lib, "vc6-stlport-re300ls.lib")
#else // DEBUG
#pragma comment(lib, "vc6-stlport-re300l.lib")
#endif // _DEBUG
#else // _DLL
#ifdef _MT
#if defined(_DEBUG) && defined(__STL_DEBUG)
#pragma comment(lib, "vc6-stlport-re300ddm.lib")
#elif defined(_DEBUG)
#pragma comment(lib, "vc6-stlport-re300dm.lib")
#else //_DEBUG
#pragma comment(lib, "vc6-stlport-re300m.lib")
#endif //_DEBUG
#else //_MT
// STLPort does not support single threaded builds:
#error STLPort does not support single threaded builds
#endif //_MT
#endif //_DLL
#elif _MSC_VER < 1300
#ifdef _DLL
// All these are multithreaded:
#ifdef _DEBUG
#pragma comment(lib, "vc6-re300dl.lib")
#elif defined(BOOST_REGEX_STATIC_LINK)
// static regex lib, dll runtime
#pragma comment(lib, "vc6-re300ls.lib")
#else // DEBUG
#pragma comment(lib, "vc6-re300l.lib")
#endif // _DEBUG
#else // _DLL
#ifdef _MT
#ifdef _DEBUG
#pragma comment(lib, "vc6-re300dm.lib")
#else //_DEBUG
#pragma comment(lib, "vc6-re300m.lib")
#endif //_DEBUG
#else //_MT
#ifdef _DEBUG
#pragma comment(lib, "vc6-re300d.lib")
#else //_DEBUG
#pragma comment(lib, "vc6-re300.lib")
#endif //_DEBUG
#endif //_MT
#endif //_DLL
#else
#ifdef _DLL
// All these are multithreaded:
#ifdef _DEBUG
#pragma comment(lib, "vc7-re300dl.lib")
#elif defined(BOOST_REGEX_STATIC_LINK)
// static regex lib, dll runtime
#pragma comment(lib, "vc7-re300ls.lib")
#else // DEBUG
#pragma comment(lib, "vc7-re300l.lib")
#endif // _DEBUG
#else // _DLL
#ifdef _MT
#ifdef _DEBUG
#pragma comment(lib, "vc7-re300dm.lib")
#else //_DEBUG
#pragma comment(lib, "vc7-re300m.lib")
#endif //_DEBUG
#else //_MT
#ifdef _DEBUG
#pragma comment(lib, "vc7-re300d.lib")
#else //_DEBUG
#pragma comment(lib, "vc7-re300.lib")
#endif //_DEBUG
#endif //_MT
#endif //_DLL
#endif // __SGI_STL_PORT
#endif //BOOST_MSVC
#if defined(__BORLANDC__) && !defined(BOOST_REGEX_BUILD_DLL)
#if __BORLANDC__ < 0x550
#ifdef BOOST_REGEX_USE_VCL
#ifdef _RTLDLL
#pragma comment(lib, "bcb4re300lv.lib")
#else
#pragma comment(lib, "bcb4re300v.lib")
#endif
#else // VCL
#ifdef _RTLDLL
#ifdef __MT__
#pragma comment(lib, "bcb4re300lm.lib")
#else // __MT__
#pragma comment(lib, "bcb4re300l.lib")
#endif // __MT__
#else //_RTLDLL
#ifdef __MT__
#pragma comment(lib, "bcb4re300m.lib")
#else // __MT__
#pragma comment(lib, "bcb4re300.lib")
#endif // __MT__
#endif // _RTLDLL
#endif // VCL
#else // C++ Builder 5:
#ifdef BOOST_REGEX_USE_VCL
#ifdef _RTLDLL
#pragma comment(lib, "bcb5re300lv.lib")
#else
#pragma comment(lib, "bcb5re300v.lib")
#endif
#else // VCL
#ifdef _RTLDLL
#ifdef __MT__
#pragma comment(lib, "bcb5re300lm.lib")
#else // __MT__
#pragma comment(lib, "bcb5re300l.lib")
#endif // __MT__
#else //_RTLDLL
#ifdef __MT__
#pragma comment(lib, "bcb5re300m.lib")
#else // __MT__
#pragma comment(lib, "bcb5re300.lib")
#endif // __MT__
#endif // _RTLDLL
#endif // VCL
#endif
#endif //__BORLANDC__
#endif //BOOST_REGEX_NO_LIB
#endif // BOOST_REGEX_LIBRARY_INCLUDE_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,217 @@
// (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// This work was funded in part by Lawrence Berkeley and Lawrence
// Livermore National Labs
//
// This file generated for 5-argument member functions and 6-argument free
// functions by gen_signature.py
#ifndef SIGNATURE_DWA2002128_HPP
# define SIGNATURE_DWA2002128_HPP
# include <boost/mpl/type_list.hpp>
namespace boost { namespace python { namespace detail {
template <class R>
mpl::type_list<R>
signature(R (*)())
{
return mpl::type_list<R>();
}
template <class R, class A0>
mpl::type_list<R,A0>
signature(R (*)(A0))
{
return mpl::type_list<R,A0>();
}
template <class R, class A0, class A1>
mpl::type_list<R,A0,A1>
signature(R (*)(A0, A1))
{
return mpl::type_list<R,A0,A1>();
}
template <class R, class A0, class A1, class A2>
mpl::type_list<R,A0,A1,A2>
signature(R (*)(A0, A1, A2))
{
return mpl::type_list<R,A0,A1,A2>();
}
template <class R, class A0, class A1, class A2, class A3>
mpl::type_list<R,A0,A1,A2,A3>
signature(R (*)(A0, A1, A2, A3))
{
return mpl::type_list<R,A0,A1,A2,A3>();
}
template <class R, class A0, class A1, class A2, class A3, class A4>
mpl::type_list<R,A0,A1,A2,A3,A4>
signature(R (*)(A0, A1, A2, A3, A4))
{
return mpl::type_list<R,A0,A1,A2,A3,A4>();
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
mpl::type_list<R,A0,A1,A2,A3,A4,A5>
signature(R (*)(A0, A1, A2, A3, A4, A5))
{
return mpl::type_list<R,A0,A1,A2,A3,A4,A5>();
}
template <class R, class A0>
mpl::type_list<R,A0&> signature(R (A0::*)())
{
return mpl::type_list<R,A0&>();
}
template <class R, class A0, class A1>
mpl::type_list<R,A0&,A1> signature(R (A0::*)(A1))
{
return mpl::type_list<R,A0&,A1>();
}
template <class R, class A0, class A1, class A2>
mpl::type_list<R,A0&,A1,A2> signature(R (A0::*)(A1, A2))
{
return mpl::type_list<R,A0&,A1,A2>();
}
template <class R, class A0, class A1, class A2, class A3>
mpl::type_list<R,A0&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3))
{
return mpl::type_list<R,A0&,A1,A2,A3>();
}
template <class R, class A0, class A1, class A2, class A3, class A4>
mpl::type_list<R,A0&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4))
{
return mpl::type_list<R,A0&,A1,A2,A3,A4>();
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
mpl::type_list<R,A0&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5))
{
return mpl::type_list<R,A0&,A1,A2,A3,A4,A5>();
}
template <class R, class A0>
mpl::type_list<R,A0 const&> signature(R (A0::*)() const)
{
return mpl::type_list<R,A0 const&>();
}
template <class R, class A0, class A1>
mpl::type_list<R,A0 const&,A1> signature(R (A0::*)(A1) const)
{
return mpl::type_list<R,A0 const&,A1>();
}
template <class R, class A0, class A1, class A2>
mpl::type_list<R,A0 const&,A1,A2> signature(R (A0::*)(A1, A2) const)
{
return mpl::type_list<R,A0 const&,A1,A2>();
}
template <class R, class A0, class A1, class A2, class A3>
mpl::type_list<R,A0 const&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3) const)
{
return mpl::type_list<R,A0 const&,A1,A2,A3>();
}
template <class R, class A0, class A1, class A2, class A3, class A4>
mpl::type_list<R,A0 const&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4) const)
{
return mpl::type_list<R,A0 const&,A1,A2,A3,A4>();
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
mpl::type_list<R,A0 const&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5) const)
{
return mpl::type_list<R,A0 const&,A1,A2,A3,A4,A5>();
}
template <class R, class A0>
mpl::type_list<R,A0 volatile&> signature(R (A0::*)() volatile)
{
return mpl::type_list<R,A0 volatile&>();
}
template <class R, class A0, class A1>
mpl::type_list<R,A0 volatile&,A1> signature(R (A0::*)(A1) volatile)
{
return mpl::type_list<R,A0 volatile&,A1>();
}
template <class R, class A0, class A1, class A2>
mpl::type_list<R,A0 volatile&,A1,A2> signature(R (A0::*)(A1, A2) volatile)
{
return mpl::type_list<R,A0 volatile&,A1,A2>();
}
template <class R, class A0, class A1, class A2, class A3>
mpl::type_list<R,A0 volatile&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3) volatile)
{
return mpl::type_list<R,A0 volatile&,A1,A2,A3>();
}
template <class R, class A0, class A1, class A2, class A3, class A4>
mpl::type_list<R,A0 volatile&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4) volatile)
{
return mpl::type_list<R,A0 volatile&,A1,A2,A3,A4>();
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
mpl::type_list<R,A0 volatile&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5) volatile)
{
return mpl::type_list<R,A0 volatile&,A1,A2,A3,A4,A5>();
}
template <class R, class A0>
mpl::type_list<R,A0 const volatile&> signature(R (A0::*)() const volatile)
{
return mpl::type_list<R,A0 const volatile&>();
}
template <class R, class A0, class A1>
mpl::type_list<R,A0 const volatile&,A1> signature(R (A0::*)(A1) const volatile)
{
return mpl::type_list<R,A0 const volatile&,A1>();
}
template <class R, class A0, class A1, class A2>
mpl::type_list<R,A0 const volatile&,A1,A2> signature(R (A0::*)(A1, A2) const volatile)
{
return mpl::type_list<R,A0 const volatile&,A1,A2>();
}
template <class R, class A0, class A1, class A2, class A3>
mpl::type_list<R,A0 const volatile&,A1,A2,A3> signature(R (A0::*)(A1, A2, A3) const volatile)
{
return mpl::type_list<R,A0 const volatile&,A1,A2,A3>();
}
template <class R, class A0, class A1, class A2, class A3, class A4>
mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4> signature(R (A0::*)(A1, A2, A3, A4) const volatile)
{
return mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4>();
}
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4,A5> signature(R (A0::*)(A1, A2, A3, A4, A5) const volatile)
{
return mpl::type_list<R,A0 const volatile&,A1,A2,A3,A4,A5>();
}
}}} // namespace boost::python::detail
#endif // SIGNATURE_DWA2002128_HPP

View File

@@ -0,0 +1,16 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TYPE_LIST_DWA200222_HPP
# define TYPE_LIST_DWA200222_HPP
# include <boost/mpl/type_list.hpp>
namespace boost { namespace python { namespace detail {
struct empty_list : boost::mpl::type_list<>::type {};
}}} // namespace boost::python::detail
#endif // TYPE_LIST_DWA200222_HPP

View File

@@ -31,12 +31,8 @@
namespace boost { namespace python {
class string;
namespace detail {
class instance_holder_base;
class BOOST_PYTHON_DECL type_object_base : public python_type
{
public:

View File

@@ -0,0 +1,156 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef UNWIND_TYPE_DWA200222_HPP
# define UNWIND_TYPE_DWA200222_HPP
# include <boost/python/detail/cv_category.hpp>
namespace boost { namespace python { namespace detail {
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
{
return Generator::execute(p);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U const* p, const_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_ptr_type(U* p, Generator* = 0)
{
typedef typename cv_category<U>::type tag;
return unwind_type_cv<Generator>(p, tag());
}
template <bool is_ptr>
struct unwind_helper
{
template <class Generator, class U>
static typename Generator::result_type
execute(U p, Generator* = 0)
{
return unwind_ptr_type(p, (Generator*)0);
}
};
template <>
struct unwind_helper<false>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U& p, Generator* = 0)
{
return unwind_ptr_type(&p, (Generator*)0);
}
};
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(U& p, Generator* = 0)
{
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(U const& p, Generator* = 0)
{
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
}
enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
template <int indirection> struct unwind_helper2;
template <>
struct unwind_helper2<direct_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<pointer_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U*(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<reference_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U&(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<reference_to_pointer_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U&(*)(), Generator* = 0)
{
return unwind_ptr_type(U(0), (Generator*)0);
}
};
// Call this one with both template parameters explicitly specified
// and no function arguments:
//
// return unwind_type<my_generator,T>();
//
// Doesn't work if T is an array type; we could handle that case, but
// why bother?
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(type<U>*p = 0, Generator* = 0)
{
BOOST_STATIC_CONSTANT(int, indirection
= (is_pointer<U>::value ? pointer_ : 0)
+ (is_reference_to_pointer<U>::value
? reference_to_pointer_
: is_reference<U>::value
? reference_
: 0));
return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
}
}}} // namespace boost::python::detail
#endif // UNWIND_TYPE_DWA200222_HPP

View File

@@ -8,7 +8,7 @@
namespace boost { namespace python { namespace detail {
BOOST_PYTHON_DECL extern PyObject arbitrary_object;
extern BOOST_PYTHON_DECL PyObject arbitrary_object;
template <class T>
struct void_adaptor

View File

@@ -0,0 +1,56 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef WRAP_FUNCTION_DWA2002118_HPP
# define WRAP_FUNCTION_DWA2002118_HPP
# include <boost/python/make_function.hpp>
# include <boost/type_traits/ice.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/mpl/select_type.hpp>
namespace boost { namespace python { namespace detail {
// A function which converts its argument into a Python callable
// object. Not very general yet!
// This should eventually be replaced with a mechanism for specialized
// wrap/unwrap objects. In other words, to_python(f), where f is a
// function pointer or function type, should produce a callable Python
// object.
template <bool needs_wrapping>
struct wrap_function_select
{
template <class F>
static objects::function* execute(F f)
{
return make_function(f);
}
};
template<>
struct wrap_function_select<false>
{
template <class F>
static F execute(F f)
{
return f;
}
};
template <class F>
PyObject* wrap_function(F f)
{
return wrap_function_select<
type_traits::ice_or<
is_function<F>::value
, is_member_function_pointer<F>::value
>::value >::execute(f);
}
}}} // namespace boost::python::detail
#endif // WRAP_FUNCTION_DWA2002118_HPP

View File

@@ -34,36 +34,38 @@
// Some things we need in order to get Python.h to work with compilers other
// than MSVC on Win32
//
#if defined(_WIN32)
#if defined(_WIN32) || defined(__CYGWIN__)
# if defined(__GNUC__) && defined(__CYGWIN__)
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2
typedef int pid_t;
# define WORD_BIT 32
# define hypot _hypot
# include <stdio.h>
# if PY_MAJOR_VERSION < 2
# define HAVE_CLOCK
# define HAVE_STRFTIME
# define HAVE_STRERROR
# endif
# define NT_THREADS
# if __GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3
# define WITH_THREAD
# endif
# ifndef NETSCAPE_PI
# define USE_SOCKET
# endif
# ifdef USE_DL_IMPORT
# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
# endif
# ifdef USE_DL_EXPORT
# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
# endif
# define HAVE_LONG_LONG 1
# define LONG_LONG long long
# endif
# if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2
# define HAVE_CLOCK
# define HAVE_STRFTIME
# define HAVE_STRERROR
# endif
# define NT_THREADS
# define WITH_THREAD
# ifndef NETSCAPE_PI
# define USE_SOCKET
# endif
# ifdef USE_DL_IMPORT
# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
# endif
# ifdef USE_DL_EXPORT
# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
# endif
# define HAVE_LONG_LONG 1
# define LONG_LONG long long
# elif defined(__MWERKS__)

View File

@@ -9,57 +9,31 @@
#ifndef ERRORS_DWA052500_H_
# define ERRORS_DWA052500_H_
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/function.hpp>
namespace boost { namespace python {
struct error_already_set {};
struct argument_error : error_already_set {};
struct object_functor_base
{
typedef PyObject* result_type;
virtual PyObject* operator()() const = 0;
private:
static void* operator new(std::size_t); // don't allow dynamic allocation
void operator delete(void*);
void operator delete(void*, size_t);
};
template <class T>
struct object_functor : object_functor_base
{
object_functor(T const& f)
: m_f(f)
{
}
PyObject* operator()() const
{
return m_f();
}
private:
T const& m_f;
};
// Handles exceptions caught just before returning to Python code.
PyObject* handle_exception_impl(object_functor_base const& f);
// Returns true iff an exception was caught.
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>);
template <class T>
PyObject* handle_exception(T const& f)
bool handle_exception(T f)
{
return handle_exception_impl(object_functor<T>(f));
return handle_exception_impl(function0<void>(boost::ref(f)));
}
void handle_exception(void (*)());
BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x);
template <class T>
T* expect_non_null(T* x)
{
if (x == 0)
throw error_already_set();
return x;
return (T*)expect_non_null((PyObject*)x);
}
}} // namespace boost::python

View File

@@ -0,0 +1,42 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FROM_PYTHON_DWA2002128_HPP
# define FROM_PYTHON_DWA2002128_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/target.hpp>
namespace boost { namespace python {
template <class T>
struct from_python
: converter::from_python_lookup<typename converter::target<T>::type>
{
typedef converter::from_python_lookup<typename converter::target<T>::type> base;
from_python(PyObject*);
};
// specialization for PyObject*
template <>
struct from_python<PyObject*>
{
from_python(PyObject*) {}
bool convertible() const { return true; }
PyObject* operator()(PyObject* source) const { return source; }
};
//
// implementations
//
template <class T>
from_python<T>::from_python(PyObject* source)
: base(source)
{
}
}} // namespace boost::python
#endif // FROM_PYTHON_DWA2002128_HPP

View File

@@ -0,0 +1,54 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MAKE_FUNCTION_DWA20011221_HPP
# define MAKE_FUNCTION_DWA20011221_HPP
# include <boost/python/object/function.hpp>
# include <boost/python/object/make_holder.hpp>
# include <boost/python/detail/caller.hpp>
# include <boost/python/detail/arg_tuple_size.hpp>
# include <boost/mpl/size.hpp>
# include <boost/function.hpp>
# include <boost/bind.hpp>
# include <boost/python/default_call_policies.hpp>
namespace boost { namespace python {
template <class F>
objects::function* make_function(F f)
{
return new objects::function(
objects::py_function(
::boost::bind<PyObject*>(detail::caller(), f, _1, _2, default_call_policies()))
, detail::arg_tuple_size<F>::value);
}
template <class F, class Policies>
objects::function* make_function(F f, Policies const& policies)
{
return new objects::function(
objects::py_function(
::boost::bind<PyObject*>(detail::caller(), f, _1, _2, policies))
, detail::arg_tuple_size<F>::value);
}
template <class T, class ArgList, class Generator>
objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0)
{
enum { nargs = mpl::size<ArgList>::value };
return new objects::function(
objects::py_function(
::boost::bind<PyObject*>(detail::caller(),
objects::make_holder<nargs>
::template apply<T,Generator,ArgList>::execute
, _1, _2, default_call_policies()))
, nargs + 1);
}
}} // namespace boost::python
#endif // MAKE_FUNCTION_DWA20011221_HPP

View File

@@ -0,0 +1,42 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MANAGE_NEW_OBJECT_DWA200222_HPP
# define MANAGE_NEW_OBJECT_DWA200222_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/to_python_indirect.hpp>
# include <boost/type_traits/composite_traits.hpp>
namespace boost { namespace python {
namespace detail
{
template <class R>
struct manage_new_object_requires_a_pointer_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
template <class T> struct to_python_value;
struct manage_new_object
{
template <class T>
struct apply
{
typedef typename mpl::select_type<
boost::is_pointer<T>::value
, to_python_indirect<T, detail::make_owning_holder>
, detail::manage_new_object_requires_a_pointer_return_type<T>
>::type type;
};
};
}} // namespace boost::python
#endif // MANAGE_NEW_OBJECT_DWA200222_HPP

View File

@@ -0,0 +1,110 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MODULE_DWA2001128_HPP
# define MODULE_DWA2001128_HPP
# include <boost/python/errors.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/reference.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/objects.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/class_fwd.hpp>
namespace boost { namespace python {
class BOOST_PYTHON_DECL module_base
{
public:
// Create a module. REQUIRES: only one module is created per module.
module_base(const char* name);
~module_base();
// Add elements to the module
void setattr(const char* name, PyObject*);
void setattr(const char* name, ref const&);
void add(PyTypeObject* x); // just use the type's name
void add_type(ref);
// Return a reference to the Python module object being built
ref module() const;
private:
ref m_module;
static PyMethodDef initial_methods[1];
};
class module : public module_base
{
public:
module(const char* name)
: module_base(name) {}
// Add elements to the module
module& setattr(const char* name, PyObject*);
module& setattr(const char* name, PyTypeObject*);
module& setattr(const char* name, ref const&);
module& add(PyTypeObject* x); // just use the type's name
template <class T, class Bases, class HolderGenerator>
module& add(class_<T,Bases,HolderGenerator> const& c)
{
Py_INCREF(c.object());
this->add_type(c.object());
return *this;
}
template <class Fn>
module& def(char const* name, Fn fn)
{
this->setattr(name, boost::python::make_function(fn));
return *this;
}
template <class Fn, class ResultHandler>
module& def(char const* name, Fn fn, ResultHandler handler)
{
this->setattr(name, boost::python::make_function(fn, handler));
return *this;
}
};
//
// inline implementations
//
inline ref module_base::module() const
{
return m_module;
}
inline module& module::setattr(const char* name, PyObject* x)
{
this->module_base::setattr(name, x);
return *this;
}
inline module& module::setattr(const char* name, PyTypeObject* x)
{
this->module_base::setattr(name, (PyObject*)x);
return *this;
}
inline module& module::setattr(const char* name, ref const& x)
{
this->module_base::setattr(name, x);
return *this;
}
inline module& module::add(PyTypeObject* x)
{
this->module_base::add(x);
return *this;
}
}} // namespace boost::python
#endif // MODULE_DWA20011221_HPP

View File

@@ -16,30 +16,18 @@
namespace boost { namespace python {
class module_builder
class BOOST_PYTHON_DECL module_builder_base
{
public:
// Create a module. REQUIRES: only one module_builder is created per module.
module_builder(const char* name);
~module_builder();
module_builder_base(const char* name);
~module_builder_base();
// Add elements to the module
void add(detail::function* x, const char* name);
void add(PyTypeObject* x, const char* name = 0);
void add(ref x, const char*name);
template <class Fn>
void def_raw(Fn fn, const char* name)
{
add(detail::new_raw_arguments_function(fn), name);
}
template <class Fn>
void def(Fn fn, const char* name)
{
add(detail::new_wrapped_function(fn), name);
}
// Return true iff a module is currently being built.
static bool initializing();
@@ -55,10 +43,29 @@ class module_builder
static PyMethodDef initial_methods[1];
};
class module_builder : public module_builder_base
{
public:
module_builder(const char* name)
: module_builder_base(name) {}
template <class Fn>
void def_raw(Fn fn, const char* name)
{
add(detail::new_raw_arguments_function(fn), name);
}
template <class Fn>
void def(Fn fn, const char* name)
{
add(detail::new_wrapped_function(fn), name);
}
};
//
// inline implementations
//
inline PyObject* module_builder::module() const
inline PyObject* module_builder_base::module() const
{
return m_module;
}

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef AUTO_PTR_GENERATOR_DWA2002123_HPP
# define AUTO_PTR_GENERATOR_DWA2002123_HPP
# include <memory>
namespace boost { namespace python { namespace object {
struct auto_ptr_generator
{
template <class T>
struct apply
{
typedef std::auto_ptr<T> type;
};
};
}}} // namespace boost::python::object
#endif // AUTO_PTR_GENERATOR_DWA2002123_HPP

View File

@@ -0,0 +1,111 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_DWA20011214_HPP
# define CLASS_DWA20011214_HPP
# include <boost/python/module.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/utility.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/reference.hpp>
# include <boost/iterator_adaptors.hpp>
# include <cstddef>
namespace boost { namespace python {
class module;
namespace objects {
template <class T> struct holder;
// To identify a class, we don't need cv/reference decorations
typedef converter::undecorated_type_id_t class_id;
struct BOOST_PYTHON_DECL class_base : noncopyable
{
// constructor
class_base(
char const* name // The name of the class
, std::size_t num_types // A list of class_ids. The first is the type
, class_id const*const types // this is wrapping. The rest are the types of
// any bases.
);
// Retrieve the underlying object
ref object() const { return m_object; }
private:
ref m_object;
};
// Base class for all holders
struct BOOST_PYTHON_DECL instance_holder : noncopyable
{
public:
instance_holder();
virtual ~instance_holder();
// return the next holder in a chain
instance_holder* next() const;
virtual void* holds(converter::type_id_t) = 0;
void install(PyObject* inst) throw();
struct iterator_policies : default_iterator_policies
{
template <class Iterator>
void increment(Iterator& p)
{
p.base() = p.base()->next();
}
};
typedef iterator_adaptor<
instance_holder*
, iterator_policies
, value_type_is<noncopyable>
, reference_is<instance_holder&>
, pointer_is<instance_holder*>
, iterator_category_is<std::input_iterator_tag> > iterator;
private:
instance_holder* m_next;
};
// Each extension instance will be one of these
struct instance
{
PyObject_HEAD
instance_holder* objects;
};
// Given a type_id, find the instance data which corresponds to it, or
// return 0 in case no such type is held.
BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t);
template <class T>
T* find_instance(PyObject* p, T* = 0)
{
return static_cast<T*>(find_instance_impl(p, converter::type_id<T>()));
}
BOOST_PYTHON_DECL ref class_metatype();
BOOST_PYTHON_DECL ref class_type();
//
// implementation
//
inline instance_holder* instance_holder::next() const
{
return m_next;
}
}}} // namespace boost::python::objects
#endif // CLASS_DWA20011214_HPP

View File

@@ -0,0 +1,102 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_CONVERTERS_DWA2002119_HPP
# define CLASS_CONVERTERS_DWA2002119_HPP
# include <boost/python/converter/class.hpp>
# include <boost/python/object/class_wrapper.hpp>
# include <boost/mpl/for_each.hpp>
# include <boost/python/reference.hpp>
namespace boost { namespace python { namespace objects {
// Instantiating this class brings into existence all converters
// associated with a class Bases is expected to be an mpl sequence of
// base types.
template <class Derived, class Bases>
struct class_converters
{
public: // member functions
// Constructor takes the python class object associated with T
class_converters(ref const& python_class);
private: // data members
converter::class_from_python_converter<Derived> m_unwrapper;
class_wrapper<Derived> m_wrapper;
};
//
// Implementation details
//
//////////////////////////////////////////////////////////////////////
//
// register_base_of<T> -
// A BinaryMetaFunction object which registers a single base
// class of T, and the corresponding cast(s)
//
// register_downcast/do_nothing -
// Helpers for register_base_of<> which take care of registering
// down-casts
template <class Base, class Derived>
struct register_downcast
{
static void execute()
{
register_conversion<Base, Derived>(true);
}
};
struct do_nothing
{
static void execute() { }
};
// Here's where the real work gets done:
template <class Derived>
struct register_base_of
{
// Ignored is needed because mpl::for_each is still actually
// accumulate. We're not using any state so it just sits there.
template <class Ignored, class Base>
struct apply
{
typedef void type; // 'type' needs to be defined for the same reasons
// Here's the runtime part:
static void execute()
{
// Register the Base class
register_dynamic_id<Base>();
// Register the up-cast
register_conversion<Derived,Base>(false);
// Register the down-cast, if appropriate.
mpl::select_type<
is_polymorphic<Base>::value
, register_downcast<Base,Derived>
, do_nothing
>::type::execute();
}
};
};
template <class Derived, class Bases>
class_converters<Derived,Bases>::class_converters(ref const& type_object)
: m_wrapper(type_object)
{
// register all up/downcasts here
register_dynamic_id<Derived>();
// register each base in the sequence
mpl::for_each<Bases, void, register_base_of<Derived> >::execute();
}
}}} // namespace boost::python::object
#endif // CLASS_CONVERTERS_DWA2002119_HPP

View File

@@ -0,0 +1,26 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_OBJECT_DWA200222_HPP
# define CLASS_OBJECT_DWA200222_HPP
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/registry.hpp>
namespace boost { namespace python { namespace objects {
template <class T>
struct class_object
{
static PyTypeObject*& reference;
};
template <class T>
PyTypeObject*& class_object<T>::reference = converter::registry::class_object(
converter::undecorated_type_id<T>());
}}} // namespace boost::python::objects
#endif // CLASS_OBJECT_DWA200222_HPP

View File

@@ -0,0 +1,61 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_WRAPPER_DWA20011221_HPP
# define CLASS_WRAPPER_DWA20011221_HPP
# include <boost/python/object/value_holder.hpp>
# include <boost/python/reference.hpp>
# include <boost/python/to_python_converter.hpp>
namespace boost { namespace python { namespace objects {
template <class T>
struct class_wrapper
: to_python_converter<T, class_wrapper<T> >
{
class_wrapper(ref const& type_)
: m_class_object_keeper(type_)
{
assert(type_->ob_type == (PyTypeObject*)class_metatype().get());
m_class_object = (PyTypeObject*)type_.get();
}
static PyObject* convert(T const& x)
{
// Don't call the type directly to do the construction, since
// that would require the registration of an appropriate
// __init__ function.
PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0);
if (raw_result == 0)
return 0;
// Everything's OK; Bypass NULL checks but guard against
// exceptions.
ref result(raw_result, ref::allow_null());
// Build a value_holder to contain the object using the copy
// constructor
value_holder<T>* p = new value_holder<T>(raw_result, cref(x));
// Install it in the instance
p->install(raw_result);
// Return the new result
return result.release();
}
private:
ref m_class_object_keeper;
static PyTypeObject* m_class_object;
};
template <class T>
PyTypeObject* class_wrapper<T>::m_class_object;
}}} // namespace boost::python::objects
#endif // CLASS_WRAPPER_DWA20011221_HPP

View File

@@ -0,0 +1,24 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CONSTRUCT_DWA20011215_HPP
# define CONSTRUCT_DWA20011215_HPP
namespace boost { namespace python { namespace objects {
template <class T, class ArgList>
struct construct
{
static
template <class
void operator()(PyObject* args, PyObject* keywords)
{
}
};
}}} // namespace boost::python::objects
#endif // CONSTRUCT_DWA20011215_HPP

View File

@@ -0,0 +1,37 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FORWARD_DWA20011215_HPP
# define FORWARD_DWA20011215_HPP
# include <boost/mpl/select_type.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
namespace boost { namespace python { namespace objects {
// A little metaprogram which selects the type to pass through an
// intermediate forwarding function when the destination argument type
// is T.
template <class T>
struct forward
{
BOOST_STATIC_CONSTANT(
bool, by_value = (is_scalar<T>::value | is_reference<T>::value)
);
typedef typename mpl::select_type<
by_value
, T
, reference_wrapper<
typename add_const<T>::type
>
>::type type;
};
}}} // namespace boost::python::objects
#endif // FORWARD_DWA20011215_HPP

View File

@@ -0,0 +1,51 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FUNCTION_DWA20011214_HPP
# define FUNCTION_DWA20011214_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/reference.hpp>
# include <boost/function.hpp>
namespace boost { namespace python { namespace objects {
// We use boost::function to avoid generating lots of virtual tables
typedef boost::function2<PyObject*, PyObject*, PyObject*> py_function;
struct BOOST_PYTHON_DECL function : PyObject
{
function(py_function, unsigned min_args, unsigned max_args = 0);
~function();
PyObject* call(PyObject*, PyObject*) const;
// Add an attributeto the name_space with the given name. If it is
// a function object (this class), and an existing function is
// already there, add it as an overload.
static void add_to_namespace(
ref const& name_space, char const* name, ref const& attribute);
private: // helper functions
void argument_error(PyObject* args, PyObject* keywords) const;
void add_overload(function*);
private: // data members
py_function m_fn;
unsigned m_min_args;
unsigned m_max_args;
function* m_overloads;
};
extern BOOST_PYTHON_DECL PyTypeObject function_type;
//
// implementations
//
}}} // namespace boost::python::objects
#endif // FUNCTION_DWA20011214_HPP

View File

@@ -0,0 +1,165 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef INHERITANCE_DWA200216_HPP
# define INHERITANCE_DWA200216_HPP
# include <boost/python/converter/type_id.hpp>
# include <boost/shared_ptr.hpp>
namespace boost { namespace python { namespace objects {
typedef converter::undecorated_type_id_t class_id;
using converter::undecorated_type_id;
// Types used to get address and id of most derived type
typedef std::pair<void*,class_id> dynamic_id_t;
typedef dynamic_id_t (*dynamic_id_function)(void*);
BOOST_PYTHON_DECL void register_dynamic_id_aux(
class_id static_id, dynamic_id_function get_dynamic_id);
BOOST_PYTHON_DECL void add_cast(
class_id src_t, class_id dst_t, void* (*cast)(void*), bool polymorphic);
BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst);
BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst);
// is_polymorphic test from John Maddock
template <class T>
struct is_polymorphic
{
struct d1 : public T
{
d1();
char padding[256];
};
struct d2 : public T
{
d2();
virtual ~d2();
virtual void foo();
char padding[256];
};
BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1)));
};
//
// a generator with an execute() function which, given a source type
// and a pointer to an object of that type, returns its most-derived
// /reachable/ type identifier and object pointer.
//
// first, the case where T has virtual functions
template <class T>
struct polymorphic_id_generator
{
static dynamic_id_t execute(void* p_)
{
T* p = static_cast<T*>(p_);
return std::make_pair(dynamic_cast<void*>(p), class_id(typeid(*p)));
}
};
// now, the non-polymorphic case.
template <class T>
struct non_polymorphic_id_generator
{
static dynamic_id_t execute(void* p_)
{
return std::make_pair(p_, converter::undecorated_type_id<T>());
}
};
// Now the generalized selector
template <class T>
struct dynamic_id_generator
{
typedef typename mpl::select_type<
is_polymorphic<T>::value
, polymorphic_id_generator<T>
, non_polymorphic_id_generator<T> >::type type;
};
// Register the dynamic id function for T with the type-conversion
// system.
template <class T>
void register_dynamic_id(T* = 0)
{
typedef typename dynamic_id_generator<T>::type generator;
register_dynamic_id_aux(
converter::undecorated_type_id<T>(), &generator::execute);
}
//
// a generator with an execute() function which, given a void*
// pointing to an object of type Source will attempt to convert it to
// an object of type Target.
//
template <class Source, class Target>
struct dynamic_cast_generator
{
static void* execute(void* source)
{
return dynamic_cast<Target*>(
static_cast<Source*>(source));
}
};
template <class Source, class Target>
struct implicit_cast_generator
{
static void* execute(void* source)
{
Target* result = static_cast<Source*>(source);
return result;
}
};
template <class Source, class Target>
struct cast_generator
{
// CWPro7 will return false sometimes, but that's OK since we can
// always cast up with dynamic_cast<>
BOOST_STATIC_CONSTANT(
bool, is_upcast = (
is_base_and_derived<Target,Source>::value
));
typedef typename mpl::select_type<
is_upcast
# if defined(__MWERKS__) && __MWERKS__ <= 0x2406
// grab a few more implicit_cast cases for CodeWarrior
|| !is_polymorphic<Source>::value
|| !is_polymorphic<Target>::value
# endif
, implicit_cast_generator<Source,Target>
, dynamic_cast_generator<Source,Target>
>::type type;
};
template <class Source, class Target>
inline void register_conversion(
// We need this parameter because CWPro7 can't determine
// which is the base reliably.
bool is_downcast = !cast_generator<Source,Target>::is_upcast
// These parameters shouldn't be used, they're an MSVC bug workaround
, Source* = 0, Target* = 0)
{
typedef typename cast_generator<Source,Target>::type generator;
add_cast(converter::undecorated_type_id<Source>()
, converter::undecorated_type_id<Target>()
, &generator::execute
, is_downcast);
}
}}} // namespace boost::python::object
#endif // INHERITANCE_DWA200216_HPP

View File

@@ -0,0 +1,17 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef LIFE_SUPPORT_DWA200222_HPP
# define LIFE_SUPPORT_DWA200222_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace objects {
BOOST_PYTHON_DECL PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient);
}}} // namespace boost::python::object
#endif // LIFE_SUPPORT_DWA200222_HPP

View File

@@ -0,0 +1,176 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MAKE_HOLDER_DWA20011215_HPP
# define MAKE_HOLDER_DWA20011215_HPP
# include <boost/mpl/at.hpp>
# include <boost/python/object/forward.hpp>
# include <boost/python/object/class.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/eval.hpp>
namespace boost { namespace python { namespace objects {
template <int nargs> struct make_holder;
template <>
struct make_holder<0>
{
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
static void execute(
PyObject* p)
{
(new holder(p))->install(p);
}
};
};
template <>
struct make_holder<1>
{
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
static void execute(
PyObject* p
, t0 a0)
{
(new holder(p, f0(a0)))->install(p);
}
};
};
template <>
struct make_holder<2>
{
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
typedef typename forward<t1>::type f1;
static void execute(
PyObject* p, t0 a0, t1 a1)
{
(new holder(p, f0(a0), f1(a1)))->install(p);
}
};
};
template <>
struct make_holder<3>
{
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
typedef typename forward<t1>::type f1;
typedef typename mpl::at<2,ArgList>::type t2;
typedef typename forward<t2>::type f2;
static void execute(
PyObject* p, t0 a0, t1 a1, t2 a2)
{
(new holder(p, f0(a0), f1(a1), f2(a2)))->install(p);
}
};
};
template <>
struct make_holder<4>
{
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
typedef typename forward<t1>::type f1;
typedef typename mpl::at<2,ArgList>::type t2;
typedef typename forward<t2>::type f2;
typedef typename mpl::at<3,ArgList>::type t3;
typedef typename forward<t3>::type f3;
static void execute(
PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3)
{
(new holder(p, f0(a0), f1(a1), f2(a2), f3(a3)))->install(p);
}
};
};
template <>
struct make_holder<5>
{
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
typedef typename forward<t1>::type f1;
typedef typename mpl::at<2,ArgList>::type t2;
typedef typename forward<t2>::type f2;
typedef typename mpl::at<3,ArgList>::type t3;
typedef typename forward<t3>::type f3;
typedef typename mpl::at<4,ArgList>::type t4;
typedef typename forward<t4>::type f4;
static void execute(
PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4)
{
(new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4)))->install(p);
}
};
};
template <>
struct make_holder<6>
{
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
typedef typename forward<t1>::type f1;
typedef typename mpl::at<2,ArgList>::type t2;
typedef typename forward<t2>::type f2;
typedef typename mpl::at<3,ArgList>::type t3;
typedef typename forward<t3>::type f3;
typedef typename mpl::at<4,ArgList>::type t4;
typedef typename forward<t4>::type f4;
typedef typename mpl::at<5,ArgList>::type t5;
typedef typename forward<t5>::type f5;
static void execute(
PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)
{
(new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4), f5(a5)))->install(p);
}
};
};
}}} // namespace boost::python::objects
#endif // MAKE_HOLDER_DWA20011215_HPP

View File

@@ -0,0 +1,201 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef POINTER_HOLDER_DWA20011215_HPP
# define POINTER_HOLDER_DWA20011215_HPP
# include <boost/python/object/class.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/object/inheritance.hpp>
# include <boost/python/detail/eval.hpp>
# include <boost/ref.hpp>
# include <boost/type.hpp>
namespace boost { namespace python { namespace objects {
template <class Pointer, class Value>
struct pointer_holder : instance_holder
{
pointer_holder(Pointer);
// Forward construction to the held object
pointer_holder(PyObject*)
: m_p(new Value) {}
template <class A1>
pointer_holder(PyObject*, A1 a1)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
))
{}
template <class A1, class A2>
pointer_holder(PyObject*, A1 a1, A2 a2)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
))
{}
template <class A1, class A2, class A3>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
))
{}
template <class A1, class A2, class A3, class A4>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
))
{}
template <class A1, class A2, class A3, class A4, class A5>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
))
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
))
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
))
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
: m_p(new Value(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
, (typename unwrap_reference<A10>::type&)(a10)
))
{}
private: // required holder implementation
void* holds(converter::type_id_t);
private: // data members
Pointer m_p;
};
}}}
// back to namespace boost for this forward declaration
namespace boost
{
template <class T> class shared_ptr;
}
namespace boost { namespace python { namespace objects {
struct shared_ptr_generator
{
template <class T>
struct apply
{
typedef boost::shared_ptr<T> type;
};
};
// A generator metafunction which can be passed to make_holder
// PointerGenerator should be another generator metafunction which
// makes the appropriate (smart) pointer type to hold the argument to
// pointer_holder_generator.
template <class PointerGenerator>
struct pointer_holder_generator
{
template <class Held>
struct apply
{
typedef typename detail::eval<PointerGenerator,Held>::type pointer;
typedef pointer_holder<pointer, Held> type;
};
};
template <class Pointer, class Value>
pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
: m_p(p)
{
}
template <class Pointer, class Value>
void* pointer_holder<Pointer, Value>::holds(converter::type_id_t dst_t)
{
if (dst_t == converter::type_id<Pointer>())
return &this->m_p;
converter::type_id_t src_t = converter::type_id<Value>();
return src_t == dst_t ? &*this->m_p
: find_dynamic_type(&*this->m_p, src_t, dst_t);
}
}}} // namespace boost::python::objects
#endif // POINTER_HOLDER_DWA20011215_HPP

View File

@@ -0,0 +1,163 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef VALUE_HOLDER_DWA20011215_HPP
# define VALUE_HOLDER_DWA20011215_HPP
# include <boost/python/object/class.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/object/inheritance.hpp>
# include <boost/ref.hpp>
namespace boost { namespace python { namespace objects {
template <class Held>
struct value_holder : instance_holder
{
// Forward construction to the held object
value_holder(PyObject*)
: m_held() {}
template <class A1>
value_holder(PyObject*, A1 a1)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
)
{}
template <class A1, class A2>
value_holder(PyObject*, A1 a1, A2 a2)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
)
{}
template <class A1, class A2, class A3>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
)
{}
template <class A1, class A2, class A3, class A4>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
)
{}
template <class A1, class A2, class A3, class A4, class A5>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
)
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
)
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
)
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
: m_held(
(typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
, (typename unwrap_reference<A10>::type&)(a10)
)
{}
private: // required holder implementation
void* holds(converter::type_id_t);
private: // data members
Held m_held;
};
// A generator metafunction which can be passed to make_holder
struct value_holder_generator
{
template <class Held>
struct apply
{
typedef value_holder<Held> type;
};
};
template <class Held>
void* value_holder<Held>::holds(converter::type_id_t dst_t)
{
converter::type_id_t src_t = converter::type_id<Held>();
return src_t == dst_t ? &m_held
: find_static_type(&m_held, src_t, dst_t);
}
}}} // namespace boost::python::objects
#endif // VALUE_HOLDER_DWA20011215_HPP

View File

@@ -17,7 +17,7 @@
namespace boost { namespace python {
class object
class BOOST_PYTHON_DECL object
{
public:
explicit object(ref p);
@@ -32,15 +32,36 @@ class object
ref m_p;
};
class tuple : public object
class tuple;
class BOOST_PYTHON_DECL tuple_base : public object
{
public:
explicit tuple(std::size_t n = 0);
explicit tuple(ref p);
explicit tuple_base(std::size_t n = 0);
explicit tuple_base(ref p);
static PyTypeObject* type_obj();
static bool accepts(ref p);
std::size_t size() const;
ref operator[](std::size_t pos) const;
void set_item(std::size_t pos, const ref& rhs);
tuple slice(int low, int high) const;
friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&);
friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&);
};
class tuple : public tuple_base
{
public:
explicit tuple(std::size_t n = 0) : tuple_base(n) {}
explicit tuple(ref p) : tuple_base(p) {}
template <class First, class Second>
tuple(const std::pair<First,Second>& x)
: object(ref(PyTuple_New(2)))
: tuple_base(ref(PyTuple_New(2)))
{
set_item(0, x.first);
set_item(1, x.second);
@@ -48,7 +69,7 @@ class tuple : public object
template <class First, class Second>
tuple(const First& first, const Second& second)
: object(ref(PyTuple_New(2)))
: tuple_base(ref(PyTuple_New(2)))
{
set_item(0, first);
set_item(1, second);
@@ -56,7 +77,7 @@ class tuple : public object
template <class First, class Second, class Third>
tuple(const First& first, const Second& second, const Third& third)
: object(ref(PyTuple_New(3)))
: tuple_base(ref(PyTuple_New(3)))
{
set_item(0, first);
set_item(1, second);
@@ -65,7 +86,7 @@ class tuple : public object
template <class First, class Second, class Third, class Fourth>
tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth)
: object(ref(PyTuple_New(4)))
: tuple_base(ref(PyTuple_New(4)))
{
set_item(0, first);
set_item(1, second);
@@ -73,32 +94,31 @@ class tuple : public object
set_item(3, fourth);
}
static PyTypeObject* type_obj();
static bool accepts(ref p);
std::size_t size() const;
ref operator[](std::size_t pos) const;
template <class T>
void set_item(std::size_t pos, const T& rhs)
{
this->set_item(pos, make_ref(rhs));
}
void set_item(std::size_t pos, const ref& rhs);
tuple slice(int low, int high) const;
friend tuple operator+(const tuple&, const tuple&);
tuple& operator+=(const tuple& rhs);
void set_item(std::size_t pos, const ref& rhs)
{
tuple_base::set_item(pos, rhs);
}
};
class list : public object
class list;
struct BOOST_PYTHON_DECL list_proxy;
struct BOOST_PYTHON_DECL list_slice_proxy;
class BOOST_PYTHON_DECL list_base : public object
{
struct proxy;
struct slice_proxy;
protected:
typedef list_proxy proxy;
typedef list_slice_proxy slice_proxy;
public:
explicit list(ref p);
explicit list(std::size_t sz = 0);
explicit list_base(ref p);
explicit list_base(std::size_t sz = 0);
static PyTypeObject* type_obj();
static bool accepts(ref p);
std::size_t size() const;
@@ -106,26 +126,14 @@ class list : public object
proxy operator[](std::size_t pos);
ref get_item(std::size_t pos) const;
template <class T>
void set_item(std::size_t pos, const T& x)
{ this->set_item(pos, make_ref(x)); }
void set_item(std::size_t pos, const ref& );
// void set_item(std::size_t pos, const object& );
template <class T>
void insert(std::size_t index, const T& x)
{ this->insert(index, make_ref(x)); }
void insert(std::size_t index, const ref& item);
template <class T>
void push_back(const T& item)
{ this->push_back(make_ref(item)); }
void push_back(const ref& item);
template <class T>
void append(const T& item)
{ this->append(make_ref(item)); }
void append(const ref& item);
list slice(int low, int high) const;
@@ -135,7 +143,31 @@ class list : public object
tuple as_tuple() const;
};
class string
class list : public list_base
{
public:
explicit list(ref p) : list_base(p) {}
explicit list(std::size_t sz = 0) : list_base(sz) {}
template <class T>
void set_item(std::size_t pos, const T& x)
{ this->set_item(pos, make_ref(x)); }
template <class T>
void insert(std::size_t index, const T& x)
{ this->insert(index, make_ref(x)); }
template <class T>
void push_back(const T& item)
{ this->push_back(make_ref(item)); }
template <class T>
void append(const T& item)
{ this->append(make_ref(item)); }
void set_item(std::size_t pos, const ref& x) { list_base::set_item(pos, x); }
void insert(std::size_t index, const ref& item) { list_base::insert(index, item); }
void push_back(const ref& item) { list_base::push_back(item); }
void append(const ref& item) { list_base::append(item); }
};
class BOOST_PYTHON_DECL string
: public object, public boost::multipliable2<string, unsigned int>
{
public:
@@ -175,48 +207,31 @@ class string
friend string operator%(const string& format, const tuple& args);
};
class dictionary : public object
class dictionary;
struct BOOST_PYTHON_DECL dictionary_proxy;
class BOOST_PYTHON_DECL dictionary_base : public object
{
private:
struct proxy;
protected:
typedef dictionary_proxy proxy;
public:
explicit dictionary(ref p);
dictionary();
explicit dictionary_base(ref p);
dictionary_base();
void clear();
static PyTypeObject* type_obj();
static bool accepts(ref p);
public:
template <class Key>
proxy operator[](const Key& key)
{ return this->operator[](make_ref(key)); }
proxy operator[](ref key);
template <class Key>
ref operator[](const Key& key) const
{ return this->operator[](make_ref(key)); }
ref operator[](ref key) const;
template <class Key>
ref get_item(const Key& key) const
{ return this->get_item(make_ref(key)); }
ref get_item(const ref& key) const;
template <class Key, class Default>
ref get_item(const Key& key, const Default& default_) const
{ return this->get_item(make_ref(key), make_ref(default_)); }
ref get_item(const ref& key, const ref& default_) const;
template <class Key, class Value>
void set_item(const Key& key, const Value& value)
{ this->set_item(make_ref(key), make_ref(value)); }
void set_item(const ref& key, const ref& value);
template <class Key>
void erase(const Key& key)
{ this->erase(make_ref(key)); }
void erase(ref key);
// proxy operator[](const object& key);
@@ -235,7 +250,7 @@ class dictionary : public object
// TODO: iterator support
};
struct dictionary::proxy
struct BOOST_PYTHON_DECL dictionary_proxy
{
template <class T>
const ref& operator=(const T& rhs)
@@ -244,19 +259,63 @@ struct dictionary::proxy
operator ref() const;
private:
friend class dictionary;
proxy(const ref& dict, const ref& key);
friend class dictionary_base;
dictionary_proxy(const ref& dict, const ref& key);
// This is needed to work around the very strange MSVC error report that the
// return type of the built-in operator= differs from that of the ones
// defined above. Couldn't hurt to make these un-assignable anyway, though.
const ref& operator=(const proxy&); // Not actually implemented
const ref& operator=(const dictionary_proxy&); // Not actually implemented
private:
ref m_dict;
ref m_key;
};
struct list::proxy
class dictionary : public dictionary_base
{
typedef dictionary_proxy proxy;
public:
explicit dictionary(ref p) : dictionary_base(p) {}
dictionary() : dictionary_base() {}
template <class Key>
proxy operator[](const Key& key)
{ return this->operator[](make_ref(key)); }
proxy operator[](ref key)
{ return dictionary_base::operator[](key); }
template <class Key>
ref operator[](const Key& key) const
{ return this->operator[](make_ref(key)); }
ref operator[](ref key) const
{ return dictionary_base::operator[](key); }
template <class Key>
ref get_item(const Key& key) const
{ return this->get_item(make_ref(key)); }
ref get_item(const ref& key) const
{ return dictionary_base::get_item(key); }
template <class Key, class Default>
ref get_item(const Key& key, const Default& default_) const
{ return this->get_item(make_ref(key), make_ref(default_)); }
ref get_item(const ref& key, const ref& default_) const
{ return dictionary_base::get_item(key, default_); }
template <class Key, class Value>
void set_item(const Key& key, const Value& value)
{ this->set_item(make_ref(key), make_ref(value)); }
void set_item(const ref& key, const ref& value)
{ dictionary_base::set_item(key, value); }
template <class Key>
void erase(const Key& key)
{ this->erase(make_ref(key)); }
void erase(ref key)
{ dictionary_base::erase(key); }
};
struct BOOST_PYTHON_DECL list_proxy
{
template <class T>
const ref& operator=(const T& rhs)
@@ -266,19 +325,19 @@ struct list::proxy
operator ref() const;
private:
friend class list;
proxy(const ref& list, std::size_t index);
friend class list_base;
list_proxy(const ref& list, std::size_t index);
// This is needed to work around the very strange MSVC error report that the
// return type of the built-in operator= differs from that of the ones
// defined above. Couldn't hurt to make these un-assignable anyway, though.
const ref& operator=(const proxy&); // Not actually implemented
const ref& operator=(const list_proxy&); // Not actually implemented
private:
list m_list;
std::size_t m_index;
};
struct list::slice_proxy
struct BOOST_PYTHON_DECL list_slice_proxy
{
const list& operator=(const list& rhs);
operator ref() const;
@@ -286,8 +345,8 @@ struct list::slice_proxy
std::size_t size() const;
ref operator[](std::size_t pos) const;
private:
friend class list;
slice_proxy(const ref& list, int low, int high);
friend class list_base;
list_slice_proxy(const ref& list, int low, int high);
private:
ref m_list;
int m_low, m_high;
@@ -295,34 +354,36 @@ struct list::slice_proxy
}} // namespace boost::python
# ifndef BOOST_PYTHON_V2
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
PyObject* to_python(const boost::python::tuple&);
boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple>);
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple&);
BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple>);
inline boost::python::tuple from_python(PyObject* p, boost::python::type<const boost::python::tuple&>)
{
return from_python(p, boost::python::type<boost::python::tuple>());
}
PyObject* to_python(const boost::python::list&);
boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list>);
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list&);
BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list>);
inline boost::python::list from_python(PyObject* p, boost::python::type<const boost::python::list&>)
{
return from_python(p, boost::python::type<boost::python::list>());
}
PyObject* to_python(const boost::python::string&);
boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string>);
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string&);
BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string>);
inline boost::python::string from_python(PyObject* p, boost::python::type<const boost::python::string&>)
{
return from_python(p, boost::python::type<boost::python::string>());
}
PyObject* to_python(const boost::python::dictionary&);
boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary>);
BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary&);
BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary>);
inline boost::python::dictionary from_python(PyObject* p, boost::python::type<const boost::python::dictionary&>)
{
@@ -330,5 +391,5 @@ inline boost::python::dictionary from_python(PyObject* p, boost::python::type<co
}
BOOST_PYTHON_END_CONVERSION_NAMESPACE
# endif
#endif // OBJECTS_DWA051100_H_

View File

@@ -31,7 +31,7 @@
namespace boost { namespace python {
tuple standard_coerce(ref l, ref r);
BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r);
namespace detail {

View File

@@ -14,9 +14,13 @@
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/cast.hpp>
# include <cassert>
# include <cstddef>
# include <boost/python/detail/signatures.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/conversions.hpp>
# include <boost/python/detail/cast.hpp>
# ifndef BOOST_PYTHON_V2
# include <boost/python/conversions.hpp>
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
@@ -35,14 +39,19 @@ struct py_ptr_conversions : Base
};
BOOST_PYTHON_END_CONVERSION_NAMESPACE
# endif
namespace boost { namespace python {
# ifndef BOOST_PYTHON_V2
BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions);
# endif
template <class T>
class reference
# ifndef BOOST_PYTHON_V2
: public py_ptr_conversions<reference<T>, T>
# endif
{
public:
typedef T value_type;
@@ -50,18 +59,10 @@ public:
reference(const reference& rhs)
: m_p(rhs.m_p)
{
Py_XINCREF(object());
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XINCREF(m_p);
}
#if !defined(BOOST_MSVC6_OR_EARLIER)
template <class T2>
reference(const reference<T2>& rhs)
: m_p(rhs.object())
{
Py_XINCREF(object());
}
#endif
reference() : m_p(0) {}
// These are two ways of spelling the same thing, that we need to increment
@@ -72,85 +73,140 @@ public:
template <class T2>
explicit reference(T2* x)
: m_p(expect_non_null(x)) {}
: m_p(expect_non_null(x))
{
assert(m_p->ob_refcnt > 0);
}
template <class T2>
reference(T2* x, increment_count_t)
: m_p(expect_non_null(x)) { Py_INCREF(object()); }
: m_p(expect_non_null(x))
{
assert(m_p->ob_refcnt > 0);
Py_INCREF(m_p);
}
template <class T2>
reference(T2* x, allow_null)
: m_p(x) {}
: m_p(x)
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
}
template <class T2>
reference(T2* x, allow_null, increment_count_t)
: m_p(x) { Py_XINCREF(object()); }
: m_p(x)
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XINCREF(m_p);
}
template <class T2>
reference(T2* x, increment_count_t, allow_null)
: m_p(x) { Py_XINCREF(object()); }
#if !defined(BOOST_MSVC6_OR_EARLIER)
template <class T2>
reference& operator=(const reference<T2>& rhs)
: m_p(x)
{
Py_XDECREF(object());
m_p = rhs.m_p;
Py_XINCREF(object());
return *this;
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XINCREF(m_p);
}
#endif
reference& operator=(const reference& rhs)
{
assert(rhs.m_p == 0 || rhs.m_p->ob_refcnt > 0);
Py_XINCREF(static_cast<PyObject*>(rhs.m_p));
Py_XDECREF(object());
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XDECREF(m_p);
m_p = rhs.m_p;
return *this;
}
~reference()
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XDECREF(m_p);
}
T& operator*() const { return *m_p; }
T& operator*() const
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
return *m_p;
}
// MSVC doesn't like boost::dereferencable unless T has a default
// constructor, so operator-> must be defined by hand :(
T* operator->() const { return &**this; }
T* operator->() const
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
return &**this;
}
T* get() const { return m_p; }
T* get() const
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
return m_p;
}
T* release()
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
T* p = m_p;
m_p = 0;
return p;
}
void reset()
{ Py_XDECREF(m_p); m_p = 0; }
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XDECREF(m_p);
m_p = 0;
}
template <class T2>
void reset(T2* x)
{ Py_XDECREF(m_p); m_p = expect_non_null(x);}
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XDECREF(m_p);
m_p = expect_non_null(x);
assert(m_p == 0 || m_p->ob_refcnt > 0);
}
template <class T2>
void reset(T2* x, increment_count_t)
{ Py_XDECREF(m_p); m_p = expect_non_null(x); Py_INCREF(object()); }
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XINCREF(x);
Py_XDECREF(m_p);
m_p = expect_non_null(x);
assert(m_p->ob_refcnt > 0);
}
template <class T2>
void reset(T2* x, allow_null)
{ Py_XDECREF(m_p); m_p = x;}
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XDECREF(m_p);
m_p = x;
assert(m_p == 0 || m_p->ob_refcnt > 0);
}
template <class T2>
void reset(T2* x, allow_null, increment_count_t)
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XINCREF(x);
Py_XDECREF(m_p);
m_p = x;
assert(m_p == 0 || m_p->ob_refcnt > 0);
}
template <class T2>
void reset(T2* x, increment_count_t, allow_null)
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
{
assert(m_p == 0 || m_p->ob_refcnt > 0);
Py_XINCREF(x);
Py_XDECREF(m_p);
m_p = x;
assert(m_p == 0 || m_p->ob_refcnt > 0);
}
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
private:
@@ -158,18 +214,27 @@ private:
#endif
inline PyObject* object() const
{ return as_object(m_p); }
{
#ifdef BOOST_PYTHON_V2
return (PyObject*)(
(char*)&m_p->ob_type - offsetof(PyObject,ob_type));
#else
return as_object(m_p);
#endif
}
T* m_p;
};
typedef reference<PyObject> ref;
#ifndef BOOST_PYTHON_V2
template <class T>
ref make_ref(const T& x)
{
return ref(to_python(x));
}
#endif
}} // namespace boost::python

View File

@@ -0,0 +1,45 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REFERENCE_EXISTING_OBJECT_DWA200222_HPP
# define REFERENCE_EXISTING_OBJECT_DWA200222_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/to_python_indirect.hpp>
# include <boost/type_traits/composite_traits.hpp>
namespace boost { namespace python {
namespace detail
{
template <class R>
struct reference_existing_object_requires_a_pointer_or_reference_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
template <class T> struct to_python_value;
struct reference_existing_object
{
template <class T>
struct apply
{
BOOST_STATIC_CONSTANT(
bool, ok = is_pointer<T>::value || is_reference<T>::value);
typedef typename mpl::select_type<
ok
, to_python_indirect<T, detail::make_reference_holder>
, detail::reference_existing_object_requires_a_pointer_or_reference_return_type<T>
>::type type;
};
};
}} // namespace boost::python
#endif // REFERENCE_EXISTING_OBJECT_DWA200222_HPP

View File

@@ -0,0 +1,62 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REFERENCE_FROM_PYTHON_DWA2002130_HPP
# define REFERENCE_FROM_PYTHON_DWA2002130_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/python/type_from_python.hpp>
namespace boost { namespace python {
// Utility which produces a member extractor function on platforms
// other than VC6.
template <class Class, class Member, Member (Class::*mp)>
struct get_member
{
static Member& execute(Class* c)
{
return c->*mp;
}
};
template <
PyTypeObject const* python_type
, class Value
, class PythonObject
, class Extract
>
struct reference_from_python
{
typedef type_from_python<python_type> convertible_t;
reference_from_python()
: m_mutable_converter(
&convertible_t::convertible, convert_mutable)
, m_const_converter(
&convertible_t::convertible, convert_const)
{}
static Value& convert_mutable(PyObject* op, converter::from_python_data&)
{
return Extract::execute(*(PythonObject*)op);
}
static Value const& convert_const(PyObject* op, converter::from_python_data&)
{
return Extract::execute(*(PythonObject*)op);
}
private:
typedef converter::from_python_converter<Value&> mutable_converter;
typedef converter::from_python_converter<Value const&> const_converter;
mutable_converter m_mutable_converter;
const_converter m_const_converter;
};
}} // namespace boost::python
#endif // REFERENCE_FROM_PYTHON_DWA2002130_HPP

View File

@@ -0,0 +1,49 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef RETURN_INTERNAL_REFERENCE_DWA2002131_HPP
# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP
# include <boost/python/default_call_policies.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/to_python_indirect.hpp>
# include <boost/python/with_custodian_and_ward.hpp>
namespace boost { namespace python {
namespace detail
{
template <class T>
struct return_internal_reference_requires_a_pointer_or_reference_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
struct internal_reference_to_python_generator
{
template <class T>
struct apply
{
typedef typename mpl::select_type<
is_object<T>::value
, detail::return_internal_reference_requires_a_pointer_or_reference_return_type<T>
, to_python_indirect<T, detail::make_reference_holder>
>::type type;
};
};
template <std::size_t owner_arg = 1, class Base = default_call_policies>
struct return_internal_reference
: with_custodian_and_ward_postcall<0, owner_arg, Base>
{
typedef reference_existing_object result_converter;
};
}} // namespace boost::python
#endif // RETURN_INTERNAL_REFERENCE_DWA2002131_HPP

View File

@@ -0,0 +1,20 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef RETURN_VALUE_POLICY_DWA2002131_HPP
# define RETURN_VALUE_POLICY_DWA2002131_HPP
# include <boost/python/default_call_policies.hpp>
namespace boost { namespace python {
template <class Handler, class Base = default_call_policies>
struct return_value_policy : Base
{
typedef Handler result_converter;
};
}} // namespace boost::python
#endif // RETURN_VALUE_POLICY_DWA2002131_HPP

View File

@@ -0,0 +1,39 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TO_PYTHON_CONVERTER_DWA200221_HPP
# define TO_PYTHON_CONVERTER_DWA200221_HPP
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/to_python_function.hpp>
# include <boost/python/converter/type_id.hpp>
namespace boost { namespace python {
template <class T, class Derived>
struct to_python_converter
{
to_python_converter();
};
//
// implementation
//
template <class T, class Derived>
to_python_converter<T,Derived>::to_python_converter()
{
typedef converter::as_to_python_value_function<
T, Derived
> normalized;
converter::registry::insert(
&normalized::convert
, converter::undecorated_type_id<T>());
}
}} // namespace boost::python
#endif // TO_PYTHON_CONVERTER_DWA200221_HPP

View File

@@ -0,0 +1,102 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TO_PYTHON_INDIRECT_DWA200221_HPP
# define TO_PYTHON_INDIRECT_DWA200221_HPP
# include <boost/type_traits/object_traits.hpp>
# include <boost/python/object/pointer_holder.hpp>
# include <boost/python/object/class_object.hpp>
# include <boost/python/detail/unwind_type.hpp>
# include <memory>
namespace boost { namespace python {
template <class T, class HolderGenerator>
struct to_python_indirect
{
static bool convertible();
PyObject* operator()(T ptr) const;
private:
static PyTypeObject* type();
};
//
// implementations
//
namespace detail
{
struct make_owning_holder
{
typedef objects::instance_holder* result_type;
template <class T>
static result_type execute(T* p)
{
return new objects::pointer_holder<std::auto_ptr<T>, T>(
std::auto_ptr<T>(p));
}
};
struct make_reference_holder
{
typedef objects::instance_holder* result_type;
template <class T>
static result_type execute(T* p)
{
return new objects::pointer_holder<T*, T>(p);
}
};
struct get_pointer_class
{
typedef PyTypeObject* result_type;
template <class T>
static result_type execute(T* p)
{
BOOST_STATIC_ASSERT(is_class<T>::value);
return python::objects::class_object<T>::reference;
}
};
}
template <class T, class HolderGenerator>
inline bool to_python_indirect<T,HolderGenerator>::convertible()
{
return type() != 0;
}
template <class T, class HolderGenerator>
inline PyObject* to_python_indirect<T,HolderGenerator>::operator()(T x) const
{
PyObject* raw_result = type()->tp_alloc(type(), 0);
if (raw_result == 0)
return 0;
// Everything's OK; Bypass NULL checks but guard against
// exceptions.
ref result(raw_result, ref::allow_null());
// Build a value_holder to contain the object using the copy
// constructor
objects::instance_holder* p =
detail::unwind_type<HolderGenerator>(x);
// Install it in the instance
p->install(raw_result);
// Return the new result
return result.release();
}
template <class T, class HolderGenerator>
inline PyTypeObject* to_python_indirect<T,HolderGenerator>::type()
{
return detail::unwind_type<detail::get_pointer_class,T>();
}
}} // namespace boost::python
#endif // TO_PYTHON_INDIRECT_DWA200221_HPP

View File

@@ -0,0 +1,58 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TO_PYTHON_VALUE_DWA200221_HPP
# define TO_PYTHON_VALUE_DWA200221_HPP
# include <boost/type_traits/transform_traits.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/to_python_function.hpp>
# include <boost/python/converter/builtin_converters.hpp>
namespace boost { namespace python {
template <class T>
struct to_python_value
{
typedef typename add_reference<
typename add_const<T>::type
>::type argument_type;
static bool convertible();
PyObject* operator()(argument_type) const;
private:
// Note that this is a pointer to a function pointer
static converter::to_python_value_function const* fconvert;
};
template <class T>
converter::to_python_value_function const*
to_python_value<T>::fconvert
= &converter::registry::to_python_function(converter::undecorated_type_id<T>());
template <class T>
bool to_python_value<T>::convertible()
{
// if this assert fires, our static variable hasn't been set up yet.
assert(fconvert != 0);
return *fconvert != 0;
}
template <class T>
PyObject* to_python_value<T>::operator()(argument_type x) const
{
// This might be further optimized on platforms which dynamically
// link without specific imports/exports
converter::to_python_value_function f = *fconvert;
return f(&x);
}
}} // namespace boost::python
#endif // TO_PYTHON_VALUE_DWA200221_HPP

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TYPE_FROM_PYTHON_DWA2002130_HPP
# define TYPE_FROM_PYTHON_DWA2002130_HPP
namespace boost { namespace python {
template <PyTypeObject const* python_type>
struct type_from_python
{
static void* convertible(PyObject* op)
{
return PyObject_TypeCheck(
op, const_cast<PyTypeObject*>(python_type)) ? op : 0;
}
};
}} // namespace boost::python
#endif // TYPE_FROM_PYTHON_DWA2002130_HPP

View File

@@ -0,0 +1,73 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef VALUE_FROM_PYTHON_DWA2002130_HPP
# define VALUE_FROM_PYTHON_DWA2002130_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/static_assert.hpp>
namespace boost { namespace python {
template <typename T, class Derived>
struct value_from_python
{
typedef value_from_python<T,Derived> self;
typedef converter::from_python_check from_python_check;
value_from_python(from_python_check convertible)
: m_converter(
convertible
, &Derived::convert
// Change this to a compile-time check later to avoid
// generating destroy function
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
)
{
}
value_from_python()
: m_converter(
&Derived::convertible
, &Derived::convert
// Change this to a compile-time check later to avoid
// generating destroy function
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
)
{
}
static void* get_storage(converter::from_python_data& data)
{
return converter::get_storage<T const&>(data);
}
// Mark successful construction
static void constructed(converter::from_python_data& data)
{
data.stage1 = self::get_storage(data);
}
inline static void destroy(converter::from_python_data& data)
{
// Get the location of the storage for
void* storage = self::get_storage(data);
// Check for successful construction
if (data.stage1 == storage)
static_cast<T*>(storage)->~T();
}
private:
converter::from_python_converter<T const&> m_converter;
};
}} // namespace boost::python
#endif // VALUE_FROM_PYTHON_DWA2002130_HPP

View File

@@ -0,0 +1,80 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
# define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
# include <boost/python/default_call_policies.hpp>
# include <boost/python/object/life_support.hpp>
namespace boost { namespace python {
enum custodial_timing { pre_call, post_call };
template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
struct with_custodian_and_ward : Base
{
static bool precall(PyObject* args);
};
template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
struct with_custodian_and_ward_postcall : Base
{
static PyObject* postcall(PyObject* args, PyObject* result);
};
//
// implementations
//
template <std::size_t custodian, std::size_t ward, class Base>
bool with_custodian_and_ward<custodian,ward,Base>::precall(PyObject* args_)
{
BOOST_STATIC_ASSERT(custodian != ward);
BOOST_STATIC_ASSERT(custodian > 0);
BOOST_STATIC_ASSERT(ward > 0);
PyObject* patient = PyTuple_GetItem(args_, ward - 1);
if (patient == 0) return false;
PyObject* nurse = PyTuple_GetItem(args_, custodian - 1);
if (nurse == 0) return false;
PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient);
if (life_support == 0)
return false;
bool result = Base::precall(args_);
if (!result)
Py_XDECREF(life_support);
return result;
}
template <std::size_t custodian, std::size_t ward, class Base>
PyObject* with_custodian_and_ward_postcall<custodian,ward,Base>::postcall(PyObject* args_, PyObject* result)
{
BOOST_STATIC_ASSERT(custodian != ward);
PyObject* patient = ward > 0 ? PyTuple_GetItem(args_, ward - 1) : result;
if (patient == 0) return 0;
PyObject* nurse = custodian > 0 ? PyTuple_GetItem(args_, custodian - 1) : result;
if (nurse == 0) return 0;
result = Base::postcall(args_, result);
if (result == 0)
return 0;
if (python::objects::make_nurse_and_patient(nurse, patient) == 0)
{
Py_XDECREF(result);
return 0;
}
return result;
}
}} // namespace boost::python
#endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP

View File

@@ -645,7 +645,7 @@ PyObject* instance::divmod(PyObject* other)
PyObject* instance::power(PyObject* exponent, PyObject* modulus)
{
if (as_object(modulus->ob_type) == Py_None)
if (as_object(modulus) == Py_None)
return callback<PyObject*>::call_method(this, "__pow__", exponent);
else
return callback<PyObject*>::call_method(this, "__pow__", exponent, modulus);
@@ -999,7 +999,7 @@ namespace {
}
}
void adjust_slice_indices(PyObject* obj, int& start, int& finish)
BOOST_PYTHON_DECL void adjust_slice_indices(PyObject* obj, int& start, int& finish)
{
int length = callback<int>::call_method(obj, "__len__");

View File

@@ -16,65 +16,16 @@
#define BOOST_PYTHON_SOURCE
#include <boost/python/conversions.hpp>
#include <boost/python/detail/void_adaptor.hpp>
#include <boost/function.hpp>
#include <typeinfo>
#include <exception>
#ifndef BOOST_NO_LIMITS
# include <boost/cast.hpp>
#endif
namespace boost { namespace python {
// IMPORTANT: this function may only be called from within a catch block!
PyObject* handle_exception_impl(object_functor_base const& f)
{
try
{
return f();
}
catch(const boost::python::error_already_set&)
{
// The python error reporting has already been handled.
}
catch(const std::bad_alloc&)
{
PyErr_NoMemory();
}
catch(const std::exception& x)
{
PyErr_SetString(PyExc_RuntimeError, x.what());
}
catch(...)
{
PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
}
return 0;
}
void handle_exception(void (*f)())
{
handle_exception(
boost::python::detail::make_void_adaptor(f));
}
namespace detail {
void expect_complex(PyObject* p)
{
if (!PyComplex_Check(p))
{
PyErr_SetString(PyExc_TypeError, "expected a complex number");
throw boost::python::argument_error();
}
}
} // namespace boost::python::detail
}} // namespace boost::python
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
long from_python(PyObject* p, boost::python::type<long>)
BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type<long>)
{
// Why am I clearing the error here before trying to convert? I know there's a reason...
long result;
@@ -86,7 +37,7 @@ long from_python(PyObject* p, boost::python::type<long>)
return result;
}
double from_python(PyObject* p, boost::python::type<double>)
BOOST_PYTHON_DECL double from_python(PyObject* p, boost::python::type<double>)
{
double result;
{
@@ -151,48 +102,48 @@ PyObject* integer_to_python(T value)
return to_python(value_as_long);
}
int from_python(PyObject* p, boost::python::type<int> type)
BOOST_PYTHON_DECL int from_python(PyObject* p, boost::python::type<int> type)
{
return integer_from_python(p, type);
}
PyObject* to_python(unsigned int i)
BOOST_PYTHON_DECL PyObject* to_python(unsigned int i)
{
return integer_to_python(i);
}
unsigned int from_python(PyObject* p, boost::python::type<unsigned int> type)
BOOST_PYTHON_DECL unsigned int from_python(PyObject* p, boost::python::type<unsigned int> type)
{
return integer_from_python(p, type);
}
short from_python(PyObject* p, boost::python::type<short> type)
BOOST_PYTHON_DECL short from_python(PyObject* p, boost::python::type<short> type)
{
return integer_from_python(p, type);
}
float from_python(PyObject* p, boost::python::type<float>)
BOOST_PYTHON_DECL float from_python(PyObject* p, boost::python::type<float>)
{
return static_cast<float>(from_python(p, boost::python::type<double>()));
}
PyObject* to_python(unsigned short i)
BOOST_PYTHON_DECL PyObject* to_python(unsigned short i)
{
return integer_to_python(i);
}
unsigned short from_python(PyObject* p, boost::python::type<unsigned short> type)
BOOST_PYTHON_DECL unsigned short from_python(PyObject* p, boost::python::type<unsigned short> type)
{
return integer_from_python(p, type);
}
PyObject* to_python(char c)
BOOST_PYTHON_DECL PyObject* to_python(char c)
{
if (c == '\0') return PyString_FromString("");
return PyString_FromStringAndSize(&c, 1);
}
char from_python(PyObject* p, boost::python::type<char>)
BOOST_PYTHON_DECL char from_python(PyObject* p, boost::python::type<char>)
{
int l = -1;
if (PyString_Check(p)) l = PyString_Size(p);
@@ -204,37 +155,37 @@ char from_python(PyObject* p, boost::python::type<char>)
return PyString_AsString(p)[0];
}
PyObject* to_python(unsigned char i)
BOOST_PYTHON_DECL PyObject* to_python(unsigned char i)
{
return integer_to_python(i);
}
unsigned char from_python(PyObject* p, boost::python::type<unsigned char> type)
BOOST_PYTHON_DECL unsigned char from_python(PyObject* p, boost::python::type<unsigned char> type)
{
return integer_from_python(p, type);
}
PyObject* to_python(signed char i)
BOOST_PYTHON_DECL PyObject* to_python(signed char i)
{
return integer_to_python(i);
}
signed char from_python(PyObject* p, boost::python::type<signed char> type)
BOOST_PYTHON_DECL signed char from_python(PyObject* p, boost::python::type<signed char> type)
{
return integer_from_python(p, type);
}
PyObject* to_python(unsigned long x)
BOOST_PYTHON_DECL PyObject* to_python(unsigned long x)
{
return integer_to_python(x);
}
unsigned long from_python(PyObject* p, boost::python::type<unsigned long> type)
BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type<unsigned long> type)
{
return integer_from_python(p, type);
}
void from_python(PyObject* p, boost::python::type<void>)
BOOST_PYTHON_DECL void from_python(PyObject* p, boost::python::type<void>)
{
if (p != Py_None) {
PyErr_SetString(PyExc_TypeError, "expected argument of type None");
@@ -242,7 +193,7 @@ void from_python(PyObject* p, boost::python::type<void>)
}
}
const char* from_python(PyObject* p, boost::python::type<const char*>)
BOOST_PYTHON_DECL const char* from_python(PyObject* p, boost::python::type<const char*>)
{
const char* s = PyString_AsString(p);
if (!s)
@@ -250,12 +201,12 @@ const char* from_python(PyObject* p, boost::python::type<const char*>)
return s;
}
PyObject* to_python(const std::string& s)
BOOST_PYTHON_DECL PyObject* to_python(const std::string& s)
{
return PyString_FromStringAndSize(s.data(), s.size());
}
std::string from_python(PyObject* p, boost::python::type<std::string>)
BOOST_PYTHON_DECL std::string from_python(PyObject* p, boost::python::type<std::string>)
{
if (! PyString_Check(p)) {
PyErr_SetString(PyExc_TypeError, "expected a string");
@@ -264,7 +215,7 @@ std::string from_python(PyObject* p, boost::python::type<std::string>)
return std::string(PyString_AsString(p), PyString_Size(p));
}
bool from_python(PyObject* p, boost::python::type<bool>)
BOOST_PYTHON_DECL bool from_python(PyObject* p, boost::python::type<bool>)
{
int value = from_python(p, boost::python::type<int>());
if (value == 0)
@@ -274,12 +225,12 @@ bool from_python(PyObject* p, boost::python::type<bool>)
#ifdef BOOST_MSVC6_OR_EARLIER
// An optimizer bug prevents these from being inlined.
PyObject* to_python(double d)
BOOST_PYTHON_DECL PyObject* to_python(double d)
{
return PyFloat_FromDouble(d);
}
PyObject* to_python(float f)
BOOST_PYTHON_DECL PyObject* to_python(float f)
{
return PyFloat_FromDouble(f);
}

18
src/converter/body.cpp Normal file
View File

@@ -0,0 +1,18 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/body.hpp>
namespace boost { namespace python { namespace converter {
// default implementation is a no-op. Most handles will not hold any
// data that needs to be managed. Unwrap objects which convert
// by-value are an exception. Fortunately, the concrete body subclass
// has that knowledge.
void body::destroy_handle(handle*) const
{
}
}}} // namespace boost::python::converter

View File

@@ -0,0 +1,227 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/detail/config.hpp>
#include <boost/python/detail/wrap_python.hpp>
#include <boost/python/converter/builtin_converters.hpp>
#include <boost/python/converter/target.hpp>
#include <boost/python/value_from_python.hpp>
#include <boost/python/converter/from_python_data.hpp>
#include <boost/python/reference.hpp>
#include <boost/cast.hpp>
//#include <boost/mpl/type_list.hpp>
#include <string>
namespace boost { namespace python { namespace converter {
namespace
{
// Only an object which we know is holding a char const* can be
// converted to one
struct convertible_to_cstring
{
static unaryfunc* execute(PyObject* obj)
{
return PyString_Check(obj) ? &obj->ob_type->tp_str : 0;
}
};
struct extract_cstring
{
static char const* execute(PyObject* obj)
{
return PyString_AsString(obj);
}
};
// Any object which can be converted to a Python string can also be
// converted to a C++ string, since the latter owns its bytes.
struct convertible_to_string
{
static unaryfunc* execute(PyObject* obj)
{
return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0;
}
};
// Transform a function returning a unaryfunc* into one that returns a void*
template <class F>
struct return_void_ptr
{
static void* execute(PyObject* p) { return F::execute(p); }
};
template <
class T // The target type
, class Convertible // returns a pointer to a unaryfunc producing an object
, class TExtract // ...from which TExtract extracts T's constructor argument
>
struct tp_scalar_from_python
: from_python_converter<T>
{
private:
typedef return_void_ptr<Convertible> convertible_fn;
public:
tp_scalar_from_python()
: from_python_converter<T>(
&convertible_fn::execute
, convert)
{}
static T convert(PyObject* obj, from_python_data& data)
{
unaryfunc converter = *(unaryfunc*)data.stage1;
ref converted(converter(obj));
return TExtract::execute(converted.get());
}
};
// Extract a reference to T using the functions in the source
// object's type slots
template <
class T // The target type
, class Convertible // returns a pointer to a unaryfunc producing an object
, class TExtract // ...from which TExtract extracts T's constructor argument
>
struct tp_cref_from_python
: value_from_python<T, tp_cref_from_python<T,Convertible,TExtract> >
{
private:
typedef tp_cref_from_python<T,Convertible,TExtract> self;
typedef value_from_python<T,tp_cref_from_python<T,Convertible,TExtract> > base;
public:
tp_cref_from_python()
: base(&return_void_ptr<Convertible>::execute)
{}
static T const& convert(PyObject* obj, from_python_data& data)
{
unaryfunc converter = *(unaryfunc*)data.stage1;
void* storage = self::get_storage(data);
ref converted(converter(obj));
T* const p = new (storage) T(TExtract::execute(converted.get()));
// note that construction is successful.
data.stage1 = p;
return *p;
}
};
struct convertible_to_int
{
static unaryfunc* execute(PyObject* obj)
{
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
if (number_methods == 0)
return 0;
// For floating types, return the float conversion slot to avoid
// creating a new object. We'll handle that in
// py_int_or_float_as_long, below
if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float)
return &number_methods->nb_float;
return number_methods && number_methods->nb_int
? &number_methods->nb_int : 0;
}
};
struct py_int_or_float_as_long
{
static long execute(PyObject* obj)
{
if (PyObject_TypeCheck(obj, &PyFloat_Type))
{
return numeric_cast<long>(PyFloat_AS_DOUBLE(obj));
}
else
{
return PyInt_AS_LONG(obj);
}
}
};
struct convertible_to_double
{
static unaryfunc* execute(PyObject* obj)
{
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
if (number_methods == 0)
return 0;
// For integer types, return the tp_int conversion slot to avoid
// creating a new object. We'll handle that in
// py_float_or_int_as_double, below
if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int)
return &number_methods->nb_int;
return number_methods && number_methods->nb_float
? &number_methods->nb_float : 0;
}
};
struct py_float_or_int_as_double
{
static double execute(PyObject* obj)
{
if (PyObject_TypeCheck(obj, &PyInt_Type))
{
return PyInt_AS_LONG(obj);
}
else
{
return PyFloat_AS_DOUBLE(obj);
}
}
};
template <class T, class Convertible, class Convert>
struct scalar_from_python
{
tp_cref_from_python<T,Convertible,Convert> cref_converter;
tp_scalar_from_python<T,Convertible,Convert> value_converter;
};
template <class T>
void register_int_converters(T* = 0)
{
static scalar_from_python<T, convertible_to_int, py_int_or_float_as_long> x;
}
}
#define REGISTER_INT_CONVERTERS(U) register_int_converters<U>()
#define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U)
void initialize_builtin_converters()
{
REGISTER_INT_CONVERTERS2(char);
REGISTER_INT_CONVERTERS2(short);
REGISTER_INT_CONVERTERS2(int);
REGISTER_INT_CONVERTERS2(long);
static scalar_from_python<
float,convertible_to_double,py_float_or_int_as_double> float_from_python;
static scalar_from_python<
double,convertible_to_double,py_float_or_int_as_double> double_from_python;
static scalar_from_python<
long double,convertible_to_double,py_float_or_int_as_double> long_double_from_python;
static scalar_from_python<
char const*, convertible_to_cstring, extract_cstring> cstring_from_python;
static tp_cref_from_python<
std::string, convertible_to_string, extract_cstring> string_from_python;
}
}}} // namespace boost::python::converter

View File

@@ -0,0 +1,26 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/from_python.hpp>
#include <boost/python/converter/registry.hpp>
namespace boost { namespace python { namespace converter {
from_python_converter_base::from_python_converter_base(
type_id_t type
, from_python_check checker
)
: body(type)
, m_convertible(checker)
{
// Insert this in the converter chain.
from_python_converter_base*& head = registry::from_python_chain(type);
m_next = head;
head = this;
}
}}} // namespace boost::python::converter

35
src/converter/handle.cpp Normal file
View File

@@ -0,0 +1,35 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/handle.hpp>
#include <boost/python/converter/body.hpp>
namespace boost { namespace python { namespace converter {
bool handle::convertible() const
{
for (handle const* p = this; p != 0; p = p->m_next)
{
if (p->m_body == 0)
return false;
}
return true;
}
void handle::destroy()
{
// Recurse down the chain releasing from tail to head
if (m_next != 0)
m_next->destroy();
// Our body knows how to destroy us. If we never got a body,
// there's nothing to do.
if (m_body)
m_body->destroy_handle(this);
}
// void handle::dummy::nonnull() {}
}}} // namespace boost::python::converter

Some files were not shown because too many files have changed in this diff Show More