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

Compare commits

...

129 Commits

Author SHA1 Message Date
nobody
f5e65866d4 This commit was manufactured by cvs2svn to create tag
'Version_1_27_0'.

[SVN r12749]
2002-02-07 13:33:59 +00:00
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
Dave Abrahams
d4b215a66b Integrating Andreas Zieringer's shared lib changes
Modified Files:
	build/Jamfile build/win32_mwcc_setup.bat src/classes.cpp
	src/conversions.cpp src/cross_module.cpp
	src/extension_class.cpp src/functions.cpp
	src/init_function.cpp src/module_builder.cpp src/objects.cpp
	src/types.cpp


[SVN r12084]
2001-12-17 17:00:53 +00:00
Dave Abrahams
1a13387012 Integrating Andreas Zieringer's shared library implementation.
Modified Files:
	classes.hpp conversions.hpp cross_module.hpp errors.hpp
	module_builder.hpp objects.hpp operators.hpp detail/config.hpp
	detail/extension_class.hpp detail/functions.hpp
	detail/init_function.hpp detail/signatures.hpp
	detail/singleton.hpp detail/types.hpp detail/void_adaptor.hpp


[SVN r12083]
2001-12-17 16:59:54 +00:00
Dave Abrahams
291c36df05 Integrated Scott Snyder's nested class patch
[SVN r12080]
2001-12-17 05:49:24 +00:00
Dave Abrahams
bed2c8a371 no message
[SVN r12076]
2001-12-16 18:20:26 +00:00
Dave Abrahams
e65ca4ccac Python 1.5 compatibility fixes
[SVN r12072]
2001-12-16 17:58:23 +00:00
Ralf W. Grosse-Kunstleve
f9e6933840 Use "call", otherwise the "set" command is not executed.
[SVN r12066]
2001-12-16 06:00:03 +00:00
Dave Abrahams
5134fb2ec1 scott snyder's fixes to maintain 1.5.2 compatibility
[SVN r12065]
2001-12-15 22:59:48 +00:00
Ralf W. Grosse-Kunstleve
3a86a69964 Restore Python <2.2 compatibility (config.h, pyconfig.h).
[SVN r12064]
2001-12-15 04:59:11 +00:00
Ralf W. Grosse-Kunstleve
c6fd3c47a4 Makefile and example setup batch file for Win32 Metrowerks Codewarrior 7.
[SVN r12063]
2001-12-15 04:57:18 +00:00
Dave Abrahams
a365fa6109 many fixes
[SVN r12054]
2001-12-13 19:43:35 +00:00
Dave Abrahams
160451b210 Integrating scott snyder's inplace operator improvements
Fixed Python 2.2 incompatibility


[SVN r12044]
2001-12-13 18:23:10 +00:00
Dave Abrahams
2f6e3cc09d Integrating scott snyder's inplace operator improvements
[SVN r12043]
2001-12-13 18:22:03 +00:00
Dave Abrahams
d05cc7ccec integrating scott snyder's changes
[SVN r12042]
2001-12-13 18:18:52 +00:00
Dave Abrahams
ccfd4acbda factored out python.jam
[SVN r12041]
2001-12-13 18:17:38 +00:00
Dave Abrahams
6a6084ed0e Metrowerks needs BOOST_NO_STD_LOCALE in config to be able to compile regex
regex test Jamfile updates so that some tests will actually run
warning suppression for condition.cpp

unit-test rule now accepts input files
updated metrowerks and borland to properly set up path for running tests

----------------------------------------------------------------------
Modified Files:
	boost/config/compiler/metrowerks.hpp
	libs/python/src/gen_function.py libs/regex/test/Jamfile
 Tag: thread-initial
	libs/thread/src/condition.cpp
 No tag
	tools/build/boost-base.jam tools/build/borland-tools.jam
	tools/build/metrowerks-tools.jam
----------------------------------------------------------------------


[SVN r11853]
2001-12-02 17:43:45 +00:00
Dave Abrahams
0dbb780a2f * Updated to new handle_exception() idiom for boost::python
* Made Cygwin archiving reliable, even when the user supplies a path with backslashes

----------------------------------------------------------------------

Modified Files:
	tools/build/gcc-tools.jam tools/build/new/boost-build.jam
	boost/python/detail/config.hpp libs/python/build/Jamfile
	libs/python/example/do_it_yourself_convts.cpp
	libs/python/example/dvect.cpp libs/python/example/example1.cpp
	libs/python/example/getting_started1.cpp
	libs/python/example/getting_started2.cpp
	libs/python/example/ivect.cpp libs/python/example/nested.cpp
	libs/python/example/noncopyable_export.cpp
	libs/python/example/noncopyable_import.cpp
	libs/python/example/pickle1.cpp
	libs/python/example/pickle2.cpp
	libs/python/example/pickle3.cpp
	libs/python/example/richcmp1.cpp
	libs/python/example/richcmp2.cpp
	libs/python/example/richcmp3.cpp libs/python/example/rwgk1.cpp
	libs/python/example/simple_vector.cpp
	libs/python/test/comprehensive.cpp
Added Files:
	libs/python/example/rwgk2.cpp libs/python/example/rwgk3.cpp
----------------------------------------------------------------------


[SVN r11705]
2001-11-15 05:29:22 +00:00
Dave Abrahams
e6efa6e13e Fix minor gcc bug
[SVN r11704]
2001-11-15 00:51:33 +00:00
Dave Abrahams
76768120d4 use the new "no-rethrow" way of handling exceptions.
[SVN r11692]
2001-11-14 20:36:14 +00:00
Dave Abrahams
7d6ff83760 use the new "no-rethrow" way of handling exceptions.
[SVN r11691]
2001-11-14 20:07:38 +00:00
Dave Abrahams
5bec0d2d98 fixes for intel
[SVN r11690]
2001-11-14 20:06:18 +00:00
Dave Abrahams
aad05325a6 Pro7 compatibility
use the new "no-rethrow" way of handling exceptions.


[SVN r11682]
2001-11-14 19:50:35 +00:00
Dave Abrahams
6e7f1bc257 Pro7 compatibility
[SVN r11681]
2001-11-14 17:41:17 +00:00
Dave Abrahams
634d0848c8 got rid of the "rethrow error reporting" mechanism
[SVN r11680]
2001-11-14 17:37:07 +00:00
Dave Abrahams
b7e1059227 initial checkin
[SVN r11679]
2001-11-14 17:35:18 +00:00
Dave Abrahams
e7904fa67a add _d targets for debugging
[SVN r11678]
2001-11-14 17:32:08 +00:00
Dave Abrahams
e38bc7cbce Pro7 compatibility
[SVN r11677]
2001-11-14 17:26:11 +00:00
Dave Abrahams
b211f8a096 Modified Files:
index.htm - fixed reference to CVS repository
	libs/python/build/Jamfile - first stab at metrowerks Pro7 support
	status/Jamfile - added RUN_ALL_TESTS variables to force tests to run
	tools/build/boost-build.jam - fix BOOST_BUILD_INSTALLATION setting
	tools/build/metrowerks-tools.jam - command file support
	tools/build/msvc-tools.jam - permanent command file support
	tools/build/intel-win32-tools.jam - made it an extension of msvc-tools.jam
	tools/build/gcc-tools.jam  - made FINDLIBS change submitted by Toon Knapen
	tools/build/jam_src/variable.c - changed command-line/env. variable
					interpretation so that
					surrounding them with quotes causes
					no breaking at spaces.

These files were converted from tabs to spaces:

	boost/python/conversions.hpp
	boost/python/reference.hpp boost/python/detail/base_object.hpp
	boost/python/detail/functions.hpp
	boost/python/detail/wrap_python.hpp libs/python/test/comprehensive.cpp
	tools/build/boost-base.jam
	tools/build/como-tools.jam


[SVN r11652]
2001-11-10 22:16:01 +00:00
160 changed files with 12697 additions and 1204 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

@@ -54,47 +54,20 @@
# PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for
# the dvect and ivect tests above.
# declare the location of this subproject relative to the root
subproject libs/python/build ;
# grab variables from command-line or environment.
local PYTHON_VERSION = $(PYTHON_VERSION) ;
local PYTHON_ROOT = $(PYTHON_ROOT) ;
local PYTHON_INCLUDES = $(PYTHON_INCLUDES) ;
local PYTHON_LIBS = $(PYTHON_LIBS) ;
local PYTHON_LIB_PATH = $(PYTHON_LIB_PATH) ;
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) ;
# bring in the rules for python
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
# Do some OS-specific setup
if $(NT)
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_DYNAMIC_LIB ;
#######################
rule bpl-test ( test-name : sources + )
{
PYTHON_VERSION ?= 2.1 ;
PYTHON_ROOT ?= c:/tools/python ;
PYTHON_INCLUDES ?= <include>$(PYTHON_ROOT)/include <gcc><*><include>/usr/include/python$(PYTHON_VERSION) ;
PYTHON_LIBS ?= c:/cygnus/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).dll.a ;
PYTHON_LIB_PATH = $(PYTHON_ROOT)/libs ;
# common properties required for compiling any Python module.
PYTHON_PROPERTIES ?=
<gcc><*><define>SIZEOF_LONG=4
<gcc><*><define>USE_DL_IMPORT
<runtime-link>dynamic
;
boost-python-test $(test-name) : $(sources) <lib>libboost_python ;
}
else if $(UNIX)
{
PYTHON_VERSION ?= 1.5 ;
PYTHON_INCLUDES ?= <include>/usr/include/python$(PYTHON_VERSION) ;
PYTHON_LIBS ?= /usr/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).a ;
}
# how do we invoke python?
local PYTHON = $(PYTHON) ;
PYTHON ?= python ;
PYTHON = [ FAppendSuffix $(PYTHON:G=<executable-grist>) : $(SUFEXE) ] ;
SEARCH on $(PYTHON) = $(PATH) ;
#######################
@@ -102,148 +75,46 @@ SEARCH on $(PYTHON) = $(PATH) ;
# Declare the boost python static link library
#
# standard include requirements for anything using Boost.Python
local BOOST_PYTHON_INCLUDES = <include>$(BOOST_ROOT) $(PYTHON_INCLUDES) ;
# Base names of the source files for libboost_python
local CPP_SOURCES =
classes conversions extension_class functions
init_function module_builder objects types cross_module ;
types classes conversions extension_class functions
init_function module_builder objects cross_module errors
;
lib libboost_python : ../src/$(CPP_SOURCES).cpp
lib libboost_python_static : ../src/$(CPP_SOURCES).cpp
# requirements
: $(BOOST_PYTHON_INCLUDES)
<shared-linkable>true
<define>BOOST_PYTHON_STATIC_LIB=1
$(PYTHON_PROPERTIES) ;
#######################
# boost-python name : sources : requirements : default-BUILD
#
# Declare a boost python module. Return a list of the DLL files generated.
rule boost-python
{
# declare a DLL; add the boost python library to sources
dll $(<) : <lib>libboost_python $(>)
# Requirements
: $(3) # caller-specified requirements
# standard requirements
$(BOOST_PYTHON_INCLUDES)
<msvc><*><library-path>$(PYTHON_LIB_PATH)
<gcc><*><library-file>$(PYTHON_LIBS)
$(PYTHON_PROPERTIES)
: $(4) ; # pass on the default-BUILD, if any
}
# boost-python-test name : sources : requirements : default-BUILD
#
# Just like boost-python, but the result becomes part of the test pseudotarget
# instead of being built by 'all'
rule boost-python-test
{
type-DEPENDS test : $(<) ;
local gSUPPRESS_FAKE_TARGETS = true ;
boost-python $(1) : $(2) : $(3) : $(4) ;
}
#######################
# boost-python-runtest target : python-script sources : requirements : local-build : args
#
# declare two python module tests: $(<).test which builds when out-of-date, and
# $(<).run which builds unconditionally.
rule boost-python-runtest
{
# tell Jam that the python script is relative to this directory
SEARCH on $(>[1]) = $(SEARCH_SOURCE) ;
# required command-line args can be specified in argument 5
# The user can add additional arguments in PYTHON_TEST_ARGS.
local gPYTHON_TEST_ARGS = $(5) $(PYTHON_TEST_ARGS) ;
# declare the two subsidiary tests.
declare-local-target $(<:S=.test) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_TEST ;
declare-local-target $(<:S=.run) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_RUNTEST ;
}
# special rules for two new target types: PYTHON_TEST and PYTHON_RUNTEST.
# These are identical except that PYTHON_TEST runs the test when out-of-date, and
# PYTHON_RUNTEST runs the test unconditionally. These are used by boost-python-runtest.
SUFPYTHON_TEST = .test ;
gGENERATOR_FUNCTION(PYTHON_TEST) = python-test-target ;
rule python-test-target # test-target : sources :
{
python-runtest-aux $(<) : $(>) ;
Clean clean : $(<) ; # remove the test-target as part of any clean operation
type-DEPENDS test : $(<) ;
MakeLocate $(<) : $(LOCATE_TARGET) ;
}
actions python-test-target bind PYTHON
{
$(SHELL_SET)PYTHONPATH=$(PYTHONPATH)
$(SHELL_EXPORT)PYTHONPATH
$(PYTHON) "$(>)" $(ARGS) > "$(<)"
}
SUFPYTHON_RUNTEST = .run ;
gGENERATOR_FUNCTION(PYTHON_RUNTEST) = python-runtest-target ;
rule python-runtest-target # test-target : sources :
{
python-runtest-aux $(<) : $(>) ;
NOTFILE $(<) ;
ALWAYS $(<) ;
}
actions python-runtest-target bind PYTHON
{
$(SHELL_SET)PYTHONPATH=$(PYTHONPATH)
$(SHELL_EXPORT)PYTHONPATH
$(PYTHON) "$(>)" $(ARGS)
}
rule python-runtest-aux # target : sources
{
DEPENDS $(<) : $(>) ;
ARGS on $(<) += $(gPYTHON_TEST_ARGS) ;
# Some tests need an extra command-line arg if built with
# msvc. Checking the target grist is a cheap way to
# find out.
switch $(<)
{
case <*\\\\msvc\\\\*>* : ARGS on $(<) += --broken-auto-ptr ;
}
# compute the PYTHONPATH environment variable that will allow the test to
# find all of the modules on which it depends.
PYTHONPATH on $(<) = [ join
$(gLOCATE($(>[1]))) # location of python test file
$(gRUN_PATH($(<))) # location of module dependencies
[ join-path $(TOP) libs python test ] # location of doctest
$(PYTHONPATH) # base PYTHONPATH from environment
: $(SPLITPATH) ] ; # platform path separator
PYTHON on $(<) = $(PYTHON) ;
DEPENDS $(<) : $(PYTHON) ;
}
dll libboost_python
# $(SUFDLL[1])
: ../src/$(CPP_SOURCES).cpp
# requirements
: $(BOOST_PYTHON_INCLUDES)
<shared-linkable>true
<runtime-link>dynamic
<define>BOOST_PYTHON_HAS_DLL_RUNTIME=1
$(PYTHON_PROPERTIES)
;
############# comprehensive module and test ###########
boost-python-test boost_python_test : ../test/comprehensive.cpp ;
bpl-test boost_python_test
: ../test/comprehensive.cpp ;
boost-python-runtest comprehensive
: [ join-path $(DOTDOT) test comprehensive.py ]
<lib>boost_python_test ;
: ../test/comprehensive.py <lib>boost_python_test <lib>libboost_python ;
############# simple tests from ../example ############
rule boost-python-example-runtest
rule boost-python-example-runtest ( name )
{
boost-python-test $(<) : ../example/$(<).cpp ;
boost-python-runtest $(<) : [ join-path $(DOTDOT) example test_$(<).py ] <lib>$(<) ;
bpl-test $(name)
: ../example/$(name).cpp ;
boost-python-runtest $(name)
: ../example/test_$(name).py <lib>$(name) ;
}
@@ -257,18 +128,18 @@ boost-python-example-runtest pickle2 ;
boost-python-example-runtest pickle3 ;
boost-python-test ivect : ../example/ivect.cpp ;
boost-python-test dvect : ../example/dvect.cpp ;
boost-python-test noncopyable_export : ../example/noncopyable_export.cpp ;
boost-python-test noncopyable_import : ../example/noncopyable_import.cpp ;
bpl-test ivect : ../example/ivect.cpp ;
bpl-test dvect : ../example/dvect.cpp ;
bpl-test noncopyable_export : ../example/noncopyable_export.cpp ;
bpl-test noncopyable_import : ../example/noncopyable_import.cpp ;
############## cross-module tests from ../example ##########
# A simple rule to build a test which depends on multiple modules in the PYTHONPATH
rule boost-python-multi-example-runtest # test-name : python-file libs
rule boost-python-multi-example-runtest ( test-name : modules + )
{
boost-python-runtest $(<)
: ../example/tst_$(<).py <lib>$(>)
boost-python-runtest $(test-name)
: ../example/tst_$(test-name).py <lib>$(modules) <lib>libboost_python
: : : $(PYTHON_VECT_ITERATIONS) ;
}

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

149
build/win32_mwcc.mak Executable file
View File

@@ -0,0 +1,149 @@
# Usage:
#
# make copy Copy the sources and tests
# make Compile all sources
# make test Run doctest tests
# make clean Remove all object files
# make del Remove the sources and tests
#
# Revision history:
# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve)
ROOT=R:
BOOST_WIN="$(ROOT)\boost"
BOOST_UNIX=$(HOME)/boost
#PYEXE="C:\Program files\Python\python.exe"
#PYINC=-I"C:\Program files\Python\include"
#PYLIB="C:\Program files\Python\libs\python15.lib"
PYEXE="C:\Python21\python.exe"
PYINC=-I"C:\Python21\include"
PYLIB="C:\Python21\libs\python21.lib"
STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB
WARNOPTS=-warn on,nounusedexpr,nounused
OPTOPTS=-O
CPP=mwcc
CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \
$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC)
LD=mwld
LDOPTS=-export dllexport -shared
OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \
init_function.obj module_builder.obj \
objects.obj types.obj cross_module.obj
.SUFFIXES: .obj .cpp
all: libboost_python.lib \
boost_python_test.pyd \
abstract.pyd \
getting_started1.pyd getting_started2.pyd \
simple_vector.pyd \
do_it_yourself_convts.pyd \
nested.pyd \
pickle1.pyd pickle2.pyd pickle3.pyd \
noncopyable_export.pyd noncopyable_import.pyd \
ivect.pyd dvect.pyd \
richcmp1.pyd richcmp2.pyd richcmp3.pyd
libboost_python.lib: $(OBJ)
$(LD) -library -o libboost_python.lib $(OBJ)
boost_python_test.pyd: $(OBJ) comprehensive.obj
$(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) -o boost_python_test.pyd
abstract.pyd: $(OBJ) abstract.obj
$(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) -o abstract.pyd
getting_started1.pyd: $(OBJ) getting_started1.obj
$(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) -o getting_started1.pyd
getting_started2.pyd: $(OBJ) getting_started2.obj
$(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) -o getting_started2.pyd
simple_vector.pyd: $(OBJ) simple_vector.obj
$(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) -o simple_vector.pyd
do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) -o do_it_yourself_convts.pyd
nested.pyd: $(OBJ) nested.obj
$(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) -o nested.pyd
pickle1.pyd: $(OBJ) pickle1.obj
$(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) -o pickle1.pyd
pickle2.pyd: $(OBJ) pickle2.obj
$(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) -o pickle2.pyd
pickle3.pyd: $(OBJ) pickle3.obj
$(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) -o pickle3.pyd
noncopyable_export.pyd: $(OBJ) noncopyable_export.obj
$(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) -o noncopyable_export.pyd
noncopyable_import.pyd: $(OBJ) noncopyable_import.obj
$(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) -o noncopyable_import.pyd
ivect.pyd: $(OBJ) ivect.obj
$(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) -o ivect.pyd
dvect.pyd: $(OBJ) dvect.obj
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) -o dvect.pyd
richcmp1.pyd: $(OBJ) richcmp1.obj
$(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) -o richcmp1.pyd
richcmp2.pyd: $(OBJ) richcmp2.obj
$(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) -o richcmp2.pyd
richcmp3.pyd: $(OBJ) richcmp3.obj
$(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) -o richcmp3.pyd
.cpp.obj:
$(CPP) $(CPPOPTS) -c $*.cpp
test:
$(PYEXE) comprehensive.py
$(PYEXE) test_abstract.py
$(PYEXE) test_getting_started1.py
$(PYEXE) test_getting_started2.py
$(PYEXE) test_simple_vector.py
$(PYEXE) test_do_it_yourself_convts.py
$(PYEXE) test_nested.py
$(PYEXE) test_pickle1.py
$(PYEXE) test_pickle2.py
$(PYEXE) test_pickle3.py
$(PYEXE) test_cross_module.py
$(PYEXE) test_richcmp1.py
$(PYEXE) test_richcmp2.py
$(PYEXE) test_richcmp3.py
clean:
-del *.obj
-del *.lib
-del *.exp
-del *.idb
-del *.pyd
-del *.pyc
softlinks:
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
unlink:
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink
cp:
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp
rm:
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm
copy:
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy
del:
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del

2
build/win32_mwcc_setup.bat Executable file
View File

@@ -0,0 +1,2 @@
call "c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat"
set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib

View File

@@ -98,6 +98,12 @@ Notes:<ul>
<li>Any function added to a class whose initial argument matches the class (or
any base) will act like a member function in Python.
<li>To define a nested class, just pass the enclosing
<tt>class_builder</tt> (instead of a <tt>module_builder</tt>) as the
first argument to the nested <tt>class_builder</tt>'s constructor.
</ul>
<p>
We can even make a subclass of <code>hello.world</code>:

326
doc/new-conversions.html Normal file
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

@@ -287,6 +287,35 @@ bignum_class.def(&amp;rmod, "__rmod__");
found first (be it ``<code>int</code>`` or ``<code>float</code>'') will be
used for either of the two types.
<h3><a name="inplace">Inplace Operators</a></h3>
<p>
Boost.Python can also be used to expose inplace numeric operations
(i.e., <code>+=</code> and so forth). These operators must be wrapped
manually, as described in the previous section. For example, suppose
the class BigNum has an <code>operator+=</code>:
<blockquote><pre>
BigNum& operator+= (BigNum const&amp; right);
</pre></blockquote>
This can be exposed by first writing a wrapper function:
<blockquote><pre>
BigNum& iadd (BigNum&amp; self, const BigNum&amp; right)
{
return self += right;
}
</pre></blockquote>
and then exposing the wrapper with
<blockquote><pre>
bignum_class.def(&amp;iadd, "__iadd__");
</pre></blockquote>
<h3><a name="coercion">Coercion</a></h3>

View File

@@ -107,8 +107,6 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE
BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("do_it_yourself_convts");
@@ -120,9 +118,4 @@ BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts)
// Add the member functions.
ixset_class.def(&IndexingSet::add, "add");
ixset_class.def(&IndexingSet::get, "get");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -32,8 +32,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
BOOST_PYTHON_MODULE_INIT(dvect)
{
try
{
python::module_builder this_module("dvect");
python::class_builder<vects::dvect> dvect_class(this_module, "dvect");
@@ -47,10 +45,4 @@ BOOST_PYTHON_MODULE_INIT(dvect)
# include "dvect_defs.cpp"
# include "ivect_defs.cpp"
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -16,32 +16,21 @@ namespace hello {
// Python requires an exported function called init<module-name> in every
// extension module. This is where we build the module contents.
extern "C"
#ifdef _WIN32
__declspec(dllexport)
#endif
void inithello()
BOOST_PYTHON_MODULE_INIT(hello)
{
try
{
// create an object representing this extension module
boost::python::module_builder hello("hello");
// create an object representing this extension module
boost::python::module_builder hello("hello");
// Create the Python type object for our extension class
boost::python::class_builder<hello::world> world_class(hello, "world");
// Create the Python type object for our extension class
boost::python::class_builder<hello::world> world_class(hello, "world");
// Add the __init__ function
world_class.def(boost::python::constructor<int>());
// Add a regular member function
world_class.def(&hello::world::get, "get");
// Add the __init__ function
world_class.def(boost::python::constructor<int>());
// Add a regular member function
world_class.def(&hello::world::get, "get");
// Add a regular function to the module
hello.def(hello::length, "length");
}
catch(...)
{
boost::python::handle_exception(); // Deal with the exception for Python
}
// Add a regular function to the module
hello.def(hello::length, "length");
}
// Win32 DLL boilerplate

View File

@@ -16,17 +16,10 @@ namespace python = boost::python;
// extension module. This is where we build the module contents.
BOOST_PYTHON_MODULE_INIT(getting_started1)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("getting_started1");
// Add regular functions to the module.
this_module.def(greet, "greet");
this_module.def(square, "square");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -26,8 +26,6 @@ namespace python = boost::python;
BOOST_PYTHON_MODULE_INIT(getting_started2)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("getting_started2");
@@ -44,9 +42,4 @@ BOOST_PYTHON_MODULE_INIT(getting_started2)
// Even better, invite() can also be made a member of hello_class!!!
hello_class.def(invite, "invite");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -32,8 +32,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
BOOST_PYTHON_MODULE_INIT(ivect)
{
try
{
python::module_builder this_module("ivect");
python::class_builder<vects::ivect> ivect_class(this_module, "ivect");
@@ -47,10 +45,5 @@ BOOST_PYTHON_MODULE_INIT(ivect)
# include "dvect_defs.cpp"
# include "ivect_defs.cpp"
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -32,13 +32,6 @@ namespace {
BOOST_PYTHON_MODULE_INIT(nested)
{
try
{
boost::python::module_builder this_module("nested");
this_module.def(show_nested_tuples, "show_nested_tuples");
}
catch(...)
{
boost::python::handle_exception();
}
}

View File

@@ -18,8 +18,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
BOOST_PYTHON_MODULE_INIT(noncopyable_export)
{
try
{
python::module_builder this_module("noncopyable_export");
python::class_builder<store> store_class(this_module, "store");
@@ -27,9 +25,4 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_export)
store_class.def(python::constructor<int>());
store_class.def(&store::recall, "recall");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -31,8 +31,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
BOOST_PYTHON_MODULE_INIT(noncopyable_import)
{
try
{
python::module_builder this_module("noncopyable_import");
python::import_converters<store>
@@ -44,9 +42,4 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_import)
// However, to keep this example simple, we only define a
// module-level function.
this_module.def(add_stores, "add_stores");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -41,8 +41,6 @@ namespace { // Avoid cluttering the global namespace.
BOOST_PYTHON_MODULE_INIT(pickle1)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("pickle1");
@@ -56,9 +54,4 @@ BOOST_PYTHON_MODULE_INIT(pickle1)
// Support for pickle.
world_class.def(world_getinitargs, "__getinitargs__");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -73,8 +73,6 @@ namespace { // Avoid cluttering the global namespace.
BOOST_PYTHON_MODULE_INIT(pickle2)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("pickle2");
@@ -92,9 +90,4 @@ BOOST_PYTHON_MODULE_INIT(pickle2)
world_class.def(world_getinitargs, "__getinitargs__");
world_class.def(world_getstate, "__getstate__");
world_class.def(world_setstate, "__setstate__");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -65,8 +65,6 @@ namespace { // Avoid cluttering the global namespace.
BOOST_PYTHON_MODULE_INIT(pickle3)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("pickle3");
@@ -85,11 +83,6 @@ BOOST_PYTHON_MODULE_INIT(pickle3)
world_class.def_raw(world_getstate, "__getstate__");
world_class.def_raw(world_setstate, "__setstate__");
world_class.getstate_manages_dict();
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}
namespace {

View File

@@ -77,11 +77,8 @@ namespace {
BOOST_PYTHON_MODULE_INIT(richcmp1)
{
try {
boost::python::module_builder this_module("richcmp1");
// The actual work is done in a separate function in order
// to suppress a bogus VC60 warning.
init_module(this_module);
}
catch (...) { boost::python::handle_exception(); }
}

View File

@@ -55,11 +55,8 @@ namespace {
BOOST_PYTHON_MODULE_INIT(richcmp2)
{
try {
boost::python::module_builder this_module("richcmp2");
// The actual work is done in a separate function in order
// to suppress a bogus VC60 warning.
init_module(this_module);
}
catch (...) { boost::python::handle_exception(); }
}

View File

@@ -168,11 +168,8 @@ namespace {
BOOST_PYTHON_MODULE_INIT(richcmp3)
{
try {
boost::python::module_builder this_module("richcmp3");
// The actual work is done in a separate function in order
// to suppress a bogus VC60 warning.
init_module(this_module);
}
catch (...) { boost::python::handle_exception(); }
}

View File

@@ -13,29 +13,12 @@ namespace python = boost::python;
// Python requires an exported function called init<module-name> in every
// extension module. This is where we build the module contents.
extern "C"
#ifdef _WIN32
__declspec(dllexport)
#endif
void initrwgk1()
BOOST_PYTHON_MODULE_INIT(rwgk1)
{
try
{
// Create an object representing this extension module.
python::module_builder this_module("rwgk1");
// Add regular functions to the module.
this_module.def(greet, "greet");
this_module.def(square, "square");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}
// Win32 DLL boilerplate
#if defined(_WIN32)
#include <windows.h>
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; }
#endif // _WIN32

View File

@@ -85,15 +85,13 @@ namespace { // Avoid cluttering the global namespace.
BOOST_PYTHON_MODULE_INIT(simple_vector)
{
try
{
python::module_builder this_module("simple_vector");
python::class_builder<std::vector<double>, vector_double_wrapper>
vector_double(this_module, "vector_double");
vector_double.def(python::constructor<>());
vector_double.def(python::constructor<const int>());
vector_double.def(python::constructor<int>());
vector_double.def(python::constructor<python::tuple>());
vector_double.def(&std::vector<double>::size, "__len__");
vector_double.def(getitem, "__getitem__");
@@ -103,9 +101,4 @@ BOOST_PYTHON_MODULE_INIT(simple_vector)
this_module.def(foo, "foo");
this_module.def(bar, "bar");
}
catch(...)
{
python::handle_exception(); // Deal with the exception for Python
}
}

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

@@ -25,6 +25,22 @@ class class_builder
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
}
template <class OtherT, class OtherU>
class_builder(class_builder<OtherT, OtherU>& cls, const char* name)
: m_class(new detail::extension_class<T, U>(name))
{
cls.add(ref(as_object(m_class.get()), ref::increment_count), name);
}
template <class OtherT, class OtherU>
class_builder(detail::extension_class<OtherT, OtherU>* cls,
const char* name)
: m_class(new detail::extension_class<T, U>(name))
{
cls->set_attribute(name,
ref(as_object(m_class.get()), ref::increment_count));
}
~class_builder()
{}

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:
@@ -78,6 +78,19 @@ class instance
PyObject* gt(PyObject* other);
PyObject* ge(PyObject* other);
// Inplace operations.
PyObject* inplace_add(PyObject* other);
PyObject* inplace_subtract(PyObject* other);
PyObject* inplace_multiply(PyObject* other);
PyObject* inplace_divide(PyObject* other);
PyObject* inplace_remainder(PyObject* other);
PyObject* inplace_power(PyObject* exponent, PyObject* modulus);
PyObject* inplace_lshift(PyObject* other);
PyObject* inplace_rshift(PyObject* other);
PyObject* inplace_and(PyObject* other);
PyObject* inplace_or(PyObject* other);
PyObject* inplace_xor(PyObject* other);
private: // noncopyable, without the size bloat
instance(const instance&);
void operator=(const instance&);
@@ -92,7 +105,7 @@ class instance
template <class T> class meta_class;
namespace detail {
class class_base : public type_object_base
class BOOST_PYTHON_DECL class_base : public type_object_base
{
public:
class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space);
@@ -115,6 +128,10 @@ namespace detail {
private: // boost::python::type_object_base required interface implementation
void instance_dealloc(PyObject*) const; // subclasses should not override this
private: // noncopyable, without the size bloat
class_base(const class_base&);
void operator=(const class_base&);
private:
string m_name;
@@ -128,11 +145,12 @@ namespace detail {
// A type which acts a lot like a built-in Python class. T is the obj type,
// so class_t<instance> is a very simple "class-alike".
template <class T>
class class_t
class BOOST_PYTHON_DECL_TEMPLATE class_t
: public boost::python::detail::class_base
{
public:
class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space);
~class_t();
// Standard Python functions.
PyObject* call(PyObject* args, PyObject* keywords);
@@ -178,6 +196,18 @@ class class_t
PyObject* instance_number_oct(PyObject*) const;
PyObject* instance_number_hex(PyObject*) const;
PyObject* instance_number_inplace_add(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const;
PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_and(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_or(PyObject*, PyObject*) const;
PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const;
private: // Implement rich comparisons
PyObject* instance_lt(PyObject*, PyObject*) const;
PyObject* instance_le(PyObject*, PyObject*) const;
@@ -193,15 +223,11 @@ class class_t
private: // Implementation of boost::python::detail::class_base required interface
void delete_instance(PyObject*) const;
private: // noncopyable, without the size bloat
class_t(const class_t<T>&);
void operator=(const class_t&);
};
// The type of a class_t<T> object.
template <class T>
class meta_class
class BOOST_PYTHON_DECL_TEMPLATE meta_class
: public boost::python::detail::reprable<
boost::python::detail::callable<
boost::python::detail::getattrable<
@@ -239,6 +265,11 @@ class_t<T>::class_t(meta_class<T>* meta_class_obj, string name, tuple bases, con
{
}
template <class T>
class_t<T>::~class_t()
{
}
template <class T>
void class_t<T>::delete_instance(PyObject* obj) const
{
@@ -319,7 +350,7 @@ int class_t<T>::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyO
return 0;
}
void adjust_slice_indices(PyObject* obj, int& start, int& finish);
void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish);
template <class T>
PyObject* class_t<T>::instance_sequence_slice(PyObject* obj, int start, int finish) const
@@ -493,6 +524,72 @@ PyObject* class_t<T>::instance_number_hex(PyObject* obj) const
return downcast<T>(obj)->hex();
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_add(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_add(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_subtract(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_subtract(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_multiply(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_multiply(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_divide(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_divide(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_remainder(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_remainder(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const
{
return downcast<T>(obj)->inplace_power(exponent, modulus);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_lshift(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_lshift(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_rshift(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_rshift(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_and(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_and(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_or(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_or(other);
}
template <class T>
PyObject* class_t<T>::instance_number_inplace_xor(PyObject* obj, PyObject* other) const
{
return downcast<T>(obj)->inplace_xor(other);
}
template <class T>
PyObject* class_t<T>::instance_lt(PyObject* obj, PyObject* other) const
{

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>
@@ -74,17 +74,17 @@ inline void xdecref_impl(PyObject* p) { Py_XDECREF(p); }
template <class T>
inline void decref(T* p)
{
char* const raw_p = reinterpret_cast<char*>(p);
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
decref_impl(reinterpret_cast<PyObject*>(p_base));
char* const raw_p = reinterpret_cast<char*>(p);
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
decref_impl(reinterpret_cast<PyObject*>(p_base));
}
template <class T>
inline void xdecref(T* p)
{
char* const raw_p = reinterpret_cast<char*>(p);
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
char* const raw_p = reinterpret_cast<char*>(p);
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
}
namespace detail {
@@ -122,61 +122,68 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
// Converters
//
PyObject* to_python(long);
long from_python(PyObject* p, boost::python::type<long>);
BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type<long>);
long from_python(PyObject* p, boost::python::type<const long&>);
PyObject* to_python(unsigned long);
unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned long);
BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
unsigned long from_python(PyObject* p, boost::python::type<const unsigned long&>);
PyObject* to_python(int);
int from_python(PyObject*, boost::python::type<int>);
BOOST_PYTHON_DECL int from_python(PyObject*, boost::python::type<int>);
int from_python(PyObject*, boost::python::type<const int&>);
PyObject* to_python(unsigned int);
unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned int);
BOOST_PYTHON_DECL unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
unsigned int from_python(PyObject*, boost::python::type<const unsigned int&>);
PyObject* to_python(short);
short from_python(PyObject*, boost::python::type<short>);
BOOST_PYTHON_DECL short from_python(PyObject*, boost::python::type<short>);
short from_python(PyObject*, boost::python::type<const short&>);
PyObject* to_python(unsigned short);
unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned short);
BOOST_PYTHON_DECL unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
unsigned short from_python(PyObject*, boost::python::type<const unsigned short&>);
PyObject* to_python(char);
char from_python(PyObject*, boost::python::type<char>);
BOOST_PYTHON_DECL PyObject* to_python(char);
BOOST_PYTHON_DECL char from_python(PyObject*, boost::python::type<char>);
char from_python(PyObject*, boost::python::type<const char&>);
PyObject* to_python(signed char);
signed char from_python(PyObject*, boost::python::type<signed char>);
BOOST_PYTHON_DECL PyObject* to_python(signed char);
BOOST_PYTHON_DECL signed char from_python(PyObject*, boost::python::type<signed char>);
signed char from_python(PyObject*, boost::python::type<const signed char&>);
PyObject* to_python(unsigned char);
unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
BOOST_PYTHON_DECL PyObject* to_python(unsigned char);
BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
unsigned char from_python(PyObject*, boost::python::type<const unsigned char&>);
# ifndef BOOST_MSVC6_OR_EARLIER
PyObject* to_python(float);
float from_python(PyObject*, boost::python::type<float>);
float from_python(PyObject*, boost::python::type<const float&>);
PyObject* to_python(double);
double from_python(PyObject*, boost::python::type<double>);
# else
BOOST_PYTHON_DECL PyObject* to_python(float);
BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type<float>);
BOOST_PYTHON_DECL PyObject* to_python(double);
BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type<double>);
# endif
float from_python(PyObject*, boost::python::type<const float&>);
double from_python(PyObject*, boost::python::type<const double&>);
PyObject* to_python(bool);
bool from_python(PyObject*, boost::python::type<bool>);
BOOST_PYTHON_DECL bool from_python(PyObject*, boost::python::type<bool>);
bool from_python(PyObject*, boost::python::type<const bool&>);
PyObject* to_python(void);
void from_python(PyObject*, boost::python::type<void>);
BOOST_PYTHON_DECL PyObject* to_python(void);
BOOST_PYTHON_DECL void from_python(PyObject*, boost::python::type<void>);
PyObject* to_python(const char* s);
const char* from_python(PyObject*, boost::python::type<const char*>);
BOOST_PYTHON_DECL const char* from_python(PyObject*, boost::python::type<const char*>);
PyObject* to_python(const std::string& s);
std::string from_python(PyObject*, boost::python::type<std::string>);
BOOST_PYTHON_DECL PyObject* to_python(const std::string& s);
BOOST_PYTHON_DECL std::string from_python(PyObject*, boost::python::type<std::string>);
std::string from_python(PyObject*, boost::python::type<const std::string&>);
inline PyObject* to_python(const std::complex<float>& x)
@@ -294,22 +301,22 @@ inline PyObject* to_python(float f)
inline PyObject* to_python(long l)
{
return PyInt_FromLong(l);
return PyInt_FromLong(l);
}
inline PyObject* to_python(int x)
{
return PyInt_FromLong(x);
return PyInt_FromLong(x);
}
inline PyObject* to_python(short x)
{
return PyInt_FromLong(x);
return PyInt_FromLong(x);
}
inline PyObject* to_python(bool b)
{
return PyInt_FromLong(b);
return PyInt_FromLong(b);
}
inline PyObject* to_python(void)
@@ -319,7 +326,7 @@ inline PyObject* to_python(void)
inline PyObject* to_python(const char* s)
{
return PyString_FromString(s);
return PyString_FromString(s);
}
inline std::string from_python(PyObject* p, boost::python::type<const std::string&>)

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 {
@@ -169,6 +171,9 @@ struct export_converter_object_noncopyable : export_converter_object_base<T>
PyErr_SetString(PyExc_RuntimeError,
"to_python(const T&) converter not exported");
throw import_error();
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
return 0;
#endif
}
virtual T* from_python_Ts(PyObject* p, boost::python::type<T*> t) {
@@ -229,56 +234,56 @@ struct export_converter_object : export_converter_object_noncopyable<T>
}
};
namespace detail {
namespace detail
{
/* This class template is instantiated by import_converters<T>.
Its purpose is to import the converter_object via the Python API.
The actual import is only done once. The pointer to the
imported converter object is kept in the static data member
imported_converters.
*/
template <class T>
class import_extension_class
: public python_import_extension_class_converters<T>
{
public:
inline import_extension_class(const char* module, const char* py_class) {
m_module = module;
m_py_class = py_class;
}
*/
template <class T>
class import_extension_class
: public python_import_extension_class_converters<T>
{
public:
inline import_extension_class(const char* module, const char* py_class) {
m_module = module;
m_py_class = py_class;
}
static boost::python::export_converter_object_base<T>* get_converters();
static boost::python::export_converter_object_base<T>* get_converters();
private:
static std::string m_module;
static std::string m_py_class;
static boost::python::export_converter_object_base<T>* imported_converters;
};
private:
static std::string m_module;
static std::string m_py_class;
static boost::python::export_converter_object_base<T>* imported_converters;
};
template <class T> std::string import_extension_class<T>::m_module;
template <class T> std::string import_extension_class<T>::m_py_class;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::imported_converters = 0;
template <class T> std::string import_extension_class<T>::m_module;
template <class T> std::string import_extension_class<T>::m_py_class;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::imported_converters = 0;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::get_converters() {
if (imported_converters == 0) {
void* cobject
= import_converter_object(m_module, m_py_class,
converters_attribute_name);
imported_converters
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
check_export_converters_api(
export_converters_api_major,
export_converters_api_minor,
imported_converters->get_api_major(),
imported_converters->get_api_minor());
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::get_converters() {
if (imported_converters == 0) {
void* cobject
= import_converter_object(m_module, m_py_class,
converters_attribute_name);
imported_converters
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
check_export_converters_api(
export_converters_api_major,
export_converters_api_minor,
imported_converters->get_api_major(),
imported_converters->get_api_minor());
}
return imported_converters;
}
return imported_converters;
}
}}} // namespace boost::python::detail
namespace boost { namespace python {

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

@@ -57,10 +57,113 @@
# define BOOST_CSTD_ std
# endif
#if defined(_WIN32) || defined(__CYGWIN__)
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name()
# ifndef BOOST_PYTHON_MODULE_INIT
# if defined(_WIN32) || defined(__CYGWIN__)
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
# else
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name()
# endif
# endif
/*****************************************************************************
*
* Set up dll import/export options:
*
****************************************************************************/
// backwards compatibility:
#ifdef BOOST_PYTHON_STATIC_LIB
# define BOOST_PYTHON_STATIC_LINK
#endif
#if defined(__MWERKS__) \
|| (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730)
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
#endif
#if defined(__GNUC__)
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern
#endif
// Handle default cases
#ifndef BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
# ifdef _WIN32
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern
# else
# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
# endif
#endif
#ifndef BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
#endif
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32)
# if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_DECL __declspec(dllexport)
# define BOOST_PYTHON_BUILD_DLL
# else
# define BOOST_PYTHON_DECL __declspec(dllimport)
# endif
#endif
#ifndef BOOST_PYTHON_DECL
# define BOOST_PYTHON_DECL
#endif
#ifndef BOOST_PYTHON_DECL_TEMPLATE
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
# define BOOST_PYTHON_DECL_TEMPLATE BOOST_PYTHON_DECL
# else
# define BOOST_PYTHON_DECL_TEMPLATE
# endif
#endif
#if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
#else
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name()
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
#endif
# ifndef BOOST_PYTHON_EXPORT_TEMPLATE
# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template
# endif
# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL
// Borland C++ Fix/error check:
#if defined(__BORLANDC__)
# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
// problems with std::basic_string and dll RTL:
# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)
# ifdef BOOST_PYTHON_BUILD_DLL
# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL
# else
# pragma warn defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!
# endif
# endif
# ifndef _RTLDLL
// this is harmless for a static link:
# define _RWSTD_COMPILE_INSTANTIATE
# endif
# endif
//
// VCL support:
// if we're building a console app then there can't be any VCL (can there?)
# if !defined(__CONSOLE__) && !defined(_NO_VCL)
# define BOOST_PYTHON_USE_VCL
# endif
#endif
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
// Work around a compiler bug.
// boost::python::detail::function has to be seen by the compiler before the
// boost::function class template.
namespace boost { namespace python { namespace detail {
class function;
}}}
#endif
#endif // CONFIG_DWA052200_H_

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,26 +38,51 @@ template <class T> struct right_operand;
enum without_downcast_t { without_downcast };
namespace detail {
namespace detail
{
// forward declarations
class extension_instance;
class extension_class_base;
template <class T> class instance_holder;
template <class T, class U> class instance_value_holder;
template <class ref, class T> class instance_ptr_holder;
template <class Specified> struct operand_select;
class extension_instance;
class extension_class_base;
template <class T> class instance_holder;
template <class T, class U> class instance_value_holder;
template <class ref, class T> class instance_ptr_holder;
template <class Specified> struct operand_select;
template <long> struct choose_op;
template <long> struct choose_rop;
template <long> struct choose_unary_op;
template <long> struct define_operator;
meta_class<extension_instance>* extension_meta_class();
extension_instance* get_extension_instance(PyObject* p);
void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_class_object(const std::type_info&);
void report_released_smart_pointer(const std::type_info&);
class BOOST_PYTHON_DECL extension_instance : public instance
{
public:
extension_instance(PyTypeObject* class_);
~extension_instance();
void add_implementation(std::auto_ptr<instance_holder_base> holder);
typedef std::vector<instance_holder_base*> held_objects;
const held_objects& wrapped_objects() const
{ return m_wrapped_objects; }
private:
held_objects m_wrapped_objects;
};
} // namespace detail
# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t<detail::extension_instance>;
BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class<detail::extension_instance>;
# endif
namespace detail {
BOOST_PYTHON_DECL meta_class<extension_instance>* extension_meta_class();
BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p);
BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&);
BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&);
template <class T>
T* check_non_null(T* p)
@@ -71,7 +96,7 @@ template <class Held> class held_instance;
typedef void* (*conversion_function_ptr)(void*);
struct base_class_info
struct BOOST_PYTHON_DECL base_class_info
{
base_class_info(extension_class_base* t, conversion_function_ptr f)
:class_object(t), convert(f)
@@ -85,7 +110,7 @@ typedef base_class_info derived_class_info;
struct add_operator_base;
class extension_class_base : public class_t<extension_instance>
class BOOST_PYTHON_DECL extension_class_base : public class_t<extension_instance>
{
public:
extension_class_base(const char* name);
@@ -233,6 +258,9 @@ class python_extension_class_converters
}
boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
throw boost::python::argument_error();
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
return 0;
#endif
}
// Convert to T*
@@ -261,6 +289,9 @@ class python_extension_class_converters
}
boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
throw boost::python::argument_error();
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
return *(PtrType*)0;
#endif
}
// Extract from obj a reference to the PtrType object which is holding a
@@ -372,7 +403,7 @@ namespace detail {
template <class T> class instance_holder;
class read_only_setattr_function : public function
class BOOST_PYTHON_DECL read_only_setattr_function : public function
{
public:
read_only_setattr_function(const char* name);
@@ -696,30 +727,85 @@ class held_instance : public Held
public:
held_instance(PyObject*) : Held() {}
template <class A1>
held_instance(PyObject*, A1 a1) : Held(a1) {}
held_instance(PyObject*, A1 a1) : Held(
typename unwrap_parameter<A1>::type(a1)) {}
template <class A1, class A2>
held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {}
held_instance(PyObject*, A1 a1, A2 a2) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)) {}
template <class A1, class A2, class A3>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)) {}
template <class A1, class A2, class A3, class A4>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)) {}
template <class A1, class A2, class A3, class A4, class A5>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(a1, a2, a3, a4, a5, a6, a7, a8) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)
, typename unwrap_parameter<A8>::type(a8)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)
, typename unwrap_parameter<A8>::type(a8)
, typename unwrap_parameter<A9>::type(a9)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(
typename unwrap_parameter<A1>::type(a1)
, typename unwrap_parameter<A2>::type(a2)
, typename unwrap_parameter<A3>::type(a3)
, typename unwrap_parameter<A4>::type(a4)
, typename unwrap_parameter<A5>::type(a5)
, typename unwrap_parameter<A6>::type(a6)
, typename unwrap_parameter<A7>::type(a7)
, typename unwrap_parameter<A8>::type(a8)
, typename unwrap_parameter<A9>::type(a9)
, typename unwrap_parameter<A10>::type(a10)) {}
};
// Abstract base class for all obj holders. Base for template class
// instance_holder<>, below.
class instance_holder_base
class BOOST_PYTHON_DECL instance_holder_base
{
public:
virtual ~instance_holder_base() {}
@@ -807,21 +893,6 @@ class instance_ptr_holder : public instance_holder<HeldType>
PtrType m_ptr;
};
class extension_instance : public instance
{
public:
extension_instance(PyTypeObject* class_);
~extension_instance();
void add_implementation(std::auto_ptr<instance_holder_base> holder);
typedef std::vector<instance_holder_base*> held_objects;
const held_objects& wrapped_objects() const
{ return m_wrapped_objects; }
private:
held_objects m_wrapped_objects;
};
//
// Template function implementations
//

View File

@@ -29,7 +29,7 @@ class extension_instance;
// function --
// the common base class for all overloadable function and method objects
// supplied by the library.
class function : public python_object
class BOOST_PYTHON_DECL function : public python_object
{
public:
function();
@@ -59,13 +59,13 @@ class function : public python_object
template <class R, class F>
struct wrapped_function_pointer : function
{
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
wrapped_function_pointer(ptr_fun pf)
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
wrapped_function_pointer(ptr_fun pf)
: m_pf(pf) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const
PyObject* do_call(PyObject* args, PyObject* keywords) const
{
// This is where the boundary between the uniform Python function
// interface and the statically-checked C++ function interface is
@@ -77,7 +77,7 @@ struct wrapped_function_pointer : function
{ return typeid(F).name(); }
private:
const ptr_fun m_pf;
const ptr_fun m_pf;
};
// raw_arguments_function
@@ -87,13 +87,13 @@ struct wrapped_function_pointer : function
template <class Ret, class Args, class Keywords>
struct raw_arguments_function : function
{
typedef Ret (*ptr_fun)(Args, Keywords);
raw_arguments_function(ptr_fun pf)
typedef Ret (*ptr_fun)(Args, Keywords);
raw_arguments_function(ptr_fun pf)
: m_pf(pf) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const
PyObject* do_call(PyObject* args, PyObject* keywords) const
{
ref dict(keywords ?
ref(keywords, ref::increment_count) :
@@ -108,7 +108,7 @@ struct raw_arguments_function : function
{ return typeid(ptr_fun).name(); }
private:
const ptr_fun m_pf;
const ptr_fun m_pf;
};
// virtual_function<> --
@@ -127,19 +127,19 @@ template <class T, class R, class V, class D>
class virtual_function : public function
{
public:
virtual_function(V virtual_function_ptr, D default_implementation)
virtual_function(V virtual_function_ptr, D default_implementation)
: m_virtual_function_ptr(virtual_function_ptr),
m_default_implementation(default_implementation)
{}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const;
PyObject* do_call(PyObject* args, PyObject* keywords) const;
const char* description() const
{ return typeid(V).name(); }
private:
const V m_virtual_function_ptr;
const V m_virtual_function_ptr;
const D m_default_implementation;
};
@@ -160,7 +160,7 @@ template <class F>
inline function* new_wrapped_function(F pmf)
{
// Deduce the return type and pass it off to the helper function above
return new_wrapped_function_aux(return_value(pmf), pmf);
return new_wrapped_function_aux(return_value(pmf), pmf);
}
template <class R, class Args, class keywords>
@@ -201,7 +201,7 @@ inline function* new_virtual_function(
// the expression a.b where a is an instance or extension_instance object and b
// is a callable object not found in the obj namespace but on its class or
// a base class.
class bound_function : public python_object
class BOOST_PYTHON_DECL bound_function : public python_object
{
public:
static bound_function* create(const ref& target, const ref& fn);
@@ -220,7 +220,7 @@ class bound_function : public python_object
private: // data members for allocation/deallocation optimization
bound_function* m_free_list_link;
static bound_function* free_list;
static bound_function* free_list;
};
// Special functions designed to access data members of a wrapped C++ object.

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;
@@ -230,7 +278,7 @@ struct init_function
}
};
class init : public function
class BOOST_PYTHON_DECL init : public function
{
private: // override function hook
PyObject* do_call(PyObject* args, PyObject* keywords) const;

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

@@ -17,7 +17,7 @@ namespace boost { namespace python {
namespace detail {
// A stand-in for the built-in void. This one can be passed to functions and
// (under MSVC, which has a bug, be used as a default template type parameter).
struct void_t {};
struct BOOST_PYTHON_DECL void_t {};
}
// An envelope in which type information can be delivered for the purposes

View File

@@ -13,7 +13,7 @@
namespace boost { namespace python { namespace detail {
struct empty {};
struct BOOST_PYTHON_DECL empty {};
template <class Derived, class Base = empty>
struct singleton : Base
{

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,13 +31,9 @@
namespace boost { namespace python {
class string;
namespace detail {
class instance_holder_base;
class type_object_base : public python_type
class BOOST_PYTHON_DECL type_object_base : public python_type
{
public:
explicit type_object_base(PyTypeObject* type_type);
@@ -57,7 +53,11 @@ class type_object_base : public python_type
number_positive, number_absolute, number_nonzero, number_invert,
number_lshift, number_rshift, number_and, number_xor, number_or,
number_coerce, number_int, number_long, number_float, number_oct,
number_hex
number_hex, number_inplace_add, number_inplace_subtract,
number_inplace_multiply, number_inplace_divide,
number_inplace_remainder, number_inplace_power,
number_inplace_lshift, number_inplace_rshift,
number_inplace_and, number_inplace_or, number_inplace_xor
};
void enable(capability);
@@ -116,6 +116,18 @@ class type_object_base : public python_type
virtual PyObject* instance_number_oct(PyObject*) const;
virtual PyObject* instance_number_hex(PyObject*) const;
virtual PyObject* instance_number_inplace_add(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_and(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_or(PyObject*, PyObject*) const;
virtual PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const;
public: // Callbacks for rich comparisons
virtual PyObject* instance_lt(PyObject*, PyObject*) const;
virtual PyObject* instance_le(PyObject*, PyObject*) const;
@@ -311,7 +323,7 @@ PyObject* reprable<Base>::instance_repr(PyObject* obj) const
// memory. Reference counting is used to free unused memory.
// This is useful because method tables of related extension classes tend
// to be identical, so less memory is needed for them.
class shared_pod_manager
class BOOST_PYTHON_DECL shared_pod_manager
{
typedef std::pair<char*, std::size_t> holder;
typedef std::vector<holder> storage;
@@ -378,7 +390,7 @@ PyObject* reprable<Base>::instance_repr(PyObject* obj) const
};
void add_capability(type_object_base::capability capability,
BOOST_PYTHON_DECL void add_capability(type_object_base::capability capability,
PyTypeObject* dest);
// This macro gets the length of an array as a compile-time constant, and will

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

@@ -0,0 +1,39 @@
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#ifndef VOID_ADAPTOR_DWA20011112_HPP
# define VOID_ADAPTOR_DWA20011112_HPP
namespace boost { namespace python { namespace detail {
extern BOOST_PYTHON_DECL PyObject arbitrary_object;
template <class T>
struct void_adaptor
{
typedef PyObject* result_type;
void_adaptor(T const& f)
: m_f(f)
{}
PyObject* operator()() const
{
m_f();
return &arbitrary_object;
}
private:
T m_f;
};
template <class T>
void_adaptor<T> make_void_adaptor(T const& f)
{
return void_adaptor<T>(f);
}
}}} // namespace boost::python::detail
#endif // VOID_ADAPTOR_DWA20011112_HPP

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,35 +34,38 @@
// Some things we need in order to get Python.h to work with compilers other
// than MSVC on Win32
//
#if defined(_WIN32)
# ifdef __GNUC__
#if defined(_WIN32) || defined(__CYGWIN__)
# if defined(__GNUC__) && defined(__CYGWIN__)
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2
typedef int pid_t;
# define WORD_BIT 32
# define hypot _hypot
# include <stdio.h>
# if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2
# define HAVE_CLOCK
# define HAVE_STRFTIME
# define HAVE_STRERROR
# endif
# define NT_THREADS
# define WITH_THREAD
# ifndef NETSCAPE_PI
# define USE_SOCKET
# endif
# define WORD_BIT 32
# define hypot _hypot
# include <stdio.h>
# if PY_MAJOR_VERSION < 2
# define HAVE_CLOCK
# define HAVE_STRFTIME
# define HAVE_STRERROR
# endif
# define NT_THREADS
# if __GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3
# define WITH_THREAD
# endif
# ifndef NETSCAPE_PI
# define USE_SOCKET
# endif
# ifdef USE_DL_IMPORT
# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
# endif
# ifdef USE_DL_IMPORT
# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
# endif
# ifdef USE_DL_EXPORT
# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
# endif
# ifdef USE_DL_EXPORT
# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
# endif
# define HAVE_LONG_LONG 1
# define LONG_LONG long long
# define HAVE_LONG_LONG 1
# define LONG_LONG long long
# endif
# elif defined(__MWERKS__)
@@ -71,8 +74,25 @@ typedef int pid_t;
# define _MSC_VER 900
# endif
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
# include <config.h>
# else
# include <pyconfig.h>
# endif
# undef hypot // undo the evil #define left by Python.
# elif defined(__BORLANDC__)
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
# include <config.h>
# else
# include <pyconfig.h>
# endif
# undef HAVE_HYPOT
# define HAVE_HYPOT 1
# elif defined(_MSC_VER)
# include <limits> // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX
# ifdef __cplusplus
# include <limits> // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX
# endif
# endif
#endif // _WIN32
@@ -90,5 +110,11 @@ typedef int pid_t;
#if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2
# define PyObject_INIT(op, typeobj) \
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
#endif
#ifdef __MWERKS__
# pragma warn_possunwant off
#elif _MSC_VER
# pragma warning(disable:4786)
#endif

View File

@@ -9,20 +9,31 @@
#ifndef ERRORS_DWA052500_H_
# define ERRORS_DWA052500_H_
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/function.hpp>
namespace boost { namespace python {
struct error_already_set {};
struct argument_error : error_already_set {};
// Handles exceptions caught just before returning to Python code.
void handle_exception();
// Returns true iff an exception was caught.
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>);
template <class T>
bool handle_exception(T f)
{
return handle_exception_impl(function0<void>(boost::ref(f)));
}
BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x);
template <class T>
T* expect_non_null(T* x)
{
if (x == 0)
throw error_already_set();
return x;
return (T*)expect_non_null((PyObject*)x);
}
}} // namespace boost::python

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

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