mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 04:42:28 +00:00
Compare commits
164 Commits
svn-tags/m
...
boost-1.28
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4835a84482 | ||
|
|
c5e0d68304 | ||
|
|
56318c70db | ||
|
|
e84940515d | ||
|
|
29a611fa9c | ||
|
|
9a22b78ec6 | ||
|
|
f93969e629 | ||
|
|
5921d74a4b | ||
|
|
21e5bbe379 | ||
|
|
f8962b64d8 | ||
|
|
bd40528884 | ||
|
|
1de87b920c | ||
|
|
ae2b3bb60b | ||
|
|
a2a1a557f5 | ||
|
|
fff4cc8b0d | ||
|
|
aa0fc6dfe7 | ||
|
|
c639ac0c5a | ||
|
|
45aa77079d | ||
|
|
8e57090a75 | ||
|
|
e7cb8c8b4f | ||
|
|
57002aca36 | ||
|
|
5956d3ec77 | ||
|
|
2d522de701 | ||
|
|
aef987d832 | ||
|
|
c5d90745a0 | ||
|
|
1d160762b5 | ||
|
|
b45b9e5ccf | ||
|
|
4b9931c417 | ||
|
|
34424d7a00 | ||
|
|
7cd32fc4eb | ||
|
|
c9097566e2 | ||
|
|
e26556c631 | ||
|
|
bd32dce19a | ||
|
|
152a3f2e5f | ||
|
|
4fe6815062 | ||
|
|
525979afaa | ||
|
|
93a10f33d5 | ||
|
|
c9b4fb418a | ||
|
|
2151bf8f9a | ||
|
|
fa64ef6f00 | ||
|
|
a31c0e9082 | ||
|
|
365ce29761 | ||
|
|
93ca98d3a8 | ||
|
|
6e86a498ad | ||
|
|
94cfe30b77 | ||
|
|
cca3acc035 | ||
|
|
f0e3fd9e72 | ||
|
|
8388163aaf | ||
|
|
a203214ef9 | ||
|
|
4250893d2f | ||
|
|
0c1e2a7347 | ||
|
|
d5c35a1d83 | ||
|
|
722036f10e | ||
|
|
8eab74ea81 | ||
|
|
473d38c846 | ||
|
|
a9fb1b25a8 | ||
|
|
360dbd9e5e | ||
|
|
8c4f9d913d | ||
|
|
e4b1377b0e | ||
|
|
fc5e0fb012 | ||
|
|
9a140643c8 | ||
|
|
5fbba7bc01 | ||
|
|
4cf7ab3425 | ||
|
|
b7f93bd4ea | ||
|
|
962a08700e | ||
|
|
d23daf225d | ||
|
|
e5f2b0c0a9 | ||
|
|
6aa80b07e7 | ||
|
|
be0ae2389c | ||
|
|
7d8b6d149e | ||
|
|
a47fbc18f7 | ||
|
|
47ad802ab6 | ||
|
|
8a3e786294 | ||
|
|
4018b284e3 | ||
|
|
b704d42fe4 | ||
|
|
5dab2802b3 | ||
|
|
377fbed517 | ||
|
|
eab0a73f53 | ||
|
|
558170582a | ||
|
|
10ffaec730 | ||
|
|
f17876969d | ||
|
|
81777a29d5 | ||
|
|
3944786c13 | ||
|
|
af939fad66 | ||
|
|
79f8f3eb14 | ||
|
|
9137b38fb9 | ||
|
|
4bb5ee4b17 | ||
|
|
022c8502c0 | ||
|
|
b601ba55d0 | ||
|
|
8de3571aa8 | ||
|
|
5a6bc4404a | ||
|
|
17eb4a2660 | ||
|
|
81124780d0 | ||
|
|
aed7e14d4b | ||
|
|
6835c344eb | ||
|
|
0b965d1ee4 | ||
|
|
ed184acb40 | ||
|
|
7d7eac5030 | ||
|
|
68dbb13084 | ||
|
|
27d335ebe1 | ||
|
|
900e035412 | ||
|
|
bc552d326c | ||
|
|
7ffc983edd | ||
|
|
4a81d366bb | ||
|
|
383a51dde8 | ||
|
|
2a6060e425 | ||
|
|
576269dae9 | ||
|
|
ac34e0e108 | ||
|
|
11bd4c3223 | ||
|
|
8d88a92fe4 | ||
|
|
6004a35e23 | ||
|
|
a3a633242f | ||
|
|
4ad579d4ad | ||
|
|
2666c7312f | ||
|
|
516f30a307 | ||
|
|
9d3d50c654 | ||
|
|
453fbbed1b | ||
|
|
0ce8ab7bce | ||
|
|
d72128107e | ||
|
|
3b8dc924c3 | ||
|
|
08ac287726 | ||
|
|
a8d6f40794 | ||
|
|
a2071feeb1 | ||
|
|
aa705b07f3 | ||
|
|
fbbc1981ca | ||
|
|
6528bd0e4f | ||
|
|
81a07899ae | ||
|
|
c18d8fa967 | ||
|
|
3caa91cc36 | ||
|
|
0bdf3542e4 | ||
|
|
23769371bc | ||
|
|
bccd854676 | ||
|
|
2fa0910547 | ||
|
|
c170b1b83e | ||
|
|
be6016a972 | ||
|
|
a56f66e721 | ||
|
|
e589d7f1e1 | ||
|
|
948cde1a31 | ||
|
|
3447aaa8c6 | ||
|
|
688c64ce21 | ||
|
|
7eb42dc36b | ||
|
|
ae1c1b3a47 | ||
|
|
74078552df | ||
|
|
5da8206915 | ||
|
|
f271726cd8 | ||
|
|
22f6612354 | ||
|
|
74fe5bc4dd | ||
|
|
69d7011baf | ||
|
|
0301d4462b | ||
|
|
7c009e2443 | ||
|
|
a16d9f91ee | ||
|
|
7e76c85535 | ||
|
|
3054694726 | ||
|
|
a25021d215 | ||
|
|
532833ff70 | ||
|
|
e79a66851c | ||
|
|
97825fb2c7 | ||
|
|
bd9df7e619 | ||
|
|
087f09e9a6 | ||
|
|
1257b32464 | ||
|
|
a437af44f8 | ||
|
|
9644610e04 | ||
|
|
71cbe1cf50 | ||
|
|
edad2a1ee5 |
104
Jamfile
104
Jamfile
@@ -4,93 +4,21 @@ subproject libs/python ;
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
|
||||
{
|
||||
local BOOST_PYTHON_V2_PROPERTIES
|
||||
= $(PYTHON_PROPERTIES)
|
||||
<metrowerks><*><cxxflags>"-inline deferred"
|
||||
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
|
||||
<define>BOOST_PYTHON_DYNAMIC_LIB
|
||||
<define>BOOST_PYTHON_V2
|
||||
;
|
||||
|
||||
local gcc-release-properties
|
||||
= <optimization>speed <cxxflags>-fomit-frame-pointer
|
||||
<inlining>on <cxxflags>-foptimize-sibling-calls
|
||||
;
|
||||
|
||||
local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) <gcc><release>$(gcc-release-properties)
|
||||
;
|
||||
|
||||
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
|
||||
:
|
||||
$(BOOST_PYTHON_V2_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
;
|
||||
|
||||
# -------- general test -------
|
||||
extension m1 : test/m1.cpp <dll>bpl
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
extension m2 : test/m2.cpp <dll>bpl
|
||||
:
|
||||
: ;
|
||||
|
||||
boost-python-runtest try : test/newtest.py <pyd>m1 <pyd>m2 : : ;
|
||||
|
||||
# ----------- builtin converters -----------
|
||||
|
||||
extension builtin_converters_ext : test/test_builtin_converters.cpp <dll>bpl
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
boost-python-runtest test_builtin_converters : test/test_builtin_converters.py
|
||||
<pyd>builtin_converters_ext
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
# ----------- pointer adoption -----------
|
||||
|
||||
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <dll>bpl
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
|
||||
<pyd>test_pointer_adoption_ext
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
unit-test indirect_traits_test
|
||||
: test/indirect_traits_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
unit-test destroy_test
|
||||
: test/destroy_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
unit-test pointer_type_id_test
|
||||
: test/pointer_type_id_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
|
||||
unit-test select_from_python_test
|
||||
: test/select_from_python_test.cpp
|
||||
dll bpl
|
||||
:
|
||||
src/converter/from_python.cpp
|
||||
src/converter/registry.cpp
|
||||
src/converter/type_id.cpp
|
||||
src/converter/registry.cpp # MWerks needs this for some reason
|
||||
: $(PYTHON_PROPERTIES)
|
||||
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
|
||||
src/converter/callback.cpp
|
||||
:
|
||||
$(BOOST_PYTHON_V2_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
;
|
||||
|
||||
|
||||
@@ -61,6 +61,13 @@ subproject libs/python/build ;
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
# This nasty hack works with versions of Python 1.5.2 -> 2.2 to avoid
|
||||
# building any Python stuff if there's no installation.
|
||||
SEARCH on <find-python-install>__init__.py = $(PYTHON_STDLIB_PATH)/test $(SUBDIR) ;
|
||||
include <find-python-install>__init__.py ;
|
||||
if ! $(gNO_PYTHON_INSTALL)
|
||||
{
|
||||
|
||||
local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) <define>BOOST_PYTHON_DYNAMIC_LIB ;
|
||||
|
||||
#######################
|
||||
@@ -82,11 +89,13 @@ local CPP_SOURCES =
|
||||
;
|
||||
|
||||
lib boost_python_static : ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<define>BOOST_PYTHON_STATIC_LIB=1
|
||||
$(PYTHON_PROPERTIES) ;
|
||||
<define>BOOST_PYTHON_STATIC_LIB=1
|
||||
[ difference $(PYTHON_PROPERTIES) : <define>BOOST_PYTHON_DYNAMIC_LIB ]
|
||||
: <suppress>true # don't build this unless the user asks for it by name
|
||||
;
|
||||
|
||||
dll boost_python
|
||||
# $(SUFDLL[1])
|
||||
@@ -95,10 +104,17 @@ dll boost_python
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
<runtime-link>dynamic
|
||||
<define>BOOST_PYTHON_HAS_DLL_RUNTIME=1
|
||||
$(PYTHON_PROPERTIES)
|
||||
;
|
||||
|
||||
stage bin-stage : <dll>boost_python
|
||||
:
|
||||
<tag><debug>"_debug"
|
||||
<tag><debug-python>"_pydebug"
|
||||
:
|
||||
debug release
|
||||
;
|
||||
|
||||
############# comprehensive module and test ###########
|
||||
bpl-test boost_python_test
|
||||
: ../test/comprehensive.cpp ;
|
||||
@@ -114,7 +130,7 @@ rule boost-python-example-runtest ( name )
|
||||
: ../example/$(name).cpp ;
|
||||
|
||||
boost-python-runtest $(name)
|
||||
: ../example/test_$(name).py <pyd>$(name) ;
|
||||
: ../example/test_$(name).py <pyd>$(name) <dll>boost_python ;
|
||||
}
|
||||
|
||||
|
||||
@@ -154,3 +170,4 @@ boost-python-multi-example-runtest ivect2 : ivect dvect ;
|
||||
boost-python-multi-example-runtest
|
||||
noncopyable : noncopyable_import noncopyable_export ;
|
||||
|
||||
}
|
||||
22
build/__init__.py
Normal file
22
build/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# Dummy file actually to be included by Jam when the python headers
|
||||
# can't be found
|
||||
|
||||
if ! $(gNO_PYTHON_INSTALL)
|
||||
{
|
||||
ECHO "---------------------------------------------------------------------" ;
|
||||
ECHO skipping Boost.Python library build ;
|
||||
ECHO You can configure the location of your python installation, by setting: ;
|
||||
ECHO "PYTHON_ROOT - currently" \"$(PYTHON_ROOT:J=" ")\" ;
|
||||
ECHO "PYTHON_VERSION - The 2-part python Major.Minor version number (e.g." ;
|
||||
ECHO " \"2.2\", NOT \"2.2.1\") - currently" \"$(PYTHON_VERSION)\" ;
|
||||
ECHO ;
|
||||
ECHO "The following are automatically configured from PYTHON_ROOT if not" ;
|
||||
ECHO "otherwise set:" ;
|
||||
ECHO " PYTHON_INCLUDES - path to Python #include directories; currently" \"$(PYTHON_INCLUDES:J=" ")\" ;
|
||||
ECHO " PYTHON_LIB_PATH - path to Python library; currently" ;
|
||||
ECHO " " \"$(PYTHON_LIB_PATH:J=" ")\" ;
|
||||
ECHO " PYTHON_STDLIB_PATH - path to Python standard library modules; currently" ;
|
||||
ECHO " " \"$(PYTHON_STDLIB_PATH:J=" ")\" ;
|
||||
ECHO "---------------------------------------------------------------------" ;
|
||||
}
|
||||
gNO_PYTHON_INSTALL ?= true ;
|
||||
@@ -1,241 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="bpl_static" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=bpl_static - Win32 DebugPython
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "bpl_static.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "bpl_static.mak" CFG="bpl_static - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "bpl_static - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "bpl_static - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "bpl_static - Win32 DebugPython" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "bpl_static - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /WX /GR /GX /O2 /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "bpl_static - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "bpl_static - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "bpl_static___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "bpl_static___Win32_DebugPython"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "bpl_static - Win32 Release"
|
||||
# Name "bpl_static - Win32 Debug"
|
||||
# Name "bpl_static - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\classes.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\conversions.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\extension_class.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\functions.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\init_function.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\module_builder.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\objects.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\types.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\base_object.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\callback.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\caller.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\cast.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\class_builder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\classes.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\config.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\conversions.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\errors.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\extension_class.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\functions.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\init_function.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\module_builder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\none.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\objects.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\operators.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\reference.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\signatures.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\singleton.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\types.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\wrap_python.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
108
build/build.dsw
108
build/build.dsw
@@ -1,108 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "bpl_static"=.\bpl_static.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "example1"=.\example1\example1.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "getting_started1"=.\getting_started1\getting_started1.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "getting_started2"=.\getting_started2\getting_started2.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
getting_started2
|
||||
.\getting_started2
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "rwgk1"=.\rwgk1\rwgk1.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "test"=.\test\test.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
BIN
build/build.opt
BIN
build/build.opt
Binary file not shown.
@@ -1,136 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="example1" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=example1 - Win32 DebugPython
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "example1.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "example1.mak" CFG="example1 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "example1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "example1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "example1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "example1 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/hello.dll" /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "example1 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "example1 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "example1___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "example1___Win32_DebugPython"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/hello_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "example1 - Win32 Release"
|
||||
# Name "example1 - Win32 Debug"
|
||||
# Name "example1 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\example1.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,136 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="getting_started1" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=getting_started1 - Win32 DebugPython
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "getting_started1.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "getting_started1.mak" CFG="getting_started1 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "getting_started1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=xicl6.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "getting_started1 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started1 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GR /GX /ZI /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started1 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "DebugPython"
|
||||
# PROP BASE Intermediate_Dir "DebugPython"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /pdb:"DebugPython/boost_python_test_d.pdb" /debug /machine:I386 /out:"DebugPython/getting_started1_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "getting_started1 - Win32 Release"
|
||||
# Name "getting_started1 - Win32 Debug"
|
||||
# Name "getting_started1 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\getting_started1.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,135 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="getting_started2" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=getting_started2 - Win32 DebugPython
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "getting_started2.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "getting_started2.mak" CFG="getting_started2 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "getting_started2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started2 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "getting_started2"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=xicl6.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "getting_started2 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started2 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started2 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP Intermediate_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"DebugPython/getting_started2_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\pcbuild"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "getting_started2 - Win32 Release"
|
||||
# Name "getting_started2 - Win32 Debug"
|
||||
# Name "getting_started2 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\getting_started2.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,135 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="rwgk1" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=rwgk1 - Win32 DebugPython
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "rwgk1.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "rwgk1.mak" CFG="rwgk1 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "rwgk1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "rwgk1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "rwgk1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "rwgk1 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "rwgk1 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "rwgk1 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "rwgk1___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "rwgk1___Win32_DebugPython"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/rwgk1_d.dll" /pdbtype:sept /libpath:"C:\tools\python\src\PCbuild"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "rwgk1 - Win32 Release"
|
||||
# Name "rwgk1 - Win32 Debug"
|
||||
# Name "rwgk1 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\rwgk1.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,145 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=test - Win32 DebugPython
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "test.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "test - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "test - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /Zm200 /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/boost_python_test.dll" /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "test - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/boost_python_test.dll" /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "test - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "test___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "test___Win32_DebugPython"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# SUBTRACT BASE LINK32 /pdb:none
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/boost_python_test_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "test - Win32 Release"
|
||||
# Name "test - Win32 Debug"
|
||||
# Name "test - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\test\comprehensive.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\test\comprehensive.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,5 +1,9 @@
|
||||
# Usage:
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Adjust the pathnames below.
|
||||
#
|
||||
# make copy Copy the sources and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
|
||||
@@ -9,172 +9,214 @@
|
||||
"../../../c++boost.gif" alt="c++boost.gif (8819 bytes)">Building an
|
||||
Extension Module</h1>
|
||||
|
||||
<p>The build process for Boost is currently undergoing some evolution,
|
||||
and, it is to be hoped, improvement. The following facts may help:
|
||||
<h2>Building Boost.Python</h2>
|
||||
|
||||
<hr>
|
||||
Makefiles for various platforms and a Visual Studio project
|
||||
reside in the Boost subdirectory <tt>libs/python/build</tt>.
|
||||
Build targets include:
|
||||
<p>Every Boost.Python extension module must be linked with the
|
||||
<code>boost_python</code> shared library. To build
|
||||
<code>boost_python</code>, use <a
|
||||
href="../../../tools/build/index.html">Boost.Build</a> in the
|
||||
usual way from the <code>libs/python/build</code> subdirectory
|
||||
of your boost installation (if you have already built boost from
|
||||
the top level this may have no effect, since the work is already
|
||||
done).
|
||||
|
||||
<h3>Configuration</h3>
|
||||
You may need to configure the following variables to point Boost.Build at your Python installation:
|
||||
|
||||
<table border="1">
|
||||
<tr><th>Variable Name <th>Semantics <th>Default <th>Notes
|
||||
<tr>
|
||||
<td><code>PYTHON_ROOT</code>
|
||||
<td>The root directory of your Python installation
|
||||
<td>Windows: <code>c:/tools/python</code>
|
||||
Unix: <code>/usr/local</code>
|
||||
<td>On Unix, this is the <code>--with-prefix=</code> directory
|
||||
used to configure Python
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_VERSION</code>
|
||||
<td>The The 2-part python Major.Minor version number
|
||||
<td>Windows: <code>2.1</code>
|
||||
Unix: <code>1.5</code>
|
||||
<td>Be sure not to include a third number, e.g. <b>not</b>
|
||||
"<code>2.2.1</code>", even if that's the version you
|
||||
have.
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_INCLUDES</code>
|
||||
<td>path to Python <code>#include</code> directories
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code>
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_LIB_PATH</code>
|
||||
<td>path to Python library object.
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code>
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_STDLIB_PATH</code>
|
||||
<td>path to Python standard library modules
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code>
|
||||
|
||||
<tr>
|
||||
<td><code>CYGWIN_ROOT</code>
|
||||
<td>path to the user's Cygwin installation
|
||||
<td>
|
||||
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the following two settings are
|
||||
useful when building with multiple toolsets on Windows, since
|
||||
Cygwin requires a different build of Python.
|
||||
|
||||
<tr>
|
||||
<td><code>GCC_PYTHON_ROOT</code>
|
||||
<td>path to the user's Cygwin Python installation
|
||||
<td><code>$(CYGWIN_ROOT)/usr/local</code>
|
||||
<td><a href="http://www.cygwin.com">Cygwin</a> only
|
||||
|
||||
<tr>
|
||||
<td><code>GCC_DEBUG_PYTHON_ROOT</code>
|
||||
<td>path to the user's Cygwin <code><a
|
||||
href="#variants">pydebug</a></code> build
|
||||
<td><code>$(CYGWIN_ROOT)/usr/local/pydebug</code>
|
||||
<td><a href="http://www.cygwin.com">Cygwin</a> only
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Results</h3>
|
||||
<p>The build process will create a
|
||||
<code>libs/python/build/bin-stage</code> subdirectory of the
|
||||
boost root (or of <code>$(ALL_LOCATE_TARGET)</code>,
|
||||
if you have set that variable), containing the built
|
||||
libraries. The libraries are actually built to unique
|
||||
directories for each toolset and variant elsewhere in the
|
||||
filesystem, and copied to the
|
||||
<code>bin-stage</code> directory as a convenience, so if you
|
||||
build with multiple toolsets at once, the product of later
|
||||
toolsets will overwrite that of earlier toolsets in
|
||||
<code>bin-stage</code>.
|
||||
|
||||
<h3>Testing</h3>
|
||||
<p>To build and test Boost.Python from within the
|
||||
<code>libs/python/build</code> directory, invoke
|
||||
<blockquote>
|
||||
<pre>
|
||||
bjam -sTOOLS=<i><a href="../../../tools/build/index.html#Tools">toolset</a></i> test
|
||||
</pre>
|
||||
</blockquote>
|
||||
This will
|
||||
update all of the Boost.Python v1 test and example targets. The tests
|
||||
are relatively quiet by default. To get more-verbose output, you might try
|
||||
<blockquote>
|
||||
<pre>
|
||||
bjam -sTOOLS=<i><a href="../../../tools/build/index.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
|
||||
</pre>
|
||||
</blockquote>
|
||||
which will print each test's Python code with the expected output as
|
||||
it passes.
|
||||
|
||||
<h2>Building your Extension Module</h2>
|
||||
|
||||
Though there are other approaches, the easiest way to build an
|
||||
extension module using Boost.Python is with Boost.Build. Until
|
||||
Boost.Build v2 is released, cross-project build dependencies are
|
||||
not supported, so it works most smoothly if you add a new
|
||||
subproject to your boost installation. The
|
||||
<code>libs/python/example</code> subdirectory of your boost
|
||||
installation contains a minimal example (along with many extra
|
||||
sources). To copy the example subproject:
|
||||
|
||||
<ol>
|
||||
<li>Create a new subdirectory in, <code>libs/python</code>, say
|
||||
<code>libs/python/my_project</code>.
|
||||
|
||||
<li>Copy <code><a
|
||||
href="../example/Jamfile">libs/python/example/Jamfile</a></code>
|
||||
to your new directory.
|
||||
|
||||
<li>Edit the Jamfile as appropriate for your project. You'll
|
||||
want to change the "<code>subproject</code>" rule
|
||||
invocation at the top, and the names of some of the source files
|
||||
and/or targets.
|
||||
|
||||
</ol>
|
||||
|
||||
If you can't modify or copy your boost installation, the
|
||||
alternative is to create your own Boost.Build project. A similar
|
||||
example you can use as a starting point is available in <code><a
|
||||
href="../example/project.zip">this archive</a></code>. You'll
|
||||
need to edit the Jamfile and Jamrules files, depending on the
|
||||
relative location of your Boost installation and the new
|
||||
project. Note that automatic testing of extension modules is not
|
||||
available in this configuration.
|
||||
|
||||
<h2><a name="variants">Build Variants</a></h2>
|
||||
|
||||
Three <a
|
||||
href="../../../tools/build/build_system.htm#variants">variant</a>
|
||||
configurations of all python-related targets are supported, and
|
||||
can be selected by setting the <code><a
|
||||
href="../../../tools/build/build_system.htm#user_globals">BUILD</a></code>
|
||||
variable:
|
||||
|
||||
<ul>
|
||||
<li>The <tt>boost_python</tt> library for static linking with your
|
||||
extension module. On the various Unices, this library will be
|
||||
called <tt>libboost_python.a</tt>. When using Visual C++, the
|
||||
library will be called <tt>boost_python.lib</tt>.
|
||||
<li><code>release</code> (optimization, <tt>-DNDEBUG</tt>)
|
||||
|
||||
<p>
|
||||
<li>A comprehensive test of Boost.Python features. This test builds
|
||||
a Boost.Python extension module, then runs Python to import the
|
||||
module, and runs a series of tests on it using <tt><a href=
|
||||
"../test/doctest.py">doctest</a></tt>. Source code for the module
|
||||
and tests is available in the Boost subdirectory
|
||||
<tt>libs/python/test</tt>.
|
||||
<li><code>debug</code> (no optimization <tt>-D_DEBUG</tt>)
|
||||
|
||||
<p>
|
||||
<li>Various examples from the Boost subdirectory
|
||||
<tt>libs/python/example</tt>.
|
||||
All these examples include a doctest modeled
|
||||
on the comprehensive test above.
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
There is a group of makefiles with support for simultaneous
|
||||
compilation on multiple platforms and a consistent set of
|
||||
features that build the <tt>boost_python</tt> library for static
|
||||
linking, the comprehensive test, and all examples in
|
||||
<tt>libs/python/example</tt>:
|
||||
|
||||
<ul>
|
||||
<li><a href="../build/vc60.mak">vc60.mak</a>:
|
||||
Visual C++ 6.0 Service Pack 4
|
||||
|
||||
<li><a href="../build/mingw32.mak">mingw32.mak</a>:
|
||||
mingw32 (Win32-targeted) gcc 2.95.2
|
||||
|
||||
<li><a href="../build/linux_gcc.mak">linux_gcc.mak</a>:
|
||||
gcc 2.95.2 on Linux/Unix
|
||||
|
||||
<li><a href="../build/tru64_cxx.mak">tru64_cxx.mak</a>:
|
||||
Compaq Alpha using the Compaq cxx compiler
|
||||
|
||||
<li><a href="../build/irix_CC.mak">irix_CC.mak</a>:
|
||||
Silicon Graphics IRIX 6.5 CC compiler
|
||||
|
||||
</ul>
|
||||
<a href="http://cctbx.sourceforge.net/page_installation_adv.html#installation_boost_python"
|
||||
>Usage of these makefiles is described here.</a>
|
||||
|
||||
<hr>
|
||||
There is another group of makefiles for GNU make.
|
||||
These makefiles are less redundant than the makefiles
|
||||
in the group above,
|
||||
but the list of compilation targets is not as complete
|
||||
and there is no support for simultaneous compilation
|
||||
on multiple platforms.
|
||||
|
||||
<ul>
|
||||
<li><a href="../build/como.mak">como.mak</a>:
|
||||
Comeau C++ on Linux
|
||||
|
||||
<li><a href="../build/gcc.mak">gcc.mak</a>:
|
||||
GCC on Linux/Unix.
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
A project workspace for Microsoft Visual Studio is provided at <tt><a
|
||||
href="../build/build.dsw">libs/python/build/build.dsw</a></tt>. The
|
||||
include paths for this project may need to be changed for your
|
||||
installation. They currently assume that python has been installed at
|
||||
<tt>c:\tools\python</tt>. Three configurations of all targets are
|
||||
supported:
|
||||
|
||||
<ul>
|
||||
<li>Release (optimization, <tt>-DNDEBUG</tt>)
|
||||
|
||||
<li>Debug (no optimization <tt>-D_DEBUG</tt>)
|
||||
|
||||
<li>DebugPython (no optimization, <tt>-D_DEBUG
|
||||
<li><code>debug-python</code> (no optimization, <tt>-D_DEBUG
|
||||
-DBOOST_DEBUG_PYTHON</tt>)
|
||||
</ul>
|
||||
|
||||
<p>When extension modules are built with Visual C++ using
|
||||
<p>The first two variants of the <code>boost_python</code>
|
||||
library are built by default, and are compatible with the
|
||||
default Python distribution. The <code>debug-python</code>
|
||||
variant corresponds to a specially-built debugging version of
|
||||
Python. On Unix platforms, this python is built by adding
|
||||
<code>--with-pydebug</code> when configuring the Python
|
||||
build. On Windows, the debugging version of Python is generated
|
||||
by the "Win32 Debug" target of the
|
||||
<code>PCBuild.dsw</code> Visual C++ 6.0 project in the
|
||||
<code>PCBuild</code> subdirectory of your Python distribution.
|
||||
|
||||
Extension modules built with Python debugging enabled are <b>not
|
||||
link-compatible</b> with a non-debug build of Python. Since few
|
||||
people actually have a debug build of Python (it doesn't come
|
||||
with the standard distribution), the normal
|
||||
<code>debug</code> variant builds modules which are compatible
|
||||
with ordinary Python.
|
||||
|
||||
|
||||
<p>On many windows compilers, when extension modules are built
|
||||
with
|
||||
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> linking with a
|
||||
special debugging version of the Python DLL. Since this debug DLL
|
||||
isn't supplied with the default Python installation for Windows,
|
||||
Boost.Python uses <tt><a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
|
||||
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
|
||||
<tt>#include</tt>d.
|
||||
<tt>#include</tt>d - unless <code>BOOST_DEBUG_PYTHON</code> is defined.
|
||||
|
||||
<p>If you want the extra runtime checks available with the debugging
|
||||
version of the library, <tt>#define BOOST_DEBUG_PYTHON</tt> to
|
||||
re-enable library forcing, and link with the DebugPython version of
|
||||
<tt>boost_python.lib</tt>. You'll need to get the debugging version
|
||||
of the Python executable (<tt>python_d.exe</tt>) and DLL
|
||||
(<tt>python20_d.dll</tt> or <tt>python15_d.dll</tt>). The Python
|
||||
sources include project files for building these. If you <a href=
|
||||
"http://www.python.org">download</a> them, change the name of the
|
||||
top-level directory to <tt>src</tt>, and install it under
|
||||
<tt>c:\tools\python</tt>, the workspace supplied by Boost.Python will
|
||||
be able to use it without modification. Just open
|
||||
<tt>c:\tools\python\src\pcbuild\pcbuild.dsw</tt> and invoke "build
|
||||
all" to generate all the debugging targets.
|
||||
<p>If you want the extra runtime checks available with the
|
||||
debugging version of the library, <tt>#define
|
||||
BOOST_DEBUG_PYTHON</tt> to re-enable python debuggin, and link
|
||||
with the <code>debug-python</code> variant of
|
||||
<tt>boost_python</tt>.
|
||||
|
||||
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that
|
||||
any source files <tt>#include <<a href=
|
||||
any source files in your extension module <tt>#include <<a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>></tt>
|
||||
instead of the usual <tt>Python.h</tt>, or you will have link
|
||||
incompatibilities.<br>
|
||||
|
||||
<hr>
|
||||
If your platform isn't directly supported, you can build a static
|
||||
library from the following source files (in the Boost subdirectory
|
||||
<tt>libs/python/src</tt>), or compile them directly and link the
|
||||
resulting objects into your extension module:
|
||||
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../../../libs/python/src/classes.cpp">classes.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/conversions.cpp">conversions.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/cross_module.cpp">cross_module.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/extension_class.cpp">extension_class.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/functions.cpp">functions.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/init_function.cpp">init_function.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/module_builder.cpp">module_builder.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/objects.cpp">objects.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/types.cpp">types.cpp</a>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
Next: <a href="enums.html">Wrapping Enums</a> Previous: <a href=
|
||||
"under-the-hood.html">A Peek Under the Hood</a> Up: <a href=
|
||||
"index.html">Top</a>
|
||||
|
||||
<hr>
|
||||
<p>© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
<p>© Copyright David Abrahams 2002. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as is'' without
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
|
||||
<p>Updated: Apr 17, 2001 (R.W. Grosse-Kunstleve)
|
||||
<p>Updated: May 15, 2002 (David Abrahams)
|
||||
</div>
|
||||
|
||||
133
doc/index.html
133
doc/index.html
@@ -16,62 +16,101 @@
|
||||
intrusive on your C++ design. In most cases, you should not have to alter
|
||||
your C++ classes in any way in order to use them with Boost.Python. The system
|
||||
<em>should</em> simply ``reflect'' your C++ classes and functions into
|
||||
Python. The major features of Boost.Python include support for:
|
||||
<ul>
|
||||
<li><a href="inheritance.html">Subclassing extension types in Python</a>
|
||||
<li><a href="overriding.html">Overriding virtual functions in Python</a>
|
||||
<li><a href="overloading.html">[Member] function Overloading</a>
|
||||
<li><a href="special.html#numeric_auto">Automatic wrapping of numeric operators</a>
|
||||
</ul>
|
||||
among others.
|
||||
Python.
|
||||
|
||||
<p>
|
||||
|
||||
<table border="1">
|
||||
<tr><td> <b>Note:</b> this is the last official release of
|
||||
Boost.Python v1. Development of this version of the library has
|
||||
stopped; it will be retired soon in favor of the redesigned and
|
||||
improved version 2. A summary of the development goals is available on
|
||||
the Python <a href="http://www.python.org/sigs/c++-sig/">C++-sig</a>
|
||||
page, which also serves as a mailing list for users of both versions
|
||||
of the library. A preview of the v2 documentation is available <a
|
||||
href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/index.html?rev=HEAD&content-type=text/html">here</a>,
|
||||
and instructions for getting started with a prerelease are available
|
||||
upon request.
|
||||
</table>
|
||||
|
||||
<h2>Supported Platforms</h2>
|
||||
<p>Boost.Python is known to have been tested in the following configurations:
|
||||
<p>Boost.Python is known to have been tested
|
||||
against <a href="http://www.python/org/2.2.1">Python 2.2.1</a> using
|
||||
the following compilers:
|
||||
|
||||
<ul>
|
||||
<li>Against Python 2.0 using the following compiler/library combinations:
|
||||
<ul>
|
||||
<li><a
|
||||
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>
|
||||
with the native library.
|
||||
href="http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/default.asp">MSVC++6sp5</a>.
|
||||
All tests pass.
|
||||
|
||||
<li>An upcoming release of <a
|
||||
href="http://www.metrowerks.com/products/windows/">Metrowerks
|
||||
CodeWarrior Pro6 for Windows</a> with the native library (the first
|
||||
release has a bug that's fatal to Boost.Python)
|
||||
<li><a
|
||||
href="http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/default.asp">MSVC++6sp5</a>
|
||||
with <a href="http://www.stlport.org">STLPort</a>-4.5.3. A compiler bug interferes with
|
||||
<a
|
||||
href="../example/simple_vector.cpp">libs/python/example/simple_vector.cpp</a>. All
|
||||
other tests pass.
|
||||
|
||||
<li><a
|
||||
<p>
|
||||
<li><a href="http://msdn.microsoft.com/visualc/">MSVC++7 (Visual
|
||||
Studio .NET)</a>. All tests pass.
|
||||
|
||||
<p>
|
||||
<li><a href="http://www.metrowerks.com/products/windows/">Metrowerks
|
||||
CodeWarrior Pro7.2 and Pro7.0 for Windows</a>. All tests pass.
|
||||
|
||||
<p>
|
||||
<li><a href="http://gcc.gnu.org">GCC 3.0.4</a> under <a
|
||||
href="http://www.cygwin.com">Cygwin</a> and
|
||||
<a href="http://www.redhat.com/">RedHat Linux 7.1</a>.
|
||||
All tests pass.
|
||||
|
||||
<p>
|
||||
<li>Compaq C++ V6.2-024 for Digital UNIX (an <a
|
||||
href="http://www.edg.com/">EDG</a>-based compiler).
|
||||
All tests pass.<br>
|
||||
Note that the Boost.Compatibility
|
||||
library must be included (see e.g. tru64_cxx.mak in the build
|
||||
directory).
|
||||
|
||||
<p>
|
||||
<li>Silicon Graphics MIPSpro Version 7.3.1.2m (an <a
|
||||
href="http://www.edg.com/">EDG</a>-based compiler).
|
||||
All tests pass.<br>
|
||||
Note that the Boost.Compatibility
|
||||
library must be included (see e.g. irix_CC.mak in the build
|
||||
directory).
|
||||
|
||||
<p>
|
||||
<li><a href="http://gcc.gnu.org">GCC 2.95.2</a> under <a
|
||||
href="http://www.mingw.org">MinGW</a> and <a
|
||||
href="http://www.redhat.com/">RedHat Linux 7.1</a>.
|
||||
Compilation succeeds, but some tests fail at runtime due to
|
||||
exception handling bugs. It is therefore highly recommended
|
||||
to use GCC 3.0.4 instead.
|
||||
|
||||
<p>
|
||||
<li><a
|
||||
href="http://developer.intel.com/software/products/compilers/c50/">Intel
|
||||
C++ 5.0</a>. Compilation succeeds, but tests <font
|
||||
color="#FF0000"><b>FAILED at runtime</b></font> due to a bug in its
|
||||
exception-handling implementation.
|
||||
C++ 6.0</a> beta: Comprehensive test fails to link due to a
|
||||
linker bug. Other tests seem to work.
|
||||
|
||||
<p>
|
||||
<li><a
|
||||
href="http://developer.intel.com/software/products/compilers/c50/">Intel
|
||||
C++ 5.0</a> Comprehensive test fails at runtime due to an
|
||||
exception-handling bug. Other tests seem to work.
|
||||
|
||||
</ul>
|
||||
|
||||
<li>Against Python 1.5.2 using the following compiler/library:
|
||||
<p>
|
||||
Note that pickling doesn't work with Python 2.2
|
||||
due to a core language bug. This is fixed in
|
||||
<a href="http://www.python/org/2.2.1">2.2.1</a>.
|
||||
|
||||
<ul>
|
||||
<li><a
|
||||
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>
|
||||
|
||||
<li><a
|
||||
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>/<a
|
||||
href="http://www.stlport.org">STLport 4.0</a>
|
||||
|
||||
<li><a href="http://gcc.gnu.org/">GCC 2.95.2</a> [by <a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich
|
||||
Koethe</a>]
|
||||
|
||||
<li><a href="http://gcc.gnu.org/">GCC 2.95.2</a>/<a href="http://www.stlport.org">STLport 4.0</a>
|
||||
|
||||
<li>Compaq C++ V6.2-024 for Digital UNIX V5.0 Rev. 910 (an <a
|
||||
href="http://www.edg.com/">EDG</a>-based compiler) with <a
|
||||
href="http://www.stlport.org/beta.html">STLport-4.1b3</a> [by <a
|
||||
href="mailto:rwgk@cci.lbl.gov">Ralf W. Grosse-Kunstleve</a>]
|
||||
|
||||
<li>An upcoming release of <a href="http://www.metrowerks.com/products/windows/">Metrowerks CodeWarrior
|
||||
Pro6 for Windows</a> (the first release has a bug that's fatal to Boost.Python)
|
||||
</ul>
|
||||
</ul>
|
||||
<p>
|
||||
Boost.Python has also been used with other versions of Python back to
|
||||
Python 1.5.2. It is expected that the older Python releases still work,
|
||||
but we are not regularly testing for backward compatibility.
|
||||
|
||||
<h2>Credits</h2>
|
||||
<ul>
|
||||
@@ -152,8 +191,8 @@ among others.
|
||||
href="../test/comprehensive.cpp">cpp</a>]</code>
|
||||
|
||||
<p>
|
||||
Questions should be directed to <a href=
|
||||
"http://www.yahoogroups.com/list/boost">the boost mailing list</a>.
|
||||
Questions should be directed to the <a href=
|
||||
"http://www.python.org/sigs/c++-sig/">Python C++ SIG</a>.
|
||||
|
||||
<p>
|
||||
© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||
@@ -162,5 +201,5 @@ among others.
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2001
|
||||
Updated: Apr 2002
|
||||
|
||||
|
||||
@@ -768,7 +768,7 @@ void throw_key_error_if_end(
|
||||
if (p == m.end())
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, boost::python::converters::to_python(key));
|
||||
throw boost::python::error_already_set();
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
162
doc/v2/Apr2002.html
Normal file
162
doc/v2/Apr2002.html
Normal file
@@ -0,0 +1,162 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - April 2002 Progress Report</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h2 align="center">April 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="index">
|
||||
<dt><a href="#accomplishments">Accomplishments</a></dt>
|
||||
<dl class="index">
|
||||
<dt><a href="#arity">Arbitrary Arity Support</a></dt>
|
||||
<dt><a href="#callbacks">New Callback Interface</a></dt>
|
||||
<dt><a href="#policies">Call Policies for Construtors</a></dt>
|
||||
<dt><a href="#bugs">Real Users, Real Bugs</a></dt>
|
||||
<dt><a href="#insights">New Insights</a></dt>
|
||||
<dt><a href="#v1">Boost.Python V1 Maintenance</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#missing">What's Missing</a></dt>
|
||||
|
||||
</dl>
|
||||
|
||||
<h2><a name="accomplishments">Accomplishments</a></h2>
|
||||
|
||||
April was a short month as far as Boost.Python was concerned, since
|
||||
the spring ISO C++ Committee Meeting (and associated vacation)
|
||||
occupied me for the 2nd half of the month. However, a suprising amount
|
||||
of work got done...
|
||||
|
||||
<h3><a name="arity">Arbitrary Arity Support</a></h3>
|
||||
|
||||
I began using the <a
|
||||
href="../../../preprocessor/doc/index.htm">Boost.Preprocessor</a>
|
||||
metaprogramming library to generate support for functions and member
|
||||
functions of arbitrary arity, which was, to say the least, quite an
|
||||
adventure. The feedback cycle resulting from my foray into
|
||||
Boost.Preprocessor resulted in several improvements to the library,
|
||||
most notably in its documentation.
|
||||
|
||||
<p>
|
||||
|
||||
Boost.Python now supports calls of up to 17 arguments on most
|
||||
compilers. Because most EDG-based compilers have dismal preprocessor
|
||||
performance, I had to "manually" expand the metaprograms for
|
||||
arities from zero to fifteen arguments, and EDG-based compilers with
|
||||
<code>__EDG_VERSION__ <= 245</code> only support 15
|
||||
arguments by default. If some crazy program finds a need for more than
|
||||
the default arity support, users can increase the base support by
|
||||
setting the <code>BOOST_PYTHON_MAX_ARITY</code> preprocessor symbol.
|
||||
|
||||
<h3><a name="callbacks">New Callback Interface</a></h3>
|
||||
|
||||
I mentioned in <a href="Mar2002.html">last month's report</a> that I
|
||||
wasn't pleased with the interface for the interface for calling into
|
||||
Python, so now it has been redesigned. The new interface is outlined
|
||||
in <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-April/000953.html">this
|
||||
message</a> (though the GCC 2.95.3 bugs have been fixed).
|
||||
|
||||
<h3><a name="policies">Call Policies for Constructors</a></h3>
|
||||
|
||||
On April 2nd, I <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-April/000916.html">announced</a>
|
||||
support for the use of call policies with constructors.
|
||||
|
||||
<h3><a name="bugs">Real Users, Real Bugs</a></h3>
|
||||
|
||||
At least two people outside of Kull began actually using Boost.Python
|
||||
v2 in earnest this month. Peter Bienstman and Pearu Pearson both
|
||||
provided valuable real-world bug reports that helped me to improve the
|
||||
library's robustness.
|
||||
|
||||
<h3><a name="insights">New Insights</a></h3>
|
||||
|
||||
<a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-May/001010.html"
|
||||
>Answering some of Pearu's questions</a> about explicitly converting
|
||||
objects between Python and C++ actually led me to a new understanding
|
||||
of the role of the current conversion facilities. In Boost.Python v1,
|
||||
all conversions between Python and C++ were handled by a single family
|
||||
of functions, called <code>to_python()</code> and
|
||||
<code>from_python()</code>. Since the primary role of Boost.Python is
|
||||
to wrap C++ functions in Python, I used these names for the first kind
|
||||
of converters I needed: those that extract C++ objects to be used as
|
||||
function arguments and which C++ function return values to
|
||||
Python. The better-considered approach in Boost.Python v2 uses a
|
||||
completely different mechanism for conversions used when calling
|
||||
Python from C++, as in wrapped virtual function implementations. I
|
||||
usually think of this as a "callback", as in "calling
|
||||
back into Python", and I named the converters used in callbacks
|
||||
accordingly: <code>to_python_callback</code> and
|
||||
<code>from_python_callback</code>. However, as it turns out, the
|
||||
behavior of the "callback" converters is the appropriate one
|
||||
for users who want to explicitly extract a C++ value from a Python
|
||||
object, or create a Python object from a C++ value. The upshot is that
|
||||
it probably makes sense to change the name of the existing <code>to_python</code> and
|
||||
<code>from_python</code> so those names are available for the
|
||||
user-friendly explicit converters.
|
||||
|
||||
<p>
|
||||
<a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-May/001013.html">Another
|
||||
of Pearu's questions</a> pushes momentum further in the direction of a
|
||||
more-sophisticated overloading mechanism than the current
|
||||
simple-minded "first match" approach, as I suggested <a
|
||||
href="Mar2002.html#implicit_conversions">last month</a>.
|
||||
|
||||
<h3><a name="v1">Boost.Python V1 Mainenance</a></h3>
|
||||
|
||||
As much as I'm looking forward to retiring Boost.Python v1, a
|
||||
significant amount of effort has been being spent dealing with support
|
||||
problems; the saying that code rots when left alone is true, and
|
||||
Boost.Python is no exception. Eventually it became obvious to me that
|
||||
we were going to have to invest some effort in keeping V1 healthy
|
||||
while working on V2. Ralf and I have expanded support for various
|
||||
compilers and stabilized the V1 codebase considerably. We discarded
|
||||
the obsolete Visual Studio projects which were causing so much
|
||||
confusion. Still to do before the next Boost release:
|
||||
<ol>
|
||||
<li>Update the build/test documentation with detailed instructions for
|
||||
configuring various toolsets.
|
||||
<li>Provide some links to Boost.Python v2 to let people know what's
|
||||
coming.
|
||||
</ol>
|
||||
|
||||
|
||||
<h2><a name="missing">What's Missing</a></h2>
|
||||
|
||||
Last month I announced that I would implement the following which are
|
||||
not yet complete:
|
||||
<ol>
|
||||
<li>Document all implemented features
|
||||
<li>Implement conversions for <code>char</code> types. This is
|
||||
implemented but not tested, so we have to assume it doesn't work.
|
||||
</ol>
|
||||
|
||||
These are my first priority for this month (especially the
|
||||
documentation).
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
3 May, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
233
doc/v2/Mar2002.html
Normal file
233
doc/v2/Mar2002.html
Normal file
@@ -0,0 +1,233 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - March 2002 Progress Report</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h2 align="center">March 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="index">
|
||||
<dt><a href="#accomplishments">Accomplishments</a></dt>
|
||||
<dl class="index">
|
||||
<dt><a href="#calling_python">Calling Python from C++</a></dt>
|
||||
<dt><a href="#virtual_functions">Virtual Functions</a></dt>
|
||||
<dt><a href="#abstract_classes">Abstract Classes</a></dt>
|
||||
<dt><a href="#implicit_conversions">C++ Implicit Conversions</a></dt>
|
||||
<dt><a href="#data_members">C++ Data Members</a></dt>
|
||||
<dt><a href="#miscellaneous">Miscellaneous</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#future">The Near future</a></dt>
|
||||
|
||||
<dt><a href="#notes">Notes</a></dt>
|
||||
|
||||
</dl>
|
||||
|
||||
<h2><a name="accomplishments">Accomplishments</a></h2>
|
||||
|
||||
March was mostly devoted to the reimplementation of features from
|
||||
Boost.Python v1, and some new features. Re-examination of the features
|
||||
from Boost.Python v1 allowed me to make significant improvements.
|
||||
|
||||
<h3><a name="calling_python">Calling Python from C++</a></h3>
|
||||
|
||||
The ability to call Python from C++ is crucial for virtual function
|
||||
support. Implementing this feature well for V2 proved to be more
|
||||
interesting than I expected. You can review most of the relevant
|
||||
design decisions
|
||||
<a href="callbacks.txt">here</a>.
|
||||
|
||||
<p>
|
||||
One point which <i>isn't</i> emphasized in that document is that there
|
||||
are subtle differences in the way <code>from_python</code> conversions
|
||||
work when used for C++ function arguments and Python function return
|
||||
values. In particular, while <code>T const&</code> arguments may
|
||||
invoke rvalue converters, a reference-to-const return value requires
|
||||
an lvalue converter, since a temporary conversion result would leave
|
||||
the returned reference dangling.
|
||||
|
||||
<p>I'm not particularly pleased with the current callback interface,
|
||||
since it usually results in constructs like:
|
||||
<pre>
|
||||
<u>return returning</u><X&>::call(f, obj);
|
||||
</pre>
|
||||
However, I think the following may be possible and I plan to investigate:
|
||||
<pre>
|
||||
return apply<X&>(f, obj);
|
||||
</pre>
|
||||
I'm open to suggestion for better names (and syntaxes)!
|
||||
|
||||
<h3><a name="virtual_functions">Virtual Functions</a></h3>
|
||||
|
||||
Once Python callbacks were implemented, it was just a short step to
|
||||
implementing virtual functions. Python extension class exposing a C++
|
||||
class whose virtual functions are overridable in Python must actually
|
||||
hold a C++ instance of a class <i>derived</i> from the one exposed to
|
||||
Python. Needing some way for users to specify that class, I added an
|
||||
optional template argument to <code>value_holder_generator</code> and
|
||||
<code>pointer_holder_generator<></code> to specify the class
|
||||
actually held. This move began to put pressure on the
|
||||
<code>class_<></code> interface, since the need for the user to
|
||||
produce complicated instantations of
|
||||
<code>class_<></code> was increased:
|
||||
|
||||
<pre>
|
||||
class<Foo, bases<>, value_holder_generator<Foo_callback> >("Foo")
|
||||
.def("hello", &Foo::hello)
|
||||
...
|
||||
</pre>
|
||||
|
||||
<h3><a name="abstract_classes">Abstract Classes</a></h3>
|
||||
|
||||
Normally when a C++ class is exposed to Python, the library registers
|
||||
a conversion function which allows users to wrap functions returning
|
||||
values of that type. Naturally, these return values are temporaries,
|
||||
so the conversion function must make a copy in some
|
||||
dynamically-allocated storage (a "holder") which is managed
|
||||
by the corresponding Python object.
|
||||
|
||||
<p>Unfortunately, in the case of abstract classes (and other types
|
||||
without a publicly-accessible copy constructor), instantiating this
|
||||
conversion function causes a compilation error. In order to support
|
||||
non-copyable classes, there had to be some way to prevent the library
|
||||
from trying to instantiate the conversion function. The only practical
|
||||
approach I could think of was to add an additional template parameter
|
||||
to the <code>class_<></code> interface. When the number of
|
||||
template parameters with useful defaults begins to grow, it is often
|
||||
hard to choose an order which allows users to take advantage of the
|
||||
defaults.
|
||||
|
||||
<p>
|
||||
|
||||
This was the straw that broke the
|
||||
<code>class_<></code> interface's back and caused the redesign
|
||||
whose outcome is detailed <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-March/000892.html">here</a>.
|
||||
The approach allows the user to supply the optional parameters in an
|
||||
arbitrary order. It was inspired by the use of <a
|
||||
href="../../../utility/iterator_adaptors.htm#named_tempalte_parameters">named
|
||||
template parameters</a> in the <a
|
||||
href="../../../utility/iterator_adaptors.htm">Boost Iterator Adaptor
|
||||
Library</a>, though in this case it is possible to deduce the meaning
|
||||
of the template parameters entirely from their type properties,
|
||||
resulting in a simpler interface. Although the move from a
|
||||
policy-based design to what resembles a configuration DSL usually
|
||||
implies a loss of flexibility, in this case I think any costs are far
|
||||
outweighed by the advantages.
|
||||
|
||||
<p>Note: working around the limitations of the various compilers I'm
|
||||
supporting was non-trivial, and resulted in a few messy implementation
|
||||
details. It might be a good idea to switch to a more-straightforward
|
||||
approach once Metrowerks CodeWarrior Pro8 is released.
|
||||
|
||||
<h3><a name="implicit_conversions">C++ Implicit Conversions</a></h3>
|
||||
|
||||
Support for C++ implicit conversion involves creating
|
||||
<code>from_python</code> converters for a type <code>U</code> which in
|
||||
turn use <code>from_python</code> converters registered for a type
|
||||
<code>T</code> where there exists a implicit conversion from
|
||||
<code>T</code> to <code>U</code>. The current implementation is
|
||||
subject to two inefficiencies:
|
||||
<ol>
|
||||
|
||||
<li>Because an rvalue <code>from_python</code> converter produces two
|
||||
pieces of data (a function and a <code>void*</code>) from its
|
||||
<code>convertible()</code> function, we end up calling the function
|
||||
for <code>T</code> twice: once when the converter is looked up in the
|
||||
registry, and again when the conversion is actually performed.
|
||||
|
||||
<li>A vector is used to mark the "visited" converters, preventing
|
||||
infinite recursion as <code>T</code> to
|
||||
<code>U</code> and <code>U</code> to <code>T</code> converters
|
||||
continually search through one-another.
|
||||
|
||||
</ol>
|
||||
|
||||
I consider the former to be a minor issue. The second may or may not
|
||||
prove to be computationally significant, but I believe that
|
||||
architecturally, it points toward a need for more sophisticated
|
||||
overload resolution. It may be that we want CLOS-style multimethod
|
||||
dispatching along with C++ style rules that prevent more than one
|
||||
implicit conversion per argument.
|
||||
|
||||
<h3><a name="data_members">C++ Data Members</a></h3>
|
||||
|
||||
To supply the ability to directly access data members, I was able to
|
||||
hijack the new Python <a
|
||||
href="http://www.python.org/2.2/descrintro.html#property">property</a>
|
||||
type. I had hoped that I would also be able to re-use the work of <a
|
||||
href="make_function.html">make_function</a> to create callable python
|
||||
objects from C++ functions which access a data member of a given
|
||||
class. C++ facilities for specifying data member pointer non-type
|
||||
template arguments require the user to explicitly specify the type of
|
||||
the data member and this under-utilized feature is also not
|
||||
well-implemented on all compilers, so passing the member pointer as a
|
||||
runtime value is the only practical approach. The upshot is that any
|
||||
such entity would actually have to be a function <i>object</i>, and I
|
||||
haven't implemented automatic wrapping of C++ callable function
|
||||
objects yet, so there is less re-use in the implementation than I'd
|
||||
like. I hope to implement callable object wrapping and refactor this
|
||||
code one day. I also hope to implement static data member support,
|
||||
for which Python's property will not be an appropriate descriptor.
|
||||
|
||||
<h3><a name="miscellaneous">Miscellaneous</a></h3>
|
||||
<ul>
|
||||
<li>Moved <code>args<></code> and <code>bases<></code> from unnamed namespace to <code>boost::python</code> in their own header files.
|
||||
<li>Convert <code>NULL</code> pointers returned from wrapped C++ functions to <code>None</code>.
|
||||
<li>Improved some compile-time error checks.
|
||||
<li>Eliminated <code>boost/python/detail/eval.hpp</code> in favor of
|
||||
more-general <code>boost/mpl/apply.hpp</code>.
|
||||
<li>General code cleanup and refactoring.
|
||||
<li>Works with Microsoft Visual C++ 7.0
|
||||
<li>Warning suppression for many compilers
|
||||
<li>Elegant interface design for exporting <code>enum</code> types.
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<h2><a name="future">The Near Future</a></h2>
|
||||
|
||||
Before April 15th I plan to
|
||||
<ol>
|
||||
<li>Document all implemented features
|
||||
<li>Implement a <code>CallPolicy</code> interface for constructors of wrapped
|
||||
classes
|
||||
<li>Implement conversions for <code>char</code> types.
|
||||
<li>Implement automated code generation for all headers containing
|
||||
families of overloaded functions to handle arbitrary arity.
|
||||
</ol>
|
||||
|
||||
I also hope to implement a mechanism for generating conversions
|
||||
between arbitrary Python sequences and C++ containers, if time permits
|
||||
(and others haven't already done it)!
|
||||
|
||||
<h2><a name="notes">Notes</a></h2>
|
||||
|
||||
The older version of KCC used by Kull is generating lots of warnings
|
||||
about a construct I use to instantiate static members of various class
|
||||
templates. I'm thinking of moving to an idiom which uses a function
|
||||
template to suppress it, but worry about bloating the size of debug
|
||||
builds. Since KCC users may be moving to GCC, I'm not sure that it's
|
||||
worth doing anything about it.
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
1 April, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -21,7 +21,6 @@
|
||||
<h2>Contents</h2>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#call-spec">call</a></dt>
|
||||
@@ -32,28 +31,48 @@
|
||||
</dl>
|
||||
<hr>
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
<p>{{Introductory text}}</p>
|
||||
<p>
|
||||
<code><boost/python/call.hpp></code> defines the <a
|
||||
href="#call-spec"><code>call</code></a> family of overloaded function
|
||||
templates, used to invoke Python callable objects from C++.
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
<a name="call-spec"></a>call
|
||||
<a name="call-spec">template <class R, class A1, class A2, ... class A<i>n</i>></a>
|
||||
R call(PyObject* callable, A1 const&, A2 const&, ... A<i>n</i> const&)
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> {{text}}</dt>
|
||||
<dt><b>Effects:</b> {{text}}</dt>
|
||||
<dt><b>Postconditions:</b> {{text}}</dt>
|
||||
<dt><b>Returns:</b> {{text}}</dt>
|
||||
<dt><b>Throws:</b> {{text}}</dt>
|
||||
<dt><b>Complexity:</b> {{text}}</dt>
|
||||
<dt><b>Rationale:</b> {{text}}</dt>
|
||||
<dt><b>Requires:</b> <code>R</code> is a pointer type, reference
|
||||
type, or a complete type with an accessible copy constructor</dt>
|
||||
|
||||
<dt><b>Effects:</b> Invokes <code>callable(a1, a2, ...a<i>n</i>)</code> in
|
||||
Python, where <code>a1</code>...<code>a<i>n</i></code> are the arguments to
|
||||
<code>call()</code>, converted to Python objects.
|
||||
<dt><b>Returns:</b> The result of the Python call, converted to the C++ type <code>R</code>.</dt>
|
||||
|
||||
</dt>
|
||||
<dt><b>Rationale:</b> For a complete semantic description and
|
||||
rationale, see <a href="callbacks.html">this page</a>.
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example(s)</h2>
|
||||
|
||||
<p>{{Example(s)}}</p>
|
||||
The following C++ function applies a Python callable object to its two
|
||||
arguments and returns the result. If a Python exception is raised or
|
||||
the result can't be converted to a <code>double</code>, an exception
|
||||
is thrown.
|
||||
|
||||
<pre>
|
||||
double apply2(PyObject* func, double x, double y)
|
||||
{
|
||||
return boost::python::call<double>(func, x, y);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
05 November, 2002
|
||||
9 May, 2002 <!-- Luann's birthday! -->
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
|
||||
140
doc/v2/call_method.html
Normal file
140
doc/v2/call_method.html
Normal file
@@ -0,0 +1,140 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - <call_method.hpp></title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h2 align="center">Header <call_method.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#call_method-spec">call_method</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
<p>
|
||||
<code><boost/python/call_method.hpp></code> defines the <a
|
||||
href="#call_method-spec"><code>call_method</code></a> family of overloaded function
|
||||
templates, used to invoke Python callable objects from C++.
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
<a name="call_method-spec">template <class R, class A1, class A2, ... class A<i>n</i>></a>
|
||||
R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... A<i>n</i> const&)
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>R</code> is a pointer type, reference
|
||||
type, or a complete type with an accessible copy constructor</dt>
|
||||
|
||||
<dt><b>Effects:</b> Invokes <code>self.<i>method</i>(a1, a2, ...a<i>n</i>)</code> in
|
||||
Python, where <code>a1</code>...<code>a<i>n</i></code> are the arguments to
|
||||
<code>call_method()</code>, converted to Python objects. For a
|
||||
complete semantic description, see <a href="callbacks.html">this
|
||||
page</a>.
|
||||
|
||||
<dt><b>Returns:</b> The result of the Python call, converted to the
|
||||
C++ type <code>R</code>.</dt>
|
||||
|
||||
</dt>
|
||||
<dt><b>Rationale:</b> <code>call_method</code> is critical to
|
||||
implementing C++ virtual functions which are overridable in Python,
|
||||
as shown by the example below.
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example(s)</h2>
|
||||
|
||||
The following C++ illustrates the use of <code>call_method</code> in
|
||||
wrapping a class with a virtual function that can be overridden in
|
||||
Python:
|
||||
|
||||
<h3>C++ Module Definition</h3>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <cstring>
|
||||
|
||||
// class to be wrapped
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
virtual char const* class_name() const { return "Base"; }
|
||||
virtual ~Base();
|
||||
};
|
||||
|
||||
bool is_base(Base* b)
|
||||
{
|
||||
return !std::strcmp(b->class_name(), "Base");
|
||||
}
|
||||
|
||||
// Wrapper code begins here
|
||||
using namespace boost::python;
|
||||
|
||||
// Callback class
|
||||
class Base_callback : public Base
|
||||
{
|
||||
public:
|
||||
Base_callback(PyObject* self) : m_self(self) {}
|
||||
|
||||
char const* class_name() const { return <b>call_method</b>(m_self, "class_name"); }
|
||||
char const* Base_name() const { return Base::class_name(); }
|
||||
private:
|
||||
PyObject* m_self;
|
||||
};
|
||||
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE_INIT(my_module)
|
||||
{
|
||||
module("my_module")
|
||||
.def("is_base", is_base)
|
||||
.add(
|
||||
class_<Base,Base_callback, noncopyable>("Base")
|
||||
.def("class_name", Base_callback::Base_name);
|
||||
)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python Code</h3>
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> class Derived(Base):
|
||||
... def __init__(self):
|
||||
... Base.__init__(self)
|
||||
... def class_name(self):
|
||||
... return self.__class__.__name__
|
||||
...
|
||||
>>> is_base(Base()) # calls the class_name() method from C++
|
||||
1
|
||||
>>> is_base(Derived())
|
||||
0
|
||||
</pre>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
9 May, 2002 <!-- Luann's birthday! -->
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
245
doc/v2/callbacks.html
Normal file
245
doc/v2/callbacks.html
Normal file
@@ -0,0 +1,245 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - Calling Python Functions and Methods</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="http://www.boost.org"><img height="86" width="277" alt="C++ Boost" src="../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h2 align="center">Calling Python Functions and Methods</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
<dt><a href="#argument_handling">Argument Handling</a></dt>
|
||||
<dt><a href="#result_handling">Result Handling</a></dt>
|
||||
<dt><a href="#result_handling">Rationale</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction">Introduction</a></h2>
|
||||
<p>
|
||||
Boost.Python provides two families of function templates,
|
||||
<code><a href="call.html#call-spec">call</a></code> and <code><a
|
||||
href="call_method.html#call_method-spec">call_method</a></code>, for
|
||||
invoking Python functions and methods respectively. The interface for
|
||||
calling a Python function object (or any Python callable object) looks
|
||||
like:
|
||||
|
||||
<pre>
|
||||
call<ResultType>(callable_object, a1, a2... a<i>N</i>);
|
||||
</pre>
|
||||
|
||||
Calling a method of a Python object is similarly easy:
|
||||
|
||||
<pre>
|
||||
call_method<ResultType>(self_object, "<i>method-name</i>", a1, a2... a<i>N</i>);
|
||||
</pre>
|
||||
|
||||
|
||||
<h2><a name="argument_handling">Argument Handling</a></h2>
|
||||
<p>
|
||||
|
||||
Arguments are converted to Python according to their type. By default,
|
||||
the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
|
||||
new Python objects, but this behavior can be overridden by the use of
|
||||
<code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a
|
||||
href="../../../bind/ref.html#reference_wrapper">ref()</a>:
|
||||
|
||||
<pre>
|
||||
class X : boost::noncopyable
|
||||
{
|
||||
...
|
||||
};
|
||||
|
||||
void apply(PyObject* callable, X& x)
|
||||
{
|
||||
// Invoke callable, passing a Python object which holds a reference to x
|
||||
boost::python::call<void>(callable, boost::ref(x));
|
||||
}
|
||||
</pre>
|
||||
|
||||
In the table below, <code><b>x</b></code> denotes the actual argument
|
||||
object and <code><b>cv</b></code> denotes an optional
|
||||
<i>cv-qualification</i>: "<code>const</code>",
|
||||
"<code>volatile</code>", or "<code>const
|
||||
volatile</code>".
|
||||
|
||||
<table border="1" summary="class_ template parameters">
|
||||
<tr>
|
||||
<th>Argument Type
|
||||
|
||||
<th>Behavior
|
||||
|
||||
<tr>
|
||||
<td><code>T cv&</code><br>
|
||||
<code>T cv</code>
|
||||
|
||||
<td>The Python argument is created by the same means used
|
||||
for the return value of a wrapped C++ function returning
|
||||
<code>T</code>. When
|
||||
<code>T</code> is a class type, that normally means
|
||||
<code>*x</code> is copy-constructed into the new Python
|
||||
object.
|
||||
|
||||
<tr>
|
||||
<td><code>T*</code>
|
||||
|
||||
<td>If <code>x == 0</code>, the Python argument will
|
||||
be <code><a
|
||||
href="http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>. Otherwise,
|
||||
the Python argument is created by the same means used for the
|
||||
return value of a wrapped C++ function returning
|
||||
<code>T</code>. When
|
||||
<code>T</code> is a class type, that normally means
|
||||
<code>*x</code> is copy-constructed into the new Python
|
||||
object.
|
||||
|
||||
<tr>
|
||||
<td><code><a
|
||||
href="../../../bind/ref.html#reference_wrapper">boost::reference_wrapper</a><T> </code>
|
||||
|
||||
<td>The Python argument contains a pointer to, rather than a
|
||||
copy of, <code>x.get()</code>. Note: failure to ensure that no
|
||||
Python code holds a reference to the resulting object beyond
|
||||
the lifetime of <code>*x.get()</code> <b>may result in a
|
||||
crash!</b>
|
||||
|
||||
<tr>
|
||||
<td><code><a
|
||||
href="ptr.html#pointer_wrapper-spec">pointer_wrapper</a><T></code>
|
||||
|
||||
<td>If <code>x.get() == 0</code>, the Python
|
||||
argument will be <code><a
|
||||
href="http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
|
||||
Otherwise, the Python argument contains a pointer to, rather
|
||||
than a copy of, <code>*x.get()</code>. Note: failure to ensure
|
||||
that no Python code holds a reference to the resulting object
|
||||
beyond the lifetime of <code>*x.get()</code> <b>may result in
|
||||
a crash!</b>
|
||||
|
||||
</table>
|
||||
|
||||
<h2><a name="result_handling">Result Handling</a></h2>
|
||||
|
||||
In general, <code>call<ResultType>()</code> and
|
||||
<code>call_method<ResultType>()</code> return
|
||||
<code>ResultType</code> by exploiting all lvalue and rvalue
|
||||
<code>from_python</code> converters registered for ResultType and
|
||||
returning a copy of the result. However, when
|
||||
<code>ResultType</code> is a pointer or reference type, Boost.Python
|
||||
searches only for lvalue converters. To prevent dangling pointers and
|
||||
references, an exception will be thrown if the Python result object
|
||||
has only a single reference count.
|
||||
|
||||
<h2><a name="rationale">Rationale</a></h2>
|
||||
|
||||
In general, to get Python arguments corresponding to
|
||||
<code>a1</code>...<code>a<i>N</i></code>, a new Python object must be
|
||||
created for each one; should the C++ object be copied into that Python
|
||||
object, or should the Python object simply hold a reference/pointer to
|
||||
the C++ object? In general, the latter approach is unsafe, since the
|
||||
called function may store a reference to the Python object
|
||||
somewhere. If the Python object is used after the C++ object is
|
||||
destroyed, we'll crash Python.
|
||||
|
||||
<p>In keeping with the philosophy that users on the Python side
|
||||
shouldn't have to worry about crashing the interpreter, the default
|
||||
behavior is to copy the C++ object, and to allow a non-copying
|
||||
behavior only if the user writes <code><a
|
||||
href="../../../bind/ref.html">boost::ref</a>(a1)</code> instead of a1
|
||||
directly. At least this way, the user doesn't get dangerous behavior
|
||||
"by accident". It's also worth noting that the non-copying
|
||||
("by-reference") behavior is in general only available for
|
||||
class types, and will fail at runtime with a Python exception if used
|
||||
otherwise[<a href="#1">1</a>].
|
||||
|
||||
<p>
|
||||
However, pointer types present a problem: one approach is to refuse
|
||||
to compile if any aN has pointer type: after all, a user can always pass
|
||||
<code>*aN</code> to pass "by-value" or <code>ref(*aN)</code>
|
||||
to indicate a pass-by-reference behavior. However, this creates a
|
||||
problem for the expected null pointer to
|
||||
<code>None</code> conversion: it's illegal to dereference a null
|
||||
pointer value.
|
||||
|
||||
<p>
|
||||
|
||||
The compromise I've settled on is this:
|
||||
|
||||
<ol>
|
||||
<li>The default behavior is pass-by-value. If you pass a non-null
|
||||
pointer, the pointee is copied into a new Python object; otherwise
|
||||
the corresponding Python argument will be None.
|
||||
|
||||
<li>if you want by-reference behavior, use <code>ptr(aN)</code> if
|
||||
<code>aN</code> is a pointer and <code>ref(aN)</code> otherwise. If
|
||||
a null pointer is passed to <code>ptr(aN)</code>, the corresponding
|
||||
Python argument will be <code>None</code>.
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
As for results, we have a similar problem: if <code>ResultType</code>
|
||||
is allowed to be a pointer or reference type, the lifetime of the
|
||||
object it refers to is probably being managed by a Python object. When
|
||||
that Python object is destroyed, our pointer dangles. The problem is
|
||||
particularly bad when the <code>ResultType</code> is char const* - the
|
||||
corresponding Python String object is typically uniquely-referenced,
|
||||
meaning that the pointer dangles as soon as <code>call<char
|
||||
const*>(...)</code> returns.
|
||||
|
||||
<p>
|
||||
The old Boost.Python v1 deals with this issue by refusing to compile
|
||||
any uses of <code>call<char const*>()</code>, but this goes both
|
||||
too far and not far enough. It goes too far because there are cases
|
||||
where the owning Python string object survives beyond the call (just
|
||||
for instance, when it's the name of a Python class), and it goes not
|
||||
far enough because we might just as well have the same problem with a
|
||||
returned pointer or reference of any other type.
|
||||
|
||||
<p>
|
||||
|
||||
In Boost.Python v2 this is dealt with by:
|
||||
|
||||
<ol>
|
||||
<li> lifting the compile-time restriction on const
|
||||
char* callback returns
|
||||
|
||||
|
||||
<li> detecting the case when the reference count on the result
|
||||
Python object is 1 and throwing an exception inside of
|
||||
<code>call<U>(...)</code> when <code>U</code> is a pointer
|
||||
or reference type.
|
||||
</ol>
|
||||
|
||||
This should be acceptably safe because users have to explicitly
|
||||
specify a pointer/reference for <code>U</code> in
|
||||
<code>call<U></code>, and they will be protected against dangles
|
||||
at runtime, at least long enough to get out of the
|
||||
<code>call<U>(...)</code> invocation.
|
||||
|
||||
<hr>
|
||||
|
||||
<a name="1">[1]</a> It would be possible to make it fail at compile-time for non-class
|
||||
types such as int and char, but I'm not sure it's a good idea to impose
|
||||
this restriction yet.
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
17 April, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
88
doc/v2/callbacks.txt
Normal file
88
doc/v2/callbacks.txt
Normal file
@@ -0,0 +1,88 @@
|
||||
Here's the plan:
|
||||
|
||||
I aim to provide an interface similar to that of Boost.Python v1's
|
||||
callback<>::call(...) for dealing with callbacks. The interface will
|
||||
look like:
|
||||
|
||||
returning<ResultType>::call("method_name", self_object, a1, a2...);
|
||||
|
||||
or
|
||||
|
||||
returning<ResultType>::call(callable_object, a1, a2...);
|
||||
|
||||
ARGUMENT HANDLING
|
||||
|
||||
There is an issue concerning how to make Python objects from the
|
||||
arguments a1...aN. A new Python object must be created; should the C++
|
||||
object be copied into that Python object, or should the Python object
|
||||
simply hold a reference/pointer to the C++ object? In general, the
|
||||
latter approach is unsafe, since the called function may store a
|
||||
reference to the Python object somewhere. If the Python object is used
|
||||
after the C++ object is destroyed, we'll crash Python.
|
||||
|
||||
I plan to make the copying behavior the default, and to allow a
|
||||
non-copying behavior if the user writes boost::ref(a1) instead of a1
|
||||
directly. At least this way, the user doesn't get dangerous behavior "by
|
||||
accident". It's also worth noting that the non-copying ("by-reference")
|
||||
behavior is in general only available for class types, and will fail at
|
||||
runtime with a Python exception if used otherwise**
|
||||
|
||||
However, pointer types present a problem: My first thought is to refuse
|
||||
to compile if any aN has pointer type: after all, a user can always pass
|
||||
*aN to pass "by-value" or ref(*aN) to indicate a pass-by-reference
|
||||
behavior. However, this creates a problem for the expected NULL pointer
|
||||
=> None conversion: it's illegal to dereference a null pointer value.
|
||||
|
||||
We could use another construct, say "ptr(aN)", to deal with null
|
||||
pointers, but then what does it mean? We know what it does when aN is
|
||||
NULL, but it might either have by-value or by-reference behavior when aN
|
||||
is non-null.
|
||||
|
||||
The compromise I've settled on is this:
|
||||
|
||||
1. The default behavior is pass-by-value. If you pass a non-null
|
||||
pointer, the pointee is copied into a new Python object; otherwise
|
||||
the corresponding Python argument will be None.
|
||||
|
||||
2. if you want by-reference behavior, use ptr(aN) if aN is a pointer
|
||||
and ref(aN) otherwise. If a null pointer is passed to ptr(aN), the
|
||||
corresponding Python argument will be None.
|
||||
|
||||
RESULT HANDLING
|
||||
|
||||
As for results, we have a similar problem: if ResultType is allowed to
|
||||
be a pointer or reference type, the lifetime of the object it refers to
|
||||
is probably being managed by a Python object. When that Python object is
|
||||
destroyed, our pointer dangles. The problem is particularly bad when the
|
||||
ResultType is char const* - the corresponding Python String object is
|
||||
typically uniquely-referenced, meaning that the pointer dangles as soon
|
||||
as returning<char const*>::call() returns.
|
||||
|
||||
Boost.Python v1 deals with this issue by refusing to compile any uses of
|
||||
callback<char const*>::call(), but IMO this goes both too far and not
|
||||
far enough. It goes too far because there are cases where the owning
|
||||
String object survives beyond the call (just for instance when it's the
|
||||
name of a Python class), and it goes not far enough because we might
|
||||
just as well have the same problem with any returned pointer or
|
||||
reference.
|
||||
|
||||
I propose to address this in Boost.Python v2 by
|
||||
|
||||
1. lifting the compile-time restriction on const
|
||||
char* callback returns
|
||||
|
||||
2. detecting the case when the reference count on the
|
||||
result Python object is 1 and throwing an exception
|
||||
inside of returning<U>::call() when U is a pointer or
|
||||
reference type.
|
||||
|
||||
I think this is acceptably safe because users have to explicitly specify
|
||||
a pointer/reference for U in returning<U>, and they will be protected
|
||||
against dangles at runtime, at least long enough to get out of the
|
||||
returning<U>::call() invocation.
|
||||
|
||||
-Dave
|
||||
|
||||
**It would be possible to make it fail at compile-time for non-class
|
||||
types such as int and char, but I'm not sure it's a good idea to impose
|
||||
this restriction yet.
|
||||
@@ -105,7 +105,7 @@ struct Foo {
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE_INIT(my_module)
|
||||
{
|
||||
module m("my_module")
|
||||
module("my_module")
|
||||
.add(
|
||||
class_<Bar>()
|
||||
)
|
||||
|
||||
150
doc/v2/data_members.html
Normal file
150
doc/v2/data_members.html
Normal file
@@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/data_members.hpp></title>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/data_members.hpp></h2>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a>
|
||||
|
||||
<dt><a href="#functions">Functions</a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#make_getter-spec">make_getter</a>
|
||||
|
||||
<dt><a href="#make_setter-spec">make_setter</a>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#examples">Example</a>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><a href="#make_getter-spec">make_getter</a>()</code> and
|
||||
<code><a href="#make_setter-spec">make_setter</a>()</code> are
|
||||
the functions used internally by <code>class_<>::<a href=
|
||||
"class.html#class_-spec-modifiers">def_readonly</a></code> and
|
||||
<code>class_<>::<a href=
|
||||
"class.html#class_-spec-modifiers">def_readwrite</a></code> to
|
||||
produce Python callable objects which wrap C++ data members.
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
|
||||
<pre>
|
||||
<a name="make_getter-spec">template <class C, class D></a>
|
||||
objects::function* make_getter(D C::*pm);
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
objects::function* make_getter(D C::*pm, Policies const& policies);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>Policies</code> is a model of <a
|
||||
href="CallPolicies.html">CallPolicies</a>.
|
||||
|
||||
<dt><b>Effects:</b> Creates a Python callable object which
|
||||
accepts a single argument that can be converted
|
||||
<code>from_python</code> to <code>C*</code>, and returns the
|
||||
corresponding member <code>D</code> member of the <code>C</code>
|
||||
object, converted <code>to_python</code>. If
|
||||
<code>policies</code> is supplied, it will be applied to the
|
||||
function as described <a href=
|
||||
"CallPolicies.html">here</a>.
|
||||
|
||||
<dt><b>Returns:</b> A pointer convertible to <code>PyObject*</code> which
|
||||
refers to the new Python callable object.
|
||||
</dl>
|
||||
<pre>
|
||||
<a name="make_setter-spec">template <class C, class D></a>
|
||||
objects::function* make_setter(D C::*pm);
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
objects::function* make_setter(D C::*pm, Policies const& policies);
|
||||
</pre>
|
||||
|
||||
<dl class="function*-semantics">
|
||||
<dt><b>Requires:</b> <code>Policies</code> is a model of <a
|
||||
href="CallPolicies.html">CallPolicies</a>.
|
||||
|
||||
<dt><b>Effects:</b> Creates a Python callable object which, when
|
||||
called from Python, expects two arguments which can be converted
|
||||
<code>from_python</code> to <code>C*</code> and
|
||||
<code>D const&</code>, respectively, and sets the
|
||||
corresponding <code>D</code> member of the <code>C</code>
|
||||
object. If <code>policies</code> is supplied, it will be applied
|
||||
to the function as described <a
|
||||
href="CallPolicies.html">here</a>.
|
||||
|
||||
<dt><b>Returns:</b> A pointer convertible to
|
||||
<code>PyObject*</code> which refers to the new Python callable
|
||||
object.
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<p>The code below uses make_getter and make_setter to expose a
|
||||
data member as functions:
|
||||
|
||||
<pre>
|
||||
#include <boost/python/data_members.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
X(int x) : y(x) {}
|
||||
int y;
|
||||
};
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(data_members_example)
|
||||
{
|
||||
module("data_members_example")
|
||||
.add(
|
||||
class_<X>("X")
|
||||
.def_init(args<int>())
|
||||
.def("get", make_getter(&X::y))
|
||||
.def("set", make_setter(&X::y))
|
||||
)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
It can be used this way in Python:
|
||||
<pre>
|
||||
>>> from data_members_example import *
|
||||
>>> x = X(1)
|
||||
>>> x.get()
|
||||
1
|
||||
>>> x.set(2)
|
||||
>>> x.get()
|
||||
2
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
8 May 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
367
doc/v2/feb2002.html
Normal file
367
doc/v2/feb2002.html
Normal file
@@ -0,0 +1,367 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - February 2002 Progress Report</title>
|
||||
<style type="text/css">
|
||||
:link { color: #0000ff }
|
||||
:visited { color: #800080 }
|
||||
p.c3 {font-style: italic}
|
||||
h2.c2 {text-align: center}
|
||||
h1.c1 {text-align: center}
|
||||
</style>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="0" width=
|
||||
"100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="http://www.boost.org"><img height="86"
|
||||
width="277" alt="C++ Boost" src="../c++boost.gif"
|
||||
border="0"></a></h3>
|
||||
|
||||
<td valign="top">
|
||||
<h1 class="c1">Boost.Python</h1>
|
||||
|
||||
<h2 class="c2">February 2002 Progress Report</h2>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="index">
|
||||
<dt><a href="#Python10">Python10 Conference Report</a>
|
||||
|
||||
<dt><a href="#progress">Boost.Python v2 Progress</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="#documentation">Documentation</a>
|
||||
|
||||
<dt><a href="#conversion">Overhaul of
|
||||
<code>to_python</code>/<code>from_python</code>
|
||||
conversion mechanism</a>
|
||||
|
||||
<dt><a href="#miscellaneous">Miscellaneous</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<h2><a name="Python10">Python10 Conference Report</a></h2>
|
||||
I spent the first week of February at the Python10 conference
|
||||
in Alexandria, VA. I'm including this experience report
|
||||
for two reasons: firstly, it documents where my time was
|
||||
used. Secondly, a public presence for Boost.Python and
|
||||
interaction between the Python and C++ communities is
|
||||
important to the future of Boost.Python, which in turn is
|
||||
important to the Kull Project.
|
||||
|
||||
<p>Andy Koenig, of all people, was the keynote speaker of
|
||||
this year's opening plenary session. He presented his
|
||||
"impressions of a polyglot outsider", which
|
||||
studiously avoided any mention of C++ until the end of his
|
||||
talk, when he was asked about standardization. I was
|
||||
surprised to learn that the C++ community at large wanted a
|
||||
few more years before beginning but when ANSI accepted
|
||||
HP's request for a standard, the process was forced to
|
||||
start: it was a matter of participating or having
|
||||
standardization proceed without one's input. Andy managed
|
||||
to highlight very effectively the balance of strengths in
|
||||
Python, one of the most important being its support for
|
||||
extension via libraries. In many ways that makes Python a
|
||||
good analogue for C++ in the interpreted world
|
||||
|
||||
<p>There were several kind mentions of the Boost.Python
|
||||
library from people who found it indispensable. I was
|
||||
particularly happy that Karl MacMillan, Michael Droettboom,
|
||||
and Ichiro Fujinaga from Johns Hopkins is using it to do OCR
|
||||
on a vast library of music notation, since in a previous life
|
||||
I was an author of music notation software. These guys are
|
||||
also drawing on Ullrich Koethe's VIGRA library for image
|
||||
manipulation (Ullrich has been a major contributor to
|
||||
Boost.Python). They also have a system for writing the
|
||||
Boost.Python wrapper code in C++ comments, which allows them
|
||||
to keep all of the code in one place. I've asked them to
|
||||
send me some information on that.
|
||||
|
||||
<p>The development of Swig has been gaining momentum again
|
||||
(the basic description at
|
||||
www.boost.org/libs/python/doc/comparisons.html still
|
||||
applies). The talk given about it by David Beazly was very
|
||||
well-attended, and they appear to have quite a few users.
|
||||
Swig's strengths (coverage of many langauages) and
|
||||
weaknesses (incomplete C++ language support) haven't
|
||||
changed, although the C++ support seems to have improved
|
||||
considerably - they now claim to have a complete model of the
|
||||
C++ type system. It seems to be mostly geared at wrapping
|
||||
what Walter Landry calls "C-Tran": C++ code which
|
||||
traffics in built-in types with little use of abstraction.
|
||||
I'm not knocking that, either: I'm sure a lot of that
|
||||
code exists, so it's a valuable service. One feature Swig
|
||||
has which I'd like to steal is the ability to unwrap a
|
||||
single Python argument into multiple C++ arguments, for
|
||||
example, by converting a Python string into a pointer and
|
||||
length. When his talk was over, David approached me about a
|
||||
possible joint workshop on language binding, which sounds
|
||||
like a fun idea to me.
|
||||
|
||||
<p>I spent some considerable time talking with Steven Knight,
|
||||
the leader of the Scons build tool effort. We had a lot to
|
||||
share with one another, and I gained a much better
|
||||
appreciation for many of the Scons design decisions. Scons
|
||||
seems to be concentrating on being the ultimate build system
|
||||
substrate, and Steve seemed to think that we were on the
|
||||
right track with our high-level design. We both hope that the
|
||||
Boost.Build V2 high-level architecture can eventually be
|
||||
ported to run on top of Scons.
|
||||
|
||||
<p>They also have a highly-refined and successful development
|
||||
procedure which I'd like to emulate for Boost.Build V2.
|
||||
Among many other things they do, their source-control system
|
||||
automatically ensures that when you check in a new test, it
|
||||
is automatically run on the currently checked-in state of the
|
||||
code, and is expected to fail -- a relatively obvious good
|
||||
idea which I've never heard before.
|
||||
|
||||
<p>Guido Van Rossum's "State of the Python
|
||||
Union" address was full of questions for the community
|
||||
about what should be done next, but the one idea Guido seemed
|
||||
to stress was that core language stability and continuing
|
||||
library development would be a good idea (sound familiar?) I
|
||||
mentioned the Boost model as a counterpoint to the idea of
|
||||
something like CPAN (the massive Perl library archives), and
|
||||
it seemed to generate some significant interest. I've
|
||||
offered to work with anyone from the Python community who
|
||||
wants to set up something like Boost.
|
||||
|
||||
<p>There was some discussion of "string
|
||||
interpolation" (variable substitution in strings), and
|
||||
Guido mentioned that he had some thoughts about the
|
||||
strengths/weaknesses of Python's formatting interface. It
|
||||
might be useful for those working on formatting for boost to
|
||||
contact him and find out what he has to say.
|
||||
|
||||
<p>Ka-Ping Yee demoed a Mailman discussion thread weaver.
|
||||
This tool weaves the various messages in a discussion thread
|
||||
into a single document so you can follow the entire
|
||||
conversation. Since we're looking very seriously at
|
||||
moving Boost to Mailman, this could be a really useful thing
|
||||
for us to have. If we do this, we'll move the yahoogroups
|
||||
discussions into the mailman archive so old discussions can
|
||||
be easily accessed in the same fashion.
|
||||
|
||||
<p>And, just because it's cool, though perhaps not
|
||||
relevant: http://homepages.ulb.ac.be/~arigo/psyco/ is a
|
||||
promising effort to accelerate the execution of Python code
|
||||
to speeds approaching those of compiled languages. It
|
||||
reminded me a lot of Todd Veldhuizen's research into
|
||||
moving parts of C++ template compilation to runtime, only
|
||||
coming from the opposite end of things.
|
||||
|
||||
<h2><a name="progress">Boost.Python v2 Progress</a></h2>
|
||||
Here's what actually got accomplished.
|
||||
|
||||
<h3><a name="documentation">Documentation</a></h3>
|
||||
|
||||
<p>My first priority upon returning from Python10 was to get
|
||||
some documentation in place. After wasting an unfortunate
|
||||
amount of time looking at automatic documentation tools which
|
||||
don't quite work, I settled down to use Bill Kempf's
|
||||
HTML templates designed to be a boost standard. While they
|
||||
are working well, it is highly labor-intensive.
|
||||
|
||||
<p>I decided to begin with the high-level reference material,
|
||||
as opposed to tutorial, narrative, or nitty-gritty details of
|
||||
the framework. It seemed more important to have a precise
|
||||
description of the way the commonly-used components work than
|
||||
to have examples in HTML (since we already have some test
|
||||
modules), and since the low-level details are much
|
||||
less-frequently needed by users it made sense for me to
|
||||
simply respond to support requests for the time being.
|
||||
|
||||
<p>After completing approximately 60% of the high-level docs
|
||||
(currently checked in to libs/python/doc/v2), I found myself
|
||||
ready to start documenting the mechanisms for creating
|
||||
to-/from-python converters. This caused a dilemma: I had
|
||||
realized during the previous week that a much simpler,
|
||||
more-efficient, and easier-to-use implementation was
|
||||
possible, but I hadn't planned on implementing it right
|
||||
away, since what was already in place worked adequately. I
|
||||
had also received my first query on the C++-sig about how to
|
||||
write such a converter
|
||||
|
||||
<p>Given the labor-intensive nature of documentation writing,
|
||||
I decided it would be a bad idea to document the conversion
|
||||
mechanism if I was just going to rewrite it. Often the best
|
||||
impetus for simplifying a design is the realization that
|
||||
understandably documenting its current state would be too
|
||||
difficult, and this was no exception.
|
||||
|
||||
<h3><a name="conversion">Overhaul of
|
||||
<code>to_python</code>/<code>from_python</code> conversion
|
||||
mechanism</a></h3>
|
||||
|
||||
<p>There were two basic realizations involved here:
|
||||
|
||||
<ol>
|
||||
<li><code>to_python</code> conversion could be a one-step
|
||||
process, once an appropriate conversion function is found.
|
||||
This allows elimination of the separate indirect
|
||||
convertibility check
|
||||
|
||||
<li>There are basically two categories of from_python
|
||||
conversions: those which lvalues stored within or held by
|
||||
the Python object (essentially extractions), like what
|
||||
happens when an instance of a C++ class exposed with class_
|
||||
is used as the target of a wrapped member function), and
|
||||
those in which a new rvalue gets created, as when a Python
|
||||
Float is converted to a C++
|
||||
<code>complex<double></code> or a Python tuple is
|
||||
converted to a C++ <code>std::vector<></code>. From
|
||||
the client side, there are two corresponding categories of
|
||||
conversion: those which demand an lvalue conversion and
|
||||
those which can accept an lvalue or an rvalue conversion.
|
||||
</ol>
|
||||
The latter realization allowed the following collapse, which
|
||||
considerably simplified things:
|
||||
|
||||
<blockquote>
|
||||
<table border="1" summary="Conversion protocol">
|
||||
<tr>
|
||||
<th>Target Type
|
||||
|
||||
<th>Eligible Converters
|
||||
|
||||
<tr>
|
||||
<td><code>T</code>
|
||||
|
||||
<td rowspan="5"><code>T</code> rvalue or lvalue
|
||||
|
||||
<tr>
|
||||
<td><code>T const</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T volatile</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T const volatile</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T const&</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T const*</code>
|
||||
|
||||
<td rowspan="9"><code>T</code> lvalue
|
||||
|
||||
<tr>
|
||||
<td><code>T volatile*</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T const volatile*</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T&</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T volatile&</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T const volatile&</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T* const&</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T const* const&</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T volatile*const&</code>
|
||||
|
||||
<tr>
|
||||
<td><code>T const volatile*const&</code>
|
||||
</table>
|
||||
</blockquote>
|
||||
This job included the following additional enhancements:
|
||||
|
||||
<ul>
|
||||
<li>Elimination of virtual functions, which cause object
|
||||
code bloat
|
||||
|
||||
<li>Registration of a single converter function for all
|
||||
lvalue conversions, two for all rvalue conversions
|
||||
|
||||
<li>Killed lots of unneeded code
|
||||
|
||||
<li>Increased opacity of registry interface
|
||||
|
||||
<li>Eliminated all need for decorated runtime type
|
||||
identifiers
|
||||
|
||||
<li>Updated test modules to reflect new interface
|
||||
|
||||
<li>Eliminated the need for users to worry about converter
|
||||
lifetime issues Additional Builtin Conversion Enhancements
|
||||
|
||||
<li>Support for complex<float>,
|
||||
complex<double>, and complex<long double>
|
||||
conversions
|
||||
|
||||
<li>Support for bool conversions
|
||||
|
||||
<li>NULL pointers representable by None in Python
|
||||
|
||||
<li>Support for conversion of Python classic classes to
|
||||
numeric types
|
||||
</ul>
|
||||
|
||||
<h3><a name="miscellaneous">Miscellaneous</a></h3>
|
||||
These don't fit easily under a large heading:
|
||||
|
||||
<ul>
|
||||
<li>Support CallPolicies for class member functions
|
||||
|
||||
<li>from_python_data.hpp: revamped type alignment
|
||||
metaprogram so that it's fast enough for KCC
|
||||
|
||||
<li>classfwd.hpp header forward-declares class_<T>
|
||||
|
||||
<li>indirect_traits.hpp:
|
||||
|
||||
<li>added is_pointer_to_reference
|
||||
|
||||
<li>fixed bugs
|
||||
|
||||
<li>Reduced recompilation dependencies
|
||||
|
||||
<li>msvc_typeinfo works around broken MS/Intel typeid()
|
||||
implementation
|
||||
|
||||
<li>Many fixes and improvements to the type_traits library
|
||||
in order to work around compiler bugs and suppress warnings
|
||||
|
||||
<li>Eliminated the need for explicit acquisition of
|
||||
converter registrations
|
||||
|
||||
<li>Expanded constructor support to 6 arguments
|
||||
|
||||
<li>Implemented generalized pointer lifetime support
|
||||
|
||||
<li>Updated code generation for returning.hpp
|
||||
|
||||
<li>Tracked down and fixed cycle GC bugs
|
||||
|
||||
<li>Added comprehensive unit tests for destroy_reference,
|
||||
pointer_type_id, select_from_python, complex<T>,
|
||||
bool, and classic class instance conversions
|
||||
</ul>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
4 April, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p class="c3">© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.
|
||||
|
||||
217
doc/v2/has_back_reference.html
Normal file
217
doc/v2/has_back_reference.html
Normal file
@@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python -
|
||||
<boost/python/has_back_reference.hpp></title>
|
||||
<style type="text/css">
|
||||
p.c3 {font-style: italic}
|
||||
h2.c2 {text-align: center}
|
||||
h1.c1 {text-align: center}
|
||||
</style>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="0" width=
|
||||
"100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86"
|
||||
width="277" alt="C++ Boost" src=
|
||||
"../../../../c++boost.gif" border="0"></a></h3>
|
||||
|
||||
<td valign="top">
|
||||
<h1 class="c1">Boost.Python</h1>
|
||||
|
||||
<h2 class="c2">Header
|
||||
<boost/python/has_back_reference.hpp></h2>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a>
|
||||
|
||||
<dt><a href="#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#has_back_reference-spec">Class template
|
||||
<code>has_back_reference</code></a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href=
|
||||
"#has_back_reference-spec-synopsis">Class template
|
||||
<code>has_back_reference</code> synopsis</a>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a>
|
||||
</dl>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><boost/python/has_back_reference.hpp></code>
|
||||
defines the traits class template
|
||||
<code>has_back_reference<></code>, which can be
|
||||
specialized by the user to indicate that a wrapped class
|
||||
instance holds a <code>PyObject*</code> corresponding to a
|
||||
Python object.
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="has_back_reference-spec"></a>Class template
|
||||
<code>has_back_reference</code></h3>
|
||||
|
||||
<p>A unary metafunction whose <code>value</code> is true iff
|
||||
its argument is a <code>pointer_wrapper<></code>.
|
||||
|
||||
<h4><a name="has_back_reference-spec-synopsis"></a>Class
|
||||
template <code>has_back_reference</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template<class WrappedClass> class has_back_reference
|
||||
{
|
||||
static <i>unspecified</i> value = false;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<p>A "<a href=
|
||||
"../../../../more/generic_programming.html#traits">traits
|
||||
class</a>" which is inspected by Boost.Python to
|
||||
determine how wrapped classes can be constructed.
|
||||
|
||||
<dl class="traits-semantics">
|
||||
|
||||
<dt><code>value</code> is an integral constant convertible
|
||||
to bool of unspecified type.
|
||||
|
||||
<dt>Specializations may substitute a value convertible to
|
||||
<code>true</code> for <code>value</code> iff for each invocation of
|
||||
<code>class_<WrappedClass>::def_init(args<</code><i>type-sequence...</i><code>>())</code>,
|
||||
there exists a corresponding constructor
|
||||
<code>WrappedClass::WrappedClass(PyObject*, </code><i>type-sequence...</i><code>)</code>. If
|
||||
such a specialization exists, the <code>WrappedClass</code>
|
||||
constructors will be called with a "back reference" pointer
|
||||
to the corresponding Python object whenever they are invoked from
|
||||
Python.
|
||||
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<h3>C++ module definition</h3>
|
||||
|
||||
<pre>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/has_back_reference.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct X
|
||||
{
|
||||
X(PyObject* self) : m_self(self), m_x(0) {}
|
||||
X(PyObject* self, int x) : m_self(self), m_x(x) {}
|
||||
|
||||
PyObject* self() { return m_self; }
|
||||
int get() { return m_x; }
|
||||
void set(int x) { m_x = x; }
|
||||
|
||||
PyObject* m_self;
|
||||
int x;
|
||||
};
|
||||
|
||||
// specialize has_back_reference for X
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <>
|
||||
struct has_back_reference<X>
|
||||
{
|
||||
enum { value = true; }
|
||||
}
|
||||
}}
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y() : m_x(0) {}
|
||||
Y(int x) : m_x(x) {}
|
||||
int get() { return m_x; }
|
||||
void set(int x) { m_x = x; }
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
boost::shared_ptr<Y> Y_self(boost::shared_ptr<Y> self) const { return self; }
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(back_references)
|
||||
{
|
||||
module("back_references")
|
||||
.add(
|
||||
class_<X>("X")
|
||||
.def_init()
|
||||
.def_init(args<int>())
|
||||
.def("self", &X::self)
|
||||
.def("get", &X::get)
|
||||
.def("set", &X::set)
|
||||
)
|
||||
.add(
|
||||
class_<Y, shared_ptr<Y> >("Y")
|
||||
.def_init()
|
||||
.def_init(args<int>())
|
||||
.def("get", &Y::get)
|
||||
.def("set", &Y::set)
|
||||
.def("self", Y_self)
|
||||
)
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
|
||||
The following Python session illustrates that <code>x.self()</code>
|
||||
returns the same Python object on which it is invoked, while
|
||||
<code>y.self()</code> must create a new Python object which refers to
|
||||
the same Y instance.
|
||||
|
||||
<h3>Python code</h3>
|
||||
|
||||
<pre>
|
||||
>>> from back_references import *
|
||||
>>> x = X(1)
|
||||
>>> x2 = x.self()
|
||||
>>> x2 is x
|
||||
<b>1</b>
|
||||
>>> (x.get(), x2.get())
|
||||
(1, 1)
|
||||
>>> x.set(10)
|
||||
>>> (x.get(), x2.get())
|
||||
(10, 10)
|
||||
>>>
|
||||
>>>
|
||||
>>> y = Y(2)
|
||||
>>> y2 = y.self()
|
||||
>>> y2 is y
|
||||
<b>0</b>
|
||||
>>> (y.get(), y2.get())
|
||||
(2, 2)
|
||||
>>> y.set(20)
|
||||
>>> (y.get(), y2.get())
|
||||
(20, 20)
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
07 May, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p class="c3">© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.
|
||||
|
||||
149
doc/v2/implicit.html
Normal file
149
doc/v2/implicit.html
Normal file
@@ -0,0 +1,149 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/implicit.hpp></title>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/implicit.hpp></h2>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl function="page-index">
|
||||
<dt><a href="#introduction">Introduction</a>
|
||||
|
||||
|
||||
<dt><a href="#functions">Functions</a>
|
||||
|
||||
<dd>
|
||||
<dl function="page-index">
|
||||
<dt><a href="#implicitly_convertible-spec">Function Template <code>implicitly_convertible</code></a>
|
||||
|
||||
</dl>
|
||||
|
||||
<dt><a href="#examples">Example</a>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<code>implicitly_convertible</code> allows Boost.Python to
|
||||
implicitly take advantage of a C++ implicit or explicit conversion
|
||||
when matching Python objects to C++ argument types.
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
|
||||
<h3><a name="implicitly_convertible-spec"></a>Function template <code>implicitly_convertible</code></h3>
|
||||
<pre>
|
||||
template <class Source, class Target>
|
||||
void implicitly_convertible();
|
||||
</pre>
|
||||
|
||||
<table border="1" summary="implicitly_convertible template parameters">
|
||||
<caption>
|
||||
<b><code>implicitly_convertible</code> template parameters</b><br>
|
||||
</caption>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><code>Source</code>
|
||||
<td>The source type of the implicit conversion
|
||||
|
||||
<tr>
|
||||
<td><code>Target</code>
|
||||
<td>The target type of the implicit conversion
|
||||
<tr>
|
||||
</table>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> The expression <code>Target(s)</code>,
|
||||
where <code>s</code> is of type <code>Source</code>, is valid.
|
||||
|
||||
<dt><b>Effects:</b> registers an rvalue <code>from_python</code>
|
||||
converter to <code>Target</code> which can succeed for any
|
||||
<code>PyObject* p</code> iff there exists any registered
|
||||
converter which can produce <code>Source</code> rvalues
|
||||
|
||||
<dt><b>Rationale:</b> C++ users expect to be able to take
|
||||
advantage of the same sort of interoperability in Python as they
|
||||
do in C++.
|
||||
</dl>
|
||||
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
|
||||
<h3>C++ module definition</h3>
|
||||
|
||||
<pre>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/implicit.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct X
|
||||
{
|
||||
X(int x) : v(x) {}
|
||||
operator int() { return v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
int x_value(X const& x)
|
||||
{
|
||||
return x.v;
|
||||
}
|
||||
|
||||
X make_x(int n) { return X(n); }
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(implicit_ext)
|
||||
{
|
||||
module("implicit_ext")
|
||||
.def("x_value", x_value)
|
||||
.def("make_x", make_x)
|
||||
.add(
|
||||
class_<X>("X")
|
||||
.def_init(args<int>())
|
||||
)
|
||||
;
|
||||
implicitly_convertible<X,int>();
|
||||
implicitly_convertible<int,X>();
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python code</h3>
|
||||
|
||||
<pre>
|
||||
>>> from implicit_ext import *
|
||||
>>> x_value(X(42))
|
||||
42
|
||||
>>> x_value(42)
|
||||
42
|
||||
>>> x = make_x(X(42))
|
||||
>>> x_value(x)
|
||||
42
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
08 May, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
<a name="make_function-spec">template <class F></a>
|
||||
objects::function* make_function(F f)</a>
|
||||
objects::function* make_function(F f)
|
||||
|
||||
template <class F, class Policies>
|
||||
objects::function* make_function(F f, Policies const& policies)
|
||||
@@ -80,7 +80,7 @@ objects::function* make_function(F f, Policies const& policies)
|
||||
objects::function* make_constructor();</a>
|
||||
</pre>
|
||||
|
||||
<dl class="make_constructor-semantics">
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is a class type. <code>ArgList</code>
|
||||
is an <a href="../../../mpl/doc/Sequences.html">MPL sequence</a> of C++
|
||||
argument types (<i>A1, A2,... AN</i>) such that if
|
||||
|
||||
@@ -104,7 +104,7 @@ Foo* make_foo(int x) { return new Foo(x); }
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE_INIT(my_module)
|
||||
{
|
||||
module m("my_module")
|
||||
module("my_module")
|
||||
.def("make_foo", make_foo)
|
||||
.add(
|
||||
class_<Foo>()
|
||||
|
||||
261
doc/v2/ptr.html
Normal file
261
doc/v2/ptr.html
Normal file
@@ -0,0 +1,261 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/ptr.hpp></title>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/ptr.hpp></h2>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a>
|
||||
|
||||
<dt><a href="#functions">Functions</a>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#ptr-spec">ptr</a>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#classes">Classes</a>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#pointer_wrapper-spec">Class template <code>pointer_wrapper</code></a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#pointer_wrapper-spec-synopsis">Class template <code>pointer_wrapper</code> synopsis</a>
|
||||
|
||||
<dt><a href="#pointer_wrapper-spec-types">Class
|
||||
<code>pointer_wrapper</code> types</a>
|
||||
|
||||
<dt><a href="#pointer_wrapper-spec-ctors">Class
|
||||
<code>pointer_wrapper</code> constructors and destructor</a>
|
||||
|
||||
<dt><a href="#pointer_wrapper-spec-observers">Class
|
||||
<code>pointer_wrapper</code> observer functions</a>
|
||||
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#metafunctions">Metafunctions</a>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#is_pointer_wrapper-spec">Class template <code>is_pointer_wrapper</code></a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#is_pointer_wrapper-spec-synopsis">Class template <code>is_pointer_wrapper</code> synopsis</a>
|
||||
</dl>
|
||||
|
||||
|
||||
<dt><a href="#unwrap_pointer-spec">Class template <code>unwrap_pointer</code></a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#unwrap_pointer-spec-synopsis">Class template <code>unwrap_pointer</code> synopsis</a>
|
||||
</dl>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
<dt><a href="#examples">Example(s)</a>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><boost/python/ptr.hpp></code> defines the
|
||||
<code>ptr()</code> function template, which allows users to
|
||||
specify how to convert C++ pointer values to python in the context
|
||||
of implementing overridable virtual functions, invoking Python
|
||||
callable objects, or explicitly converting C++ objects to
|
||||
Python. Normally, when passing pointers to Python callbacks, the
|
||||
pointee is copied to ensure that the Python object
|
||||
never holds a dangling reference. To specify that the new Python
|
||||
object should merely contain a copy of a pointer <code>p</code>,
|
||||
the user can pass <code><a href="#ptr-spec">ptr</a>(p)</code> instead of passing
|
||||
<code>p</code> directly. This interface is meant to mirror the use
|
||||
of <a href="../../../bind/ref.html"><code>boost::ref()</code></a>,
|
||||
which can be similarly used to prevent copying of referents.
|
||||
|
||||
<p><code>ptr(p)</code> returns an instance of <code><a
|
||||
href="#pointer_wrapper">pointer_wrapper<></a></code>, which
|
||||
can be detected using the <code><a
|
||||
href="#pointer_wrapper">is_pointer_wrapper<></a></code>
|
||||
metafunction; <code><a
|
||||
href="#pointer_wrapper">unwrap_pointer<></a></code> is a
|
||||
metafunction which extracts the original pointer type from a
|
||||
<code>pointer_wrapper<></code>. These classes can be thought
|
||||
of as implementation details.
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
|
||||
<a name="ptr-spec">template <class T></a>
|
||||
pointer_wrapper<T> ptr(T x);
|
||||
</pre>
|
||||
|
||||
<dl class="ptr-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is a pointer type.
|
||||
|
||||
<dt><b>Returns:</b> <code><a href="#pointer_wrapper-spec">pointer_wrapper</a><T>(x)</code>
|
||||
|
||||
<dt><b>Throws:</b> nothing.
|
||||
</dl>
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="pointer_wrapper-spec"></a>Class template <code>pointer_wrapper</code></h3>
|
||||
|
||||
<p>A "type envelope" which is returned by <a
|
||||
href="#ptr-spec">ptr()</a>, used to indicate reference semantics
|
||||
for pointers passed to Python callbacks.
|
||||
|
||||
<h4><a name="pointer_wrapper-spec-synopsis"></a>Class
|
||||
<code>pointer_wrapper</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template<class Ptr> class pointer_wrapper
|
||||
{
|
||||
public:
|
||||
typedef Ptr type;
|
||||
|
||||
explicit pointer_wrapper(Ptr x);
|
||||
operator Ptr() const;
|
||||
Ptr get() const;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="pointer_wrapper-spec-types"></a>Class template <code>pointer_wrapper</code> types</h4>
|
||||
<pre>
|
||||
typedef Ptr type;
|
||||
</pre>
|
||||
The type of the pointer being wrapped.
|
||||
|
||||
<h4><a name="pointer_wrapper-spec-ctors"></a>Class template <code>pointer_wrapper</code> constructors and
|
||||
destructor</h4>
|
||||
<pre>
|
||||
explicit pointer_wrapper(Ptr x);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>Ptr</code> is a pointer type.
|
||||
|
||||
<dt><b>Effects:</b> Stores <code>x</code> in a the <code>pointer_wrapper<></code>.
|
||||
<dt><b>Throws:</b> nothing.
|
||||
</dl>
|
||||
|
||||
<h4><a name="pointer_wrapper-spec-observers"></a>Class template <code>pointer_wrapper</code> observer
|
||||
functions</h4>
|
||||
<pre>
|
||||
operator Ptr() const;
|
||||
Ptr get() const;
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Returns:</b> a copy of the stored pointer.
|
||||
<dt><b>Rationale:</b> <code>pointer_wrapper</code> is intended
|
||||
to be a stand-in for the actual pointer type, but sometimes it's
|
||||
better to have an explicit way to retrieve the pointer.
|
||||
</dl>
|
||||
|
||||
<h3><a name="is_pointer_wrapper-spec"></a>Class template <code>is_pointer_wrapper</code></h3>
|
||||
|
||||
<p>A unary metafunction whose <code>value</code> is true iff its
|
||||
argument is a <code>pointer_wrapper<></code>.
|
||||
|
||||
<h4><a name="is_pointer_wrapper-spec-synopsis"></a>Class template <code>is_pointer_wrapper</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template<class T> class is_pointer_wrapper
|
||||
{
|
||||
static <i>unspecified</i> value = ...;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Returns:</b> <code>true</code> iff <code>T</code> is a
|
||||
specialization of
|
||||
<code>pointer_wrapper<></code>.
|
||||
<dt><code>value</code> is an integral constant convertible to bool of
|
||||
unspecified type
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="unwrap_pointer-spec"></a>Class template <code>unwrap_pointer</code></h3>
|
||||
|
||||
A unary metafunction which extracts the wrapped pointer type from a
|
||||
specialization of <code>pointer_wrapper<></code>.
|
||||
|
||||
<h4><a name="unwrap_pointer-spec-synopsis"></a>Class template <code>unwrap_pointer</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template<class T> class unwrap_pointer
|
||||
{
|
||||
typedef <i>unspecified</i> type;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Returns:</b> <code>T::type</code> if <code>T</code> is a
|
||||
specialization of
|
||||
<code>pointer_wrapper<></code>, <code>T</code> otherwise
|
||||
</dl>
|
||||
|
||||
|
||||
<h2><a name="examples"></a>Example(s)</h2>
|
||||
|
||||
This example illustrates the use of <code>ptr()</code> to prevent an
|
||||
object from being copied:
|
||||
<pre>
|
||||
#include <boost/python/call.hpp>
|
||||
#include <boost/python/ptr.hpp>
|
||||
|
||||
class expensive_to_copy
|
||||
{
|
||||
...
|
||||
};
|
||||
|
||||
void pass_as_arg(expensive_to_copy* x, PyObject* f)
|
||||
{
|
||||
// call the Python function f, passing a Python object built around
|
||||
// which refers to *x by-pointer.
|
||||
//
|
||||
// *** Note: ensuring that *x outlives the argument to f() is ***
|
||||
// *** up to the user! Failure to do so could result in a crash! ***
|
||||
|
||||
boost::python::call<void>(f, ptr(x));
|
||||
}
|
||||
...
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
07 May, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
<dl class="Reference">
|
||||
<dt><a href="#high_level">High Level Components</a>
|
||||
|
||||
<dt><a href="#framework">Framework Elements</a>
|
||||
<dt><a href="#models_of_call_policies">Models of CallPolicies</a>
|
||||
|
||||
<dt><a href="#utilities">Utilities</a>
|
||||
<dt><a href="#return_handler_generators">Models of ReturnHandlerGenerator</a>
|
||||
|
||||
<dt><a href="#type_conversion">To/From Python Type Conversion</a>
|
||||
|
||||
<dt><a href="#by_name">Index By Name</a>
|
||||
</dl>
|
||||
@@ -41,6 +43,31 @@
|
||||
<h3>General Purpose</h3>
|
||||
|
||||
<dl class="index">
|
||||
|
||||
<dt><a href="call.html">call.hpp</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="call.html#functions">Functions</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"call.html#call-spec">call</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="call_method.html">call_method.hpp</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="call_method.html#functions">Functions</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"call_method.html#call_method-spec">call_method</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="class.html">class.hpp/class_fwd.hpp</a>
|
||||
|
||||
<dd>
|
||||
@@ -57,6 +84,22 @@
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="data_members.html">data_members.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="data_members.html#functions">Functions</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>
|
||||
|
||||
<dt><a href=
|
||||
"data_members.html#make_setter-spec">make_setter</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="errors.html">errors.hpp</a>
|
||||
|
||||
<dd>
|
||||
@@ -140,89 +183,8 @@
|
||||
</dl>
|
||||
</dl>
|
||||
</dl>
|
||||
<a name="type_conversion"></a>
|
||||
|
||||
<h3>To/From Python Type Conversion</h3>
|
||||
|
||||
<dl class="index">
|
||||
<dt><a href="from_python.html">from_python.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="from_python.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"from_python.html#from_python-spec">from_python</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="to_python_converter.html">to_python_converter.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="to_python_converter.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"to_python_converter.html#to_python_converter-spec">to_python_converter</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="to_python_indirect.html">to_python_indirect.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="to_python_indirect.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="to_python_value.html">to_python_value.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="to_python_value.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"to_python_value.html#to_python_value-spec">to_python_value</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="type_from_python.html">type_from_python.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="type_from_python.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"type_from_python.html#type_from_python-spec">type_from_python</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="value_from_python.html">value_from_python.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="value_from_python.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"value_from_python.html#value_from_python-spec">value_from_python</a>
|
||||
</dl>
|
||||
</dl>
|
||||
</dl>
|
||||
<a name="models_of_call_policies"></a>
|
||||
|
||||
<h3>Models of CallPolicies</h3>
|
||||
@@ -369,6 +331,140 @@
|
||||
</dl>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<a name="type_conversion"></a>
|
||||
|
||||
<h3>To/From Python Type Conversion</h3>
|
||||
|
||||
<dl class="index">
|
||||
<dt><a href="from_python.html">from_python.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="from_python.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"from_python.html#from_python-spec">from_python</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="has_back_reference.html">has_back_reference.hpp</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="has_back_reference.html#classes">Classes</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="has_back_reference.html#has_back_reference-spec">has_back_reference</a>
|
||||
</dl>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
<dt><a href="implicit.html">implicit.hpp</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="implicit.html#functions">Functions</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"implicit.html#implicitly_convertible-spec">implicitly_convertible</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="ptr.html">ptr.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="ptr.html#functions">Functions</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="ptr.html#ptr-spec">ptr</a>
|
||||
</dl>
|
||||
|
||||
<dt><a href="ptr.html#classes">Classes</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="ptr.html#pointer_wrapper-spec">pointer_wrapper</a>
|
||||
</dl>
|
||||
|
||||
<dt><a href="ptr.html#metafunctions">MetaFunctions</a>
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="ptr.html#is_pointer_wrapper-spec">is_pointer_wrapper</a>
|
||||
<dt><a href="ptr.html#unwrap_pointer-spec">unwrap_pointer</a>
|
||||
</dl>
|
||||
|
||||
</dl>
|
||||
|
||||
<dt><a href="to_python_converter.html">to_python_converter.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="to_python_converter.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"to_python_converter.html#to_python_converter-spec">to_python_converter</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="to_python_indirect.html">to_python_indirect.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="to_python_indirect.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="to_python_value.html">to_python_value.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="to_python_value.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"to_python_value.html#to_python_value-spec">to_python_value</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="type_from_python.html">type_from_python.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="type_from_python.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"type_from_python.html#type_from_python-spec">type_from_python</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="value_from_python.html">value_from_python.hpp</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="value_from_python.html#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href=
|
||||
"value_from_python.html#value_from_python-spec">value_from_python</a>
|
||||
</dl>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ Singleton& get_it()
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE_INIT(singleton)
|
||||
{
|
||||
module m("singleton")
|
||||
module("singleton")
|
||||
.def("get_it", get_it)
|
||||
.add(
|
||||
class_<Singleton>()
|
||||
|
||||
@@ -118,7 +118,7 @@ struct Foo {
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE_INIT(my_module)
|
||||
{
|
||||
module m("my_module")
|
||||
module("my_module")
|
||||
.add(
|
||||
class_<Bar>()
|
||||
)
|
||||
|
||||
BIN
example/Attic/project.zip
Normal file
BIN
example/Attic/project.zip
Normal file
Binary file not shown.
39
example/Jamfile
Normal file
39
example/Jamfile
Normal file
@@ -0,0 +1,39 @@
|
||||
# Specify our location in the boost project hierarchy
|
||||
subproject libs/python/example ;
|
||||
|
||||
# Declares the following targets:
|
||||
#
|
||||
# 1. an extension module called "getting_started1", which is
|
||||
# built from "getting_started1.cpp". Built by default
|
||||
#
|
||||
# 2. A test target called my-test.test which runs
|
||||
# test_getting_started1.py with the extension module above. Built
|
||||
# when out-of date, but only if invoked by name or if the global
|
||||
# "test" target is invoked.
|
||||
#
|
||||
# 3. A test target called my-test.run wihch runs the above test
|
||||
# unconditionally. Built only when invoked by name.
|
||||
#
|
||||
# To see verbose test output, add "-sPYTHON_TEST_ARGS=-v" to the bjam
|
||||
# command-line before the first target.
|
||||
#
|
||||
|
||||
# Include definitions needed for Python modules
|
||||
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include python.jam ;
|
||||
|
||||
# Declare a Python extension called getting_started1
|
||||
extension getting_started1
|
||||
: # sources
|
||||
getting_started1.cpp
|
||||
|
||||
# dependencies
|
||||
<dll>../build/boost_python
|
||||
;
|
||||
|
||||
# Declare a test for the extension module
|
||||
boost-python-runtest my-test
|
||||
: # Python test driver
|
||||
test_getting_started1.py
|
||||
# extension modules to use
|
||||
<pyd>getting_started1 ;
|
||||
@@ -19,6 +19,3 @@ Examples for the cross-module support are provided by:
|
||||
ivect.cpp
|
||||
See also: libs/python/doc/cross_module.html
|
||||
|
||||
The files example1.cpp and rwgk1.cpp are obsolete. They are only
|
||||
included because the Visual Studio project in the build directory still
|
||||
refers to them.
|
||||
|
||||
@@ -77,7 +77,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
if (tup.size() != 3) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"expecting exactly 3 values in tuple.");
|
||||
throw python::error_already_set();
|
||||
python::throw_error_already_set();
|
||||
}
|
||||
MillerIndex result;
|
||||
for (int i = 0; i < 3; i++)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#include <string.h>
|
||||
|
||||
namespace hello {
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(int) {}
|
||||
~world() {}
|
||||
const char* get() const { return "hi, world"; }
|
||||
};
|
||||
|
||||
size_t length(const world& x) { return strlen(x.get()); }
|
||||
}
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE_INIT(hello)
|
||||
{
|
||||
// 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");
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
// Win32 DLL boilerplate
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif // _WIN32
|
||||
@@ -63,7 +63,7 @@ namespace { // Avoid cluttering the global namespace.
|
||||
if (state.size() != 1) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Unexpected argument in call to __setstate__.");
|
||||
throw python::error_already_set();
|
||||
python::throw_error_already_set();
|
||||
}
|
||||
int number = from_python(state[0].get(), python::type<int>());
|
||||
if (number != 42)
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace {
|
||||
{
|
||||
if(args.size() != 1 || keywords.size() != 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw boost::python::error_already_set();
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
const world& w = from_python(args[0].get(), type<const world&>());
|
||||
ref mydict = getattr(args[0], "__dict__");
|
||||
@@ -115,7 +115,7 @@ namespace {
|
||||
{
|
||||
if(args.size() != 2 || keywords.size() != 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw boost::python::error_already_set();
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
world& w = from_python(args[0].get(), type<world&>());
|
||||
ref mydict = getattr(args[0], "__dict__");
|
||||
@@ -123,7 +123,7 @@ namespace {
|
||||
if (state.size() != 2) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Unexpected argument in call to __setstate__.");
|
||||
throw python::error_already_set();
|
||||
python::throw_error_already_set();
|
||||
}
|
||||
// restore the object's __dict__
|
||||
dictionary odict = from_python(mydict.get(), type<dictionary>());
|
||||
|
||||
BIN
example/project.zip
Normal file
BIN
example/project.zip
Normal file
Binary file not shown.
@@ -35,7 +35,7 @@ namespace vects {
|
||||
{ \
|
||||
if (lhs.size() != rhs.size()) { \
|
||||
PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \
|
||||
throw boost::python::error_already_set(); \
|
||||
boost::python::throw_error_already_set(); \
|
||||
} \
|
||||
std::vector<bool> result(lhs.size()); \
|
||||
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace vects { \
|
||||
operator##oper (const vect_type1& lhs, const vect_type2& rhs) { \
|
||||
if (lhs.size() != rhs.size()) { \
|
||||
PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \
|
||||
throw boost::python::error_already_set(); \
|
||||
boost::python::throw_error_already_set(); \
|
||||
} \
|
||||
result_type result(lhs.size()); \
|
||||
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#include <string>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A couple of simple C++ functions that we want to expose to Python.
|
||||
std::string greet() { return "hello, world"; }
|
||||
int square(int number) { return number * number; }
|
||||
}
|
||||
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace python = boost::python;
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE_INIT(rwgk1)
|
||||
{
|
||||
// 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");
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
void raise_vector_IndexError() {
|
||||
PyErr_SetString(PyExc_IndexError, "vector index out of range");
|
||||
throw python::error_already_set();
|
||||
python::throw_error_already_set();
|
||||
}
|
||||
|
||||
double getitem(const std::vector<double>& vd, std::size_t key) {
|
||||
@@ -90,8 +90,8 @@ BOOST_PYTHON_MODULE_INIT(simple_vector)
|
||||
python::class_builder<std::vector<double>, vector_double_wrapper>
|
||||
vector_double(this_module, "vector_double");
|
||||
|
||||
vector_double.def(python::constructor<>());
|
||||
vector_double.def(python::constructor<int>());
|
||||
vector_double.def(python::constructor<>());
|
||||
vector_double.def(python::constructor<python::tuple>());
|
||||
vector_double.def(&std::vector<double>::size, "__len__");
|
||||
vector_double.def(getitem, "__getitem__");
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace example {
|
||||
|
||||
void raise_vector_IndexError() {
|
||||
PyErr_SetString(PyExc_IndexError, "vector index out of range");
|
||||
throw boost::python::error_already_set();
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
73
include/boost/python/args.hpp
Normal file
73
include/boost/python/args.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef ARGS_DWA2002323_HPP
|
||||
# define ARGS_DWA2002323_HPP
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
# include <boost/preprocessor/enum_params_with_a_default.hpp>
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
|
||||
# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245
|
||||
namespace boost { namespace python {
|
||||
|
||||
|
||||
// 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::python
|
||||
|
||||
# else // slow template instantiators need this other version with
|
||||
// explicit specializations of mpl::size<> and
|
||||
// mpl::at<>. Eventually, however, inheritance from mpl::list
|
||||
// *should* be eliminated and the two versions unified, just in
|
||||
// order to get true arity independence
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_ARITY, class A, boost::mpl::null_argument) >
|
||||
struct args
|
||||
{};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
template <class T> struct size;
|
||||
template <long N, class Seq> struct at;
|
||||
|
||||
# ifndef BOOST_PYTHON_GENERATE_CODE
|
||||
# include <boost/python/preprocessed/args.hpp>
|
||||
# endif
|
||||
|
||||
# define BOOST_PYTHON_ARGS_SIZE(index,ignored) \
|
||||
template <BOOST_PP_ENUM_PARAMS(index, class A)> \
|
||||
struct size<boost::python::args<BOOST_PP_ENUM_PARAMS(index, A)> > \
|
||||
{ \
|
||||
BOOST_STATIC_CONSTANT(long, value = index); \
|
||||
}; \
|
||||
|
||||
BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_ARGS_SIZE, nil)
|
||||
|
||||
# define BOOST_PYTHON_ARGS_AT(index,ignored) \
|
||||
template < \
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_PYTHON_ARITY_FINISH), class A)> \
|
||||
struct at<index, boost::python::args< \
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_PYTHON_ARITY_FINISH), A)> > \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(A,index) type; \
|
||||
}; \
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO_2ND(
|
||||
BOOST_PP_DEC(BOOST_PYTHON_ARITY_START), BOOST_PP_DEC(BOOST_PYTHON_ARITY_FINISH)
|
||||
, BOOST_PYTHON_ARGS_AT, data)
|
||||
|
||||
}}
|
||||
# endif
|
||||
#endif // ARGS_DWA2002323_HPP
|
||||
58
include/boost/python/bases.hpp
Normal file
58
include/boost/python/bases.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef BASES_DWA2002321_HPP
|
||||
# define BASES_DWA2002321_HPP
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/mpl/identity/identity.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
// 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
|
||||
{};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T> struct specifies_bases
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
template < BOOST_MPL_LIST_PARAMETERS(class B) >
|
||||
struct specifies_bases< bases< BOOST_MPL_LIST_PARAMETERS(B) > >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
# else
|
||||
template < BOOST_MPL_LIST_PARAMETERS(class B) >
|
||||
static char is_bases_helper(bases< BOOST_MPL_LIST_PARAMETERS(B) > const&);
|
||||
|
||||
static char (& is_bases_helper(...) )[256];
|
||||
|
||||
template <class T> struct specifies_bases
|
||||
{
|
||||
private:
|
||||
static typename add_reference<T>::type make();
|
||||
BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference<T>::value);
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1));
|
||||
};
|
||||
# endif
|
||||
template <class T, class Prev = bases<> >
|
||||
struct select_bases
|
||||
: mpl::select_type<
|
||||
specifies_bases<T>::value
|
||||
, T
|
||||
, Prev
|
||||
>
|
||||
{
|
||||
};
|
||||
}
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BASES_DWA2002321_HPP
|
||||
49
include/boost/python/call.hpp
Normal file
49
include/boost/python/call.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CALL_DWA2002411_HPP
|
||||
# define CALL_DWA2002411_HPP
|
||||
|
||||
# include <boost/python/converter/callback.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
# include <boost/preprocessor/enum.hpp>
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# ifndef BOOST_PYTHON_GENERATE_CODE
|
||||
# include <boost/python/preprocessed/call.hpp>
|
||||
# endif
|
||||
|
||||
# define BOOST_PYTHON_CALL_FUNCTION(nargs,ignored) \
|
||||
template < \
|
||||
class R \
|
||||
BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \
|
||||
> \
|
||||
typename converter::callback_from_python<R>::result_type \
|
||||
call(PyObject* callable \
|
||||
BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \
|
||||
, boost::type<R>* = 0 \
|
||||
) \
|
||||
{ \
|
||||
converter::callback_from_python<R> converter; \
|
||||
return converter( \
|
||||
PyEval_CallFunction( \
|
||||
callable \
|
||||
, const_cast<char*>(BOOST_PYTHON_ARG_STRING(nargs)) \
|
||||
BOOST_PP_COMMA_IF(nargs) \
|
||||
BOOST_PP_ENUM(nargs,BOOST_PYTHON_CALLBACK_TO_PYTHON_GET,nil) \
|
||||
)); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALL_FUNCTION,data)
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CALL_DWA2002411_HPP
|
||||
50
include/boost/python/call_method.hpp
Normal file
50
include/boost/python/call_method.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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 CALL_METHOD_DWA2002411_HPP
|
||||
# define CALL_METHOD_DWA2002411_HPP
|
||||
|
||||
# include <boost/python/converter/callback.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
# include <boost/preprocessor/enum.hpp>
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# ifndef BOOST_PYTHON_GENERATE_CODE
|
||||
# include <boost/python/preprocessed/call_method.hpp>
|
||||
# endif
|
||||
|
||||
# define BOOST_PYTHON_CALL_METHOD_FUNCTION(nargs,ignored) \
|
||||
template < \
|
||||
class R \
|
||||
BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \
|
||||
> \
|
||||
typename converter::callback_from_python<R>::result_type \
|
||||
call_method(PyObject* self, char const* name \
|
||||
BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \
|
||||
, boost::type<R>* = 0 \
|
||||
) \
|
||||
{ \
|
||||
converter::callback_from_python<R> converter; \
|
||||
return converter( \
|
||||
PyEval_CallMethod( \
|
||||
self \
|
||||
, const_cast<char*>(name) \
|
||||
, const_cast<char*>(BOOST_PYTHON_ARG_STRING(nargs)) \
|
||||
BOOST_PP_COMMA_IF(nargs) \
|
||||
BOOST_PP_ENUM(nargs,BOOST_PYTHON_CALLBACK_TO_PYTHON_GET,nil) \
|
||||
)); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALL_METHOD_FUNCTION,data)
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CALL_METHOD_DWA2002411_HPP
|
||||
@@ -7,35 +7,233 @@
|
||||
# define CLASS_DWA200216_HPP
|
||||
|
||||
# include <boost/python/class_fwd.hpp>
|
||||
# include <boost/python/bases.hpp>
|
||||
# include <boost/python/args.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/detail/member_function_cast.hpp>
|
||||
# include <boost/python/object/class_converters.hpp>
|
||||
# include <boost/type_traits/ice.hpp>
|
||||
# include <boost/type_traits/same_traits.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
|
||||
{};
|
||||
}
|
||||
# include <boost/mpl/bool_t.hpp>
|
||||
# include <boost/python/object/select_holder.hpp>
|
||||
# include <boost/python/object/class_wrapper.hpp>
|
||||
# include <boost/python/data_members.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Forward declarations
|
||||
namespace objects
|
||||
namespace detail
|
||||
{
|
||||
struct value_holder_generator;
|
||||
struct write_type_id;
|
||||
|
||||
template <class T, class Prev = detail::not_specified>
|
||||
struct select_held_type;
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
struct has_noncopyable;
|
||||
|
||||
// Register a to_python converter for a class T, depending on the
|
||||
// type of the first (tag) argument. The 2nd argument is a pointer
|
||||
// to the type of holder that must be created. The 3rd argument is a
|
||||
// reference to the Python type object to be created.
|
||||
template <class T, class Holder>
|
||||
static inline void register_copy_constructor(mpl::bool_t<true> const&, Holder*, ref const& obj, T* = 0)
|
||||
{
|
||||
objects::class_wrapper<T,Holder> x(obj);
|
||||
}
|
||||
|
||||
// Tag dispatched to have no effect.
|
||||
template <class T, class Holder>
|
||||
static inline void register_copy_constructor(mpl::bool_t<false> const&, Holder*, ref const&, T* = 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// class_<T,Bases,HolderGenerator>
|
||||
//
|
||||
// This is the primary mechanism through which users will expose
|
||||
// C++ classes to Python. The three template arguments are:
|
||||
//
|
||||
template <
|
||||
class T // class being wrapped
|
||||
, class X1 // = detail::not_specified
|
||||
, class X2 // = detail::not_specified
|
||||
, class X3 // = detail::not_specified
|
||||
>
|
||||
class class_ : public objects::class_base
|
||||
{
|
||||
typedef class_<T,X1,X2,X3> self;
|
||||
BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable<X1,X2,X3>::value));
|
||||
|
||||
typedef typename detail::select_held_type<
|
||||
X1, typename detail::select_held_type<
|
||||
X2, typename detail::select_held_type<
|
||||
X3
|
||||
>::type>::type>::type held_type;
|
||||
|
||||
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(
|
||||
// This bit of nastiness casts F to a member function of T if possible.
|
||||
detail::member_function_cast<T,F>::stage1(f).stage2((T*)0).stage3(f)
|
||||
)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Fn, class CallPolicy>
|
||||
self& def(char const* name, Fn fn, CallPolicy policy)
|
||||
{
|
||||
this->def(name
|
||||
, boost::python::make_function(
|
||||
// This bit of nastiness casts F to a member function of T if possible.
|
||||
detail::member_function_cast<T,Fn>::stage1(fn).stage2((T*)0).stage3(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&)
|
||||
{
|
||||
def("__init__",
|
||||
make_constructor<Args>(
|
||||
// Using runtime type selection works around a CWPro7 bug.
|
||||
objects::select_holder<T,held_type>((held_type*)0).get()
|
||||
)
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Args, class CallPolicy>
|
||||
self& def_init(Args const&, CallPolicy policy)
|
||||
{
|
||||
def("__init__",
|
||||
make_constructor<Args>(
|
||||
policy
|
||||
// Using runtime type selection works around a CWPro7 bug.
|
||||
, objects::select_holder<T,held_type>((held_type*)0).get()
|
||||
)
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Define the default constructor.
|
||||
self& def_init()
|
||||
{
|
||||
this->def_init(mpl::type_list<>::type());
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// Data member access
|
||||
//
|
||||
template <class D>
|
||||
self& def_readonly(char const* name, D T::*pm)
|
||||
{
|
||||
ref fget(make_getter(pm));
|
||||
this->add_property(name, fget);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D>
|
||||
self& def_readwrite(char const* name, D T::*pm)
|
||||
{
|
||||
ref fget(make_getter(pm));
|
||||
ref fset(make_setter(pm));
|
||||
this->add_property(name, fget, fset);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// return the underlying object
|
||||
// ref object() const;
|
||||
|
||||
private: // types
|
||||
typedef objects::class_id class_id;
|
||||
|
||||
typedef typename detail::select_bases<X1
|
||||
, typename detail::select_bases<X2
|
||||
, typename boost::python::detail::select_bases<X3>::type
|
||||
>::type
|
||||
>::type bases;
|
||||
|
||||
// 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];
|
||||
};
|
||||
friend struct id_vector;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_()
|
||||
: class_base(typeid(T).name(), id_vector::size, id_vector().ids)
|
||||
{
|
||||
// register converters
|
||||
objects::register_class_from_python<T,bases>();
|
||||
|
||||
detail::register_copy_constructor<T>(
|
||||
mpl::bool_t<is_copyable>()
|
||||
, objects::select_holder<T,held_type>((held_type*)0).get()
|
||||
, this->object());
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_(char const* name)
|
||||
: class_base(name, id_vector::size, id_vector().ids)
|
||||
{
|
||||
// register converters
|
||||
objects::register_class_from_python<T,bases>();
|
||||
|
||||
detail::register_copy_constructor<T>(
|
||||
mpl::bool_t<is_copyable>()
|
||||
, objects::select_holder<T,held_type>((held_type*)0).get()
|
||||
, this->object());
|
||||
}
|
||||
|
||||
namespace detail
|
||||
@@ -60,141 +258,29 @@ namespace detail
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// 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)
|
||||
template <class T1, class T2, class T3>
|
||||
struct has_noncopyable
|
||||
: type_traits::ice_or<
|
||||
is_same<T1,noncopyable>::value
|
||||
, is_same<T2,noncopyable>::value
|
||||
, is_same<T3,noncopyable>::value>
|
||||
{};
|
||||
|
||||
|
||||
template <class T, class Prev>
|
||||
struct select_held_type
|
||||
: mpl::select_type<
|
||||
type_traits::ice_or<
|
||||
specifies_bases<T>::value
|
||||
, is_same<T,noncopyable>::value
|
||||
>::value
|
||||
, Prev
|
||||
, T
|
||||
>
|
||||
{
|
||||
// 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&)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CLASS_FWD_DWA200222_HPP
|
||||
# define CLASS_FWD_DWA200222_HPP
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
# include <boost/python/args.hpp>
|
||||
# include <boost/python/bases.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
@@ -13,15 +16,11 @@ 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 X1 = detail::not_specified
|
||||
, class X2 = detail::not_specified
|
||||
, class X3 = detail::not_specified
|
||||
>
|
||||
class class_;
|
||||
|
||||
|
||||
@@ -145,8 +145,7 @@ namespace detail {
|
||||
// A type which acts a lot like a built-in Python class. T is the obj type,
|
||||
// so class_t<instance> is a very simple "class-alike".
|
||||
template <class T>
|
||||
class BOOST_PYTHON_DECL_TEMPLATE class_t
|
||||
: public boost::python::detail::class_base
|
||||
class class_t : public boost::python::detail::class_base
|
||||
{
|
||||
public:
|
||||
class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space);
|
||||
@@ -227,7 +226,7 @@ class BOOST_PYTHON_DECL_TEMPLATE class_t
|
||||
|
||||
// The type of a class_t<T> object.
|
||||
template <class T>
|
||||
class BOOST_PYTHON_DECL_TEMPLATE meta_class
|
||||
class meta_class
|
||||
: public boost::python::detail::reprable<
|
||||
boost::python::detail::callable<
|
||||
boost::python::detail::getattrable<
|
||||
@@ -350,19 +349,21 @@ int class_t<T>::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish);
|
||||
bool 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
|
||||
{
|
||||
adjust_slice_indices(obj, start, finish);
|
||||
if (!adjust_slice_indices(obj, start, finish))
|
||||
return 0;
|
||||
return downcast<T>(obj)->get_slice(start, finish);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const
|
||||
{
|
||||
adjust_slice_indices(obj, start, finish);
|
||||
if (!adjust_slice_indices(obj, start, finish))
|
||||
return -1;
|
||||
downcast<T>(obj)->set_slice(start, finish, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -157,16 +157,15 @@ 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
|
||||
BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type<float>);
|
||||
BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type<double>);
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
PyObject* to_python(float);
|
||||
float from_python(PyObject*, boost::python::type<float>);
|
||||
PyObject* to_python(double);
|
||||
double from_python(PyObject*, boost::python::type<double>);
|
||||
# else
|
||||
BOOST_PYTHON_DECL PyObject* to_python(float);
|
||||
BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type<float>);
|
||||
BOOST_PYTHON_DECL PyObject* to_python(double);
|
||||
BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type<double>);
|
||||
# endif
|
||||
float from_python(PyObject*, boost::python::type<const float&>);
|
||||
|
||||
@@ -261,7 +260,7 @@ PyObject* from_python(PyObject*, boost::python::type<PyObject*>);
|
||||
// #endif
|
||||
// }} // namespace boost::python
|
||||
|
||||
#if !defined(BOOST_MSVC6_OR_EARLIER)
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
template <class T>
|
||||
boost::shared_ptr<T> from_python(PyObject*p, boost::python::type<boost::shared_ptr<T> >)
|
||||
{
|
||||
@@ -287,7 +286,7 @@ PyObject* to_python(boost::shared_ptr<T> p)
|
||||
// inline implementations
|
||||
//
|
||||
|
||||
#ifndef BOOST_MSVC6_OR_EARLIER
|
||||
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
inline PyObject* to_python(double d)
|
||||
{
|
||||
return PyFloat_FromDouble(d);
|
||||
@@ -297,7 +296,7 @@ inline PyObject* to_python(float f)
|
||||
{
|
||||
return PyFloat_FromDouble(f);
|
||||
}
|
||||
#endif // BOOST_MSVC6_OR_EARLIER
|
||||
#endif
|
||||
|
||||
inline PyObject* to_python(long l)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# define BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <string>
|
||||
# include <complex>
|
||||
|
||||
@@ -23,7 +24,16 @@ namespace detail
|
||||
};
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
namespace converter
|
||||
{
|
||||
template <class T> struct callback_to_python;
|
||||
BOOST_PYTHON_DECL PyObject* do_call_to_python(char);
|
||||
BOOST_PYTHON_DECL PyObject* do_call_to_python(char const*);
|
||||
BOOST_PYTHON_DECL PyObject* do_call_to_python(PyObject*);
|
||||
BOOST_PYTHON_DECL PyObject* do_callback_to_python(PyObject*);
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
template <> struct to_python_value<T&> \
|
||||
: detail::builtin_to_python \
|
||||
{ \
|
||||
@@ -41,6 +51,23 @@ namespace detail
|
||||
} \
|
||||
};
|
||||
|
||||
# define BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
namespace converter \
|
||||
{ \
|
||||
template <> struct callback_to_python< T > \
|
||||
{ \
|
||||
callback_to_python(T const& x) \
|
||||
: m_held(expr) {} \
|
||||
PyObject* get() const \
|
||||
{ return m_held.get(); } \
|
||||
private: \
|
||||
ref m_held; \
|
||||
}; \
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T,expr) \
|
||||
BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T,expr)
|
||||
|
||||
# define BOOST_PYTHON_TO_INT(T) \
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
|
||||
@@ -53,12 +80,14 @@ BOOST_PYTHON_TO_INT(int)
|
||||
BOOST_PYTHON_TO_INT(long)
|
||||
# undef BOOST_TO_PYTHON_INT
|
||||
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : detail::none())
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_call_to_python(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_call_to_python(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 ? x : detail::none())
|
||||
BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(PyObject*, converter::do_call_to_python(x))
|
||||
BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(PyObject*, converter::do_callback_to_python(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
|
||||
278
include/boost/python/converter/callback.hpp
Normal file
278
include/boost/python/converter/callback.hpp
Normal file
@@ -0,0 +1,278 @@
|
||||
// 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 CALLBACK_DWA2002228_HPP
|
||||
# define CALLBACK_DWA2002228_HPP
|
||||
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/to_python_function.hpp>
|
||||
# include <boost/python/converter/pointee_to_python_function.hpp>
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/converter/callback_to_python_base.hpp>
|
||||
# include <boost/python/converter/callback_from_python_base.hpp>
|
||||
# include <boost/python/converter/builtin_converters.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/ptr.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct pointer_callback_from_python
|
||||
{
|
||||
pointer_callback_from_python();
|
||||
T operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct reference_callback_from_python
|
||||
{
|
||||
reference_callback_from_python();
|
||||
T operator()(PyObject*) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rvalue_callback_from_python
|
||||
{
|
||||
rvalue_callback_from_python();
|
||||
T const& operator()(PyObject*);
|
||||
private:
|
||||
rvalue_data<T> m_data;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct select_callback_from_python
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ptr = is_pointer<T>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ref = is_reference<T>::value);
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
ptr
|
||||
, pointer_callback_from_python<T>
|
||||
, typename mpl::select_type<
|
||||
ref
|
||||
, reference_callback_from_python<T>
|
||||
, rvalue_callback_from_python<T>
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct reference_callback_to_python : callback_to_python_holder
|
||||
{
|
||||
reference_callback_to_python(T& x);
|
||||
private:
|
||||
static PyObject* get_object(T& x);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct value_callback_to_python : callback_to_python_base
|
||||
{
|
||||
// Throw an exception if the conversion can't succeed
|
||||
value_callback_to_python(T const&);
|
||||
};
|
||||
|
||||
template <class Ptr>
|
||||
struct pointer_deep_callback_to_python : callback_to_python_base
|
||||
{
|
||||
// Throw an exception if the conversion can't succeed
|
||||
pointer_deep_callback_to_python(Ptr);
|
||||
};
|
||||
|
||||
template <class Ptr>
|
||||
struct pointer_shallow_callback_to_python : callback_to_python_holder
|
||||
{
|
||||
// Throw an exception if the conversion can't succeed
|
||||
pointer_shallow_callback_to_python(Ptr);
|
||||
private:
|
||||
static PyObject* get_object(Ptr p);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct select_callback_to_python
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ptr = is_pointer<T>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ref_wrapper = is_reference_wrapper<T>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ptr_wrapper = is_pointer_wrapper<T>::value);
|
||||
|
||||
typedef typename unwrap_reference<T>::type unwrapped_referent;
|
||||
typedef typename unwrap_pointer<T>::type unwrapped_ptr;
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
ptr
|
||||
, pointer_deep_callback_to_python<T>
|
||||
, typename mpl::select_type<
|
||||
ptr_wrapper
|
||||
, pointer_shallow_callback_to_python<unwrapped_ptr>
|
||||
, typename mpl::select_type<
|
||||
ref_wrapper
|
||||
, reference_callback_to_python<unwrapped_referent>
|
||||
, value_callback_to_python<T>
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct callback_from_python
|
||||
: detail::select_callback_from_python<T>::type
|
||||
{
|
||||
typedef T result_type;
|
||||
};
|
||||
|
||||
struct void_result
|
||||
{
|
||||
private:
|
||||
void_result() {}
|
||||
void operator=(void_result const&);
|
||||
|
||||
// I would prefer to make this completely untouchable, but few
|
||||
// compilers support template friends
|
||||
# if 0
|
||||
void_result(void_result const&);
|
||||
# endif
|
||||
friend struct callback_from_python<void>;
|
||||
};
|
||||
|
||||
// Specialization as a convenience for call and call_method
|
||||
template <>
|
||||
struct callback_from_python<void>
|
||||
{
|
||||
typedef void_result result_type;
|
||||
result_type operator()(PyObject* x) const
|
||||
{
|
||||
Py_DECREF(expect_non_null(x));
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct callback_to_python
|
||||
: detail::select_callback_to_python<T>::type
|
||||
{
|
||||
typedef typename detail::select_callback_to_python<T>::type base;
|
||||
public: // member functions
|
||||
// Throw an exception if the conversion can't succeed
|
||||
callback_to_python(T const& x);
|
||||
};
|
||||
|
||||
// Convenience macros for call<> and call_method<> code generation
|
||||
# define BOOST_PYTHON_CALLBACK_TO_PYTHON_GET(index,ignored) \
|
||||
converter::callback_to_python<BOOST_PP_CAT(A,index)>( \
|
||||
BOOST_PP_CAT(a,index)).get()
|
||||
|
||||
# define BOOST_PYTHON_ARG_STRING(nargs) \
|
||||
"(" BOOST_PP_REPEAT(nargs,BOOST_PYTHON_PROJECT_2ND,"O") ")"
|
||||
|
||||
//
|
||||
// Implementations
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
inline rvalue_callback_from_python<T>::rvalue_callback_from_python()
|
||||
: m_data(rvalue_from_python_chain<T>::value)
|
||||
{
|
||||
throw_if_not_registered(m_data.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T const& rvalue_callback_from_python<T>::operator()(PyObject* obj)
|
||||
{
|
||||
return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_class_registered();
|
||||
|
||||
template <class T>
|
||||
inline reference_callback_from_python<T>::reference_callback_from_python()
|
||||
{
|
||||
detail::throw_if_not_registered(lvalue_from_python_chain<T,true>::value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T reference_callback_from_python<T>::operator()(PyObject* obj) const
|
||||
{
|
||||
return python::detail::void_ptr_to_reference(
|
||||
callback_convert_reference(obj, lvalue_from_python_chain<T,true>::value)
|
||||
, (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline pointer_callback_from_python<T>::pointer_callback_from_python()
|
||||
{
|
||||
detail::throw_if_not_registered(lvalue_from_python_chain<T,true>::value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T pointer_callback_from_python<T>::operator()(PyObject* obj) const
|
||||
{
|
||||
return T(callback_convert_pointer(obj, lvalue_from_python_chain<T,true>::value));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline value_callback_to_python<T>::value_callback_to_python(T const& x)
|
||||
: callback_to_python_base(&x, to_python_function<T>::value)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Ptr>
|
||||
inline pointer_deep_callback_to_python<Ptr>::pointer_deep_callback_to_python(Ptr x)
|
||||
: callback_to_python_base(x, pointee_to_python_function<Ptr>::value)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline PyObject* reference_callback_to_python<T>::get_object(T& x)
|
||||
{
|
||||
to_python_indirect<T&,python::detail::make_reference_holder> convert;
|
||||
if (!convert.convertible())
|
||||
throw_no_class_registered();
|
||||
return convert(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline reference_callback_to_python<T>::reference_callback_to_python(T& x)
|
||||
: callback_to_python_holder(get_object(x))
|
||||
{
|
||||
}
|
||||
|
||||
template <class Ptr>
|
||||
inline pointer_shallow_callback_to_python<Ptr>::pointer_shallow_callback_to_python(Ptr x)
|
||||
: callback_to_python_holder(get_object(x))
|
||||
{}
|
||||
|
||||
template <class Ptr>
|
||||
inline PyObject* pointer_shallow_callback_to_python<Ptr>::get_object(Ptr x)
|
||||
{
|
||||
to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
|
||||
if (!convert.convertible())
|
||||
throw_no_class_registered();
|
||||
return x ? convert(x) : python::detail::none();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline callback_to_python<T>::callback_to_python(T const& x)
|
||||
: base(x)
|
||||
{}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CALLBACK_DWA2002228_HPP
|
||||
25
include/boost/python/converter/callback_from_python_base.hpp
Normal file
25
include/boost/python/converter/callback_from_python_base.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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 CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP
|
||||
# define CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Throw an exception
|
||||
BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_stage1_data const&);
|
||||
BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_stage1_data& data, void* storage);
|
||||
|
||||
BOOST_PYTHON_DECL void throw_if_not_registered(lvalue_from_python_registration*const&);
|
||||
BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, lvalue_from_python_registration*const&);
|
||||
BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, lvalue_from_python_registration*const&);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP
|
||||
45
include/boost/python/converter/callback_to_python_base.hpp
Normal file
45
include/boost/python/converter/callback_to_python_base.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CALLBACK_TO_PYTHON_BASE_DWA200237_HPP
|
||||
# define CALLBACK_TO_PYTHON_BASE_DWA200237_HPP
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct callback_to_python_holder
|
||||
{
|
||||
callback_to_python_holder(PyObject* obj);
|
||||
inline PyObject* get() const;
|
||||
private:
|
||||
ref m_held;
|
||||
};
|
||||
|
||||
struct BOOST_PYTHON_DECL callback_to_python_base : callback_to_python_holder
|
||||
{
|
||||
callback_to_python_base(void const volatile* source, to_python_function_t);
|
||||
};
|
||||
|
||||
//
|
||||
// implmentation
|
||||
//
|
||||
inline callback_to_python_holder::callback_to_python_holder(PyObject* obj)
|
||||
: m_held(obj)
|
||||
{
|
||||
}
|
||||
|
||||
inline PyObject* callback_to_python_holder::get() const
|
||||
{
|
||||
return m_held.get();
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CALLBACK_TO_PYTHON_BASE_DWA200237_HPP
|
||||
@@ -8,17 +8,21 @@
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/from_python_stage1_data.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct lvalue_from_python_registration;
|
||||
struct rvalue_from_python_registration;
|
||||
struct rvalue_stage1_data;
|
||||
|
||||
BOOST_PYTHON_DECL void* find(
|
||||
PyObject* source, lvalue_from_python_registration const*);
|
||||
BOOST_PYTHON_DECL void* find(
|
||||
PyObject* source, rvalue_from_python_registration const*, rvalue_stage1_data&);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_stage1_data find(
|
||||
PyObject* source, rvalue_from_python_registration const*);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain(
|
||||
PyObject* source, rvalue_from_python_registration const*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
# include <boost/python/converter/find_from_python.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/destroy.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/converter/pointer_type_id.hpp>
|
||||
# include <boost/python/converter/from_python_data.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/lvalue_from_python_chain.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_chain.hpp>
|
||||
# include <boost/python/detail/void_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
@@ -42,8 +43,6 @@ struct pointer_const_reference_from_python
|
||||
|
||||
private:
|
||||
typename detail::referent_storage<T>::type m_result;
|
||||
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
// Used when T == U*
|
||||
@@ -52,8 +51,6 @@ struct pointer_from_python : from_python_base
|
||||
{
|
||||
pointer_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
// Used when T == U& and (T != V const& or T == W volatile&)
|
||||
@@ -62,8 +59,6 @@ struct reference_from_python : from_python_base
|
||||
{
|
||||
reference_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
// ------- rvalue converters ---------
|
||||
@@ -79,14 +74,12 @@ class rvalue_from_python
|
||||
|
||||
public:
|
||||
rvalue_from_python(PyObject*);
|
||||
~rvalue_from_python();
|
||||
bool convertible() const;
|
||||
|
||||
result_type operator()(PyObject*);
|
||||
|
||||
private:
|
||||
rvalue_data<result_type> m_data;
|
||||
static rvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -151,12 +144,6 @@ inline void*const& from_python_base::result() const
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class U>
|
||||
inline U& void_ptr_to_reference(void const volatile* p, U&(*)())
|
||||
{
|
||||
return *(U*)p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct null_ptr_owner
|
||||
{
|
||||
@@ -169,54 +156,35 @@ namespace detail
|
||||
{
|
||||
return null_ptr_owner<U>::value;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void write_void_ptr(void const volatile* storage, void* ptr, T*)
|
||||
{
|
||||
*(T**)storage = (T*)ptr;
|
||||
}
|
||||
|
||||
// writes U(ptr) into the storage
|
||||
template <class U>
|
||||
inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)())
|
||||
{
|
||||
// stripping CV qualification suppresses warnings on older EDGs
|
||||
typedef typename remove_cv<U>::type u_stripped;
|
||||
write_void_ptr(storage, ptr, u_stripped(0));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline pointer_const_reference_from_python<T>::pointer_const_reference_from_python(PyObject* p)
|
||||
{
|
||||
detail::write_void_ptr_reference(
|
||||
python::detail::write_void_ptr_reference(
|
||||
m_result.bytes
|
||||
, p == Py_None ? p : find(p, chain)
|
||||
, p == Py_None ? p : find(p, lvalue_from_python_chain<T>::value)
|
||||
, (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool pointer_const_reference_from_python<T>::convertible() const
|
||||
{
|
||||
return detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0;
|
||||
return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0;
|
||||
}
|
||||
template <class T>
|
||||
inline T pointer_const_reference_from_python<T>::operator()(PyObject* p) const
|
||||
{
|
||||
return (p == Py_None)
|
||||
? detail::null_ptr_reference((T(*)())0)
|
||||
: detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
|
||||
: python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*& pointer_const_reference_from_python<T>::chain
|
||||
= registry::lvalue_converters(pointer_type_id<T>());
|
||||
|
||||
// --------
|
||||
|
||||
template <class T>
|
||||
inline pointer_from_python<T>::pointer_from_python(PyObject* p)
|
||||
: from_python_base(p == Py_None ? p : find(p, chain))
|
||||
: from_python_base(p == Py_None ? p : find(p, lvalue_from_python_chain<T>::value))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -226,41 +194,26 @@ inline T pointer_from_python<T>::operator()(PyObject* p) const
|
||||
return (p == Py_None) ? 0 : T(result());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*& pointer_from_python<T>::chain
|
||||
= registry::lvalue_converters(pointer_type_id<T>());
|
||||
|
||||
// --------
|
||||
|
||||
template <class T>
|
||||
inline reference_from_python<T>::reference_from_python(PyObject* p)
|
||||
: from_python_base(find(p,chain))
|
||||
: from_python_base(find(p,lvalue_from_python_chain<T>::value))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T reference_from_python<T>::operator()(PyObject*) const
|
||||
{
|
||||
return detail::void_ptr_to_reference(result(), (T(*)())0);
|
||||
return python::detail::void_ptr_to_reference(result(), (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*& reference_from_python<T>::chain
|
||||
= registry::lvalue_converters(undecorated_type_id<T>());
|
||||
|
||||
// -------
|
||||
|
||||
template <class T>
|
||||
inline rvalue_from_python<T>::rvalue_from_python(PyObject* obj)
|
||||
: m_data(find(obj, rvalue_from_python_chain<T>::value))
|
||||
{
|
||||
find(obj, chain, m_data.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_from_python<T>::~rvalue_from_python()
|
||||
{
|
||||
if (m_data.stage1.convertible == m_data.storage.bytes)
|
||||
python::detail::destroy_reference<result_type>(m_data.storage.bytes);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -276,13 +229,9 @@ rvalue_from_python<T>::operator()(PyObject* p)
|
||||
if (m_data.stage1.construct != 0)
|
||||
m_data.stage1.construct(p, &m_data.stage1);
|
||||
|
||||
return detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
|
||||
return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
rvalue_from_python_registration*& rvalue_from_python<T>::chain
|
||||
= registry::rvalue_converters(undecorated_type_id<T>());
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_DWA2002127_HPP
|
||||
|
||||
@@ -9,36 +9,24 @@
|
||||
# include <boost/python/detail/char_array.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type_traits/alignment_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/python/converter/from_python_stage1_data.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/composite_traits.hpp>
|
||||
# else
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# endif
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/detail/destroy.hpp>
|
||||
# include <boost/preprocessor/list/for_each_i.hpp>
|
||||
# include <boost/preprocessor/tuple/to_list.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
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&>
|
||||
{
|
||||
@@ -48,26 +36,6 @@ namespace detail
|
||||
|
||||
# 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 f();
|
||||
@@ -75,115 +43,47 @@ namespace detail
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
struct unknown_alignment
|
||||
{
|
||||
void* p;
|
||||
};
|
||||
|
||||
// EDG is too slow to handle this metaprogram :(
|
||||
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
struct alignment_dummy;
|
||||
typedef void (*function_ptr)();
|
||||
typedef int (alignment_dummy::*member_ptr);
|
||||
typedef int (alignment_dummy::*member_function_ptr)();
|
||||
|
||||
template <std::size_t target_alignment>
|
||||
struct best_alignment_type
|
||||
# define BOOST_PYTHON_ALIGNMENT_TYPES BOOST_PP_TUPLE_TO_LIST( \
|
||||
11, ( \
|
||||
char, short, int, long, float, double, long double \
|
||||
, void*, function_ptr, member_ptr, member_function_ptr))
|
||||
|
||||
# define BOOST_PYTHON_CHOOSE_LOWER_SIZE(R,P,I,T) \
|
||||
typename mpl::select_type< \
|
||||
sizeof(T) <= target, T, char>::type BOOST_PP_CAT(t,I);
|
||||
|
||||
# define BOOST_PYTHON_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I);
|
||||
|
||||
template <std::size_t target>
|
||||
union lower_size
|
||||
{
|
||||
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 < align1)
|
||||
| (sizeof(T2) < sizeof(T1)))
|
||||
));
|
||||
|
||||
typedef typename mpl::select_type<choose_t2, T2, T1>::type type;
|
||||
};
|
||||
BOOST_PP_LIST_FOR_EACH_I(
|
||||
BOOST_PYTHON_CHOOSE_LOWER_SIZE
|
||||
, ignored, BOOST_PYTHON_ALIGNMENT_TYPES)
|
||||
};
|
||||
|
||||
typedef mpl::type_list<
|
||||
char,short,int,long, float,double,long double
|
||||
,void*
|
||||
,void(*)()
|
||||
,void (alignment_dummy::*)()
|
||||
, char (alignment_dummy::*)
|
||||
>::type
|
||||
align_types;
|
||||
#endif // EDG is too slow
|
||||
template <class Align, std::size_t size>
|
||||
union aligned_storage
|
||||
{
|
||||
Align align;
|
||||
char bytes[size
|
||||
// this is just a STATIC_ASSERT. For some reason
|
||||
// MSVC was barfing on the boost one.
|
||||
- (is_same<Align,unknown_alignment>::value ? size : 0)];
|
||||
char bytes[size];
|
||||
};
|
||||
|
||||
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
|
||||
typedef typename remove_cv<typename remove_reference<Reference>::type>::type referent;
|
||||
|
||||
// The Python source makes the assumption that double has
|
||||
// maximal alignment, but that fails on some platforms
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, target_align = alignment_of<referent>::value);
|
||||
|
||||
// Here we make some assumptions and leave out some possible
|
||||
// types worth checking, but this should work most of the time.
|
||||
typedef typename mpl::select_type<
|
||||
is_POD<referent>::value
|
||||
, referent
|
||||
, typename mpl::select_type<
|
||||
alignment_of<long>::value >= target_align
|
||||
, long
|
||||
, typename mpl::select_type<
|
||||
alignment_of<double>::value >= target_align
|
||||
, double
|
||||
, long double>::type
|
||||
>::type
|
||||
>::type align_t;
|
||||
#endif
|
||||
BOOST_STATIC_CONSTANT(std::size_t, alignment1 = alignment_of<align_t>::value);
|
||||
BOOST_STATIC_CONSTANT(std::size_t, alignment2 = referent_alignment<Reference>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(alignment1 >= alignment2);
|
||||
BOOST_STATIC_ASSERT(alignment1 % alignment2 == 0);
|
||||
|
||||
typedef lower_size<referent_size<Reference>::value> align_t;
|
||||
typedef aligned_storage<align_t,referent_size<Reference>::value> type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct rvalue_data
|
||||
struct rvalue_base_data
|
||||
{
|
||||
rvalue_stage1_data stage1;
|
||||
|
||||
@@ -192,6 +92,38 @@ struct rvalue_data
|
||||
>::type storage;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rvalue_data : rvalue_base_data<T>
|
||||
{
|
||||
rvalue_data(rvalue_stage1_data const&);
|
||||
rvalue_data(void*);
|
||||
~rvalue_data();
|
||||
private:
|
||||
typedef typename add_reference<typename add_cv<T>::type>::type ref_type;
|
||||
};
|
||||
|
||||
//
|
||||
// Implementataions
|
||||
//
|
||||
template <class T>
|
||||
inline rvalue_data<T>::rvalue_data(rvalue_stage1_data const& stage1)
|
||||
{
|
||||
this->stage1 = stage1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_data<T>::rvalue_data(void* convertible)
|
||||
{
|
||||
this->stage1.convertible = convertible;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_data<T>::~rvalue_data()
|
||||
{
|
||||
if (this->stage1.convertible == this->storage.bytes)
|
||||
python::detail::destroy_reference<ref_type>(this->storage.bytes);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef HANDLE_DWA20011130_HPP
|
||||
# define HANDLE_DWA20011130_HPP
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL body;
|
||||
|
||||
// The common base class for unwrap_ and wrap_ handle objects. They
|
||||
// share a common base so that handles can be linked into a chain
|
||||
// within a function wrapper which is managed by a single object.
|
||||
struct BOOST_PYTHON_DECL handle : boost::noncopyable
|
||||
{
|
||||
public: // member functions
|
||||
|
||||
// All constructors take a body* passed from the derived class.
|
||||
//
|
||||
// Constructors taking a handle links this into a chain of
|
||||
// handles, for more efficient management in function wrappers
|
||||
handle();
|
||||
handle(body* body);
|
||||
handle(body* body, handle& prev);
|
||||
|
||||
// returns true iff all handles in the chain can convert their
|
||||
// arguments
|
||||
bool convertible() const;
|
||||
|
||||
// safe_bool idiom from Peter Dimov: provides handles to/from
|
||||
// bool without enabling handles to integer types/void*.
|
||||
private:
|
||||
struct dummy { inline void nonnull() {} };
|
||||
typedef void (dummy::*safe_bool)();
|
||||
public:
|
||||
inline operator safe_bool() const;
|
||||
inline safe_bool operator!() const;
|
||||
|
||||
protected: // member functions for derived classes
|
||||
// Get the body we hold
|
||||
inline body* get_body() const;
|
||||
|
||||
inline void set_body(body*);
|
||||
inline void set_prev(handle&);
|
||||
|
||||
// Release all bodies in the chain, in reverse order of
|
||||
// initialization. Only actually called for the head of the chain.
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
// Holds implementation
|
||||
body* m_body;
|
||||
|
||||
// handle for next argument, if any.
|
||||
handle* m_next;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline handle::handle()
|
||||
: m_next(0)
|
||||
{}
|
||||
|
||||
inline handle::handle(body* body, handle& prev)
|
||||
: m_body(body), m_next(0)
|
||||
{
|
||||
prev.m_next = this;
|
||||
}
|
||||
|
||||
inline handle::handle(body* body)
|
||||
: m_body(body), m_next(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline handle::operator handle::safe_bool() const
|
||||
{
|
||||
return convertible() ? &dummy::nonnull : 0;
|
||||
}
|
||||
|
||||
inline handle::safe_bool handle::operator!() const
|
||||
{
|
||||
return convertible() ? 0 : &dummy::nonnull;
|
||||
}
|
||||
|
||||
inline body* handle::get_body() const
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
||||
inline void handle::set_body(body* body)
|
||||
{
|
||||
m_body = body;
|
||||
}
|
||||
|
||||
inline void handle::set_prev(handle& prev)
|
||||
{
|
||||
prev.m_next = this;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // HANDLE_DWA20011130_HPP
|
||||
55
include/boost/python/converter/implicit.hpp
Normal file
55
include/boost/python/converter/implicit.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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 IMPLICIT_DWA2002326_HPP
|
||||
# define IMPLICIT_DWA2002326_HPP
|
||||
# include <boost/python/converter/from_python_data.hpp>
|
||||
# include <boost/python/converter/from_python_stage1_data.hpp>
|
||||
# include <boost/python/converter/registrations.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class Source, class Target>
|
||||
struct implicit
|
||||
{
|
||||
static void* convertible(PyObject* obj)
|
||||
{
|
||||
// Find a converter registration which can produce a Source
|
||||
// instance from obj
|
||||
return const_cast<rvalue_from_python_registration*>(
|
||||
find_chain(obj, rvalue_from_python_chain<Source>::value));
|
||||
}
|
||||
|
||||
static void construct(PyObject* obj, rvalue_stage1_data* data)
|
||||
{
|
||||
// This is the registration we got from the convertible step
|
||||
rvalue_from_python_registration const* registration
|
||||
= static_cast<rvalue_from_python_registration*>(data->convertible);
|
||||
|
||||
// Call the convertible function again
|
||||
rvalue_data<Source> intermediate_data(registration->convertible(obj));
|
||||
|
||||
// Use the result to construct the source type if the first
|
||||
// converter was an rvalue converter.
|
||||
if (registration->construct != 0)
|
||||
registration->construct(obj, &intermediate_data.stage1);
|
||||
|
||||
void* storage = ((rvalue_base_data<Target>*)data)->storage.bytes;
|
||||
# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13012108 // vc7.01 alpha workaround
|
||||
new (storage) Target(*static_cast<Source*>(intermediate_data.stage1.convertible));
|
||||
# else
|
||||
Target x(*static_cast<Source*>(intermediate_data.stage1.convertible));
|
||||
new (storage) Target(x);
|
||||
# endif
|
||||
|
||||
// record successful construction
|
||||
data->convertible = storage;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // IMPLICIT_DWA2002326_HPP
|
||||
70
include/boost/python/converter/lvalue_from_python_chain.hpp
Normal file
70
include/boost/python/converter/lvalue_from_python_chain.hpp
Normal 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 LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
# define LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
|
||||
# include <boost/python/converter/pointer_type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// Given T == U*cv&, T == U*, or T == U&, lvalue_from_python_chain<T>
|
||||
// declares a "templated global reference" to the lvalue from_python
|
||||
// converter chain for U. The optional bool second argument callback,
|
||||
// when true, removes special treatment for T == U*cv& so that the
|
||||
// converter for U* is found.
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct ptr_or_ptr_ref_lvalue_from_python_chain
|
||||
{
|
||||
static lvalue_from_python_registration*const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*const&
|
||||
ptr_or_ptr_ref_lvalue_from_python_chain<T>::value
|
||||
= registry::lvalue_converters(pointer_type_id<T>());
|
||||
|
||||
template <class T>
|
||||
struct ref_lvalue_from_python_chain
|
||||
{
|
||||
static lvalue_from_python_registration*const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*const&
|
||||
ref_lvalue_from_python_chain<T>::value
|
||||
= registry::lvalue_converters(undecorated_type_id<T>());
|
||||
|
||||
template <class T, bool callback>
|
||||
struct select_lvalue_from_python_chain
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ptr
|
||||
= !callback && boost::python::detail::is_reference_to_pointer<T>::value
|
||||
|| is_pointer<T>::value);
|
||||
|
||||
typedef typename add_reference<typename add_cv<T>::type>::type normalized;
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
ptr
|
||||
, ptr_or_ptr_ref_lvalue_from_python_chain<normalized>
|
||||
, ref_lvalue_from_python_chain<normalized>
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T, bool callback = false>
|
||||
struct lvalue_from_python_chain
|
||||
: detail::select_lvalue_from_python_chain<T,callback>::type
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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 POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
# define POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
# include <boost/python/converter/pointer_type_id.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// pointee_to_python_function --
|
||||
//
|
||||
// essentially a "templated global reference" which holds the
|
||||
// converter for converting a type to Python by-value. We "normalize"
|
||||
// T by adding "const volatile&" so that fewer global variables and
|
||||
// associated static initializations are generated.
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct pointee_to_python_function_base
|
||||
{
|
||||
static to_python_function_t const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
to_python_function_t const&
|
||||
pointee_to_python_function_base<T>::value
|
||||
= converter::registry::get_to_python_function(pointer_type_id<T>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct pointee_to_python_function
|
||||
: detail::pointee_to_python_function_base<
|
||||
typename add_reference<
|
||||
typename add_cv<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
@@ -8,7 +8,7 @@
|
||||
# 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>
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
# include <boost/python/converter/from_python_function.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
@@ -22,10 +22,10 @@ namespace registry
|
||||
BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t);
|
||||
BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL to_python_value_function const&
|
||||
to_python_function(undecorated_type_id_t);
|
||||
BOOST_PYTHON_DECL to_python_function_t const&
|
||||
get_to_python_function(undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t);
|
||||
BOOST_PYTHON_DECL void insert(to_python_function_t, undecorated_type_id_t);
|
||||
|
||||
// Insert an lvalue from_python converter
|
||||
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), undecorated_type_id_t);
|
||||
@@ -37,6 +37,14 @@ namespace registry
|
||||
, undecorated_type_id_t
|
||||
);
|
||||
|
||||
// Insert an rvalue from_python converter at the tail of the
|
||||
// chain. Used for implicit conversions
|
||||
BOOST_PYTHON_DECL void push_back(
|
||||
void* (*convertible)(PyObject*)
|
||||
, constructor_function
|
||||
, undecorated_type_id_t
|
||||
);
|
||||
|
||||
BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key);
|
||||
}
|
||||
|
||||
|
||||
39
include/boost/python/converter/rvalue_from_python_chain.hpp
Normal file
39
include/boost/python/converter/rvalue_from_python_chain.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
# define RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct rvalue_from_python_chain_impl
|
||||
{
|
||||
static rvalue_from_python_registration*const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
rvalue_from_python_registration*const& rvalue_from_python_chain_impl<T>::value
|
||||
= registry::rvalue_converters(undecorated_type_id<T>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct rvalue_from_python_chain
|
||||
: detail::rvalue_from_python_chain_impl<
|
||||
typename add_reference<
|
||||
typename add_cv<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
@@ -8,23 +8,41 @@
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/to_python_function_type.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
|
||||
// to_python_function --
|
||||
//
|
||||
// essentially a "templated global reference" which holds the
|
||||
// converter for converting a type to Python by-value. We "normalize"
|
||||
// T by adding "const volatile&" so that fewer global variables and
|
||||
// associated static initializations are generated.
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct to_python_function_base
|
||||
{
|
||||
static to_python_function_t const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
to_python_function_t const&
|
||||
to_python_function_base<T>::value
|
||||
= converter::registry::get_to_python_function(undecorated_type_id<T>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct to_python_function
|
||||
: detail::to_python_function_base<
|
||||
typename add_reference<
|
||||
typename add_cv<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
static PyObject* convert(void const* x)
|
||||
{
|
||||
return ToPython::convert(*(T const*)x);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
30
include/boost/python/converter/to_python_function_type.hpp
Normal file
30
include/boost/python/converter/to_python_function_type.hpp
Normal 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 TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
# include <boost/python/detail/wrap_python.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_function_t)(void const*);
|
||||
|
||||
// Given a typesafe to_python conversion function, produces a
|
||||
// to_python_function_t which can be registered in the usual way.
|
||||
template <class T, class ToPython>
|
||||
struct as_to_python_function
|
||||
{
|
||||
static PyObject* convert(void const* x)
|
||||
{
|
||||
return ToPython::convert(*(T const*)x);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
# define UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T> struct unwrapper;
|
||||
|
||||
// Select the type returned by unwrapper objects when unwrapping a
|
||||
// given type. When unwrapping T const&, the unwrapper returns T&, so
|
||||
// that the same unwrapper object can be used for both conversions (on
|
||||
// a conforming compiler).
|
||||
template <class T>
|
||||
struct unwrapper_select
|
||||
{
|
||||
typedef unwrapper<T> type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct unwrapper_select<T const&>
|
||||
{
|
||||
typedef unwrapper<T&> type;
|
||||
};
|
||||
# endif
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // UNWRAPPER_SELECT_DWA20011229_HPP
|
||||
@@ -18,8 +18,12 @@
|
||||
# include <boost/python/class_builder.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
struct BOOST_PYTHON_DECL import_error: error_already_set {};
|
||||
struct BOOST_PYTHON_DECL export_error : error_already_set {};
|
||||
|
||||
struct BOOST_PYTHON_DECL import_error: error_already_set {};
|
||||
struct BOOST_PYTHON_DECL export_error : error_already_set {};
|
||||
|
||||
void BOOST_PYTHON_DECL throw_import_error();
|
||||
void BOOST_PYTHON_DECL throw_export_error();
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@@ -170,10 +174,8 @@ struct export_converter_object_noncopyable : export_converter_object_base<T>
|
||||
virtual PyObject* to_python(const T& x) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"to_python(const T&) converter not exported");
|
||||
throw import_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
throw_import_error();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual T* from_python_Ts(PyObject* p, boost::python::type<T*> t) {
|
||||
|
||||
111
include/boost/python/data_members.hpp
Normal file
111
include/boost/python/data_members.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
// 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 DATA_MEMBERS_DWA2002328_HPP
|
||||
# define DATA_MEMBERS_DWA2002328_HPP
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/object/function.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/return_value_policy.hpp>
|
||||
# include <boost/python/copy_non_const_reference.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Data, class Class, class Policies>
|
||||
struct member
|
||||
{
|
||||
static PyObject* get(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies)
|
||||
{
|
||||
from_python<Class*> c0(PyTuple_GET_ITEM(args_, 0));
|
||||
if (!c0.convertible()) return 0;
|
||||
|
||||
// find the result converter
|
||||
typedef typename Policies::result_converter result_converter;
|
||||
typedef typename boost::add_reference<Data>::type source;
|
||||
typename mpl::apply1<result_converter,source>::type cr;
|
||||
if (!cr.convertible()) return 0;
|
||||
|
||||
if (!policies.precall(args_)) return 0;
|
||||
|
||||
PyObject* result = cr( (c0(PyTuple_GET_ITEM(args_, 0)))->*pm );
|
||||
|
||||
return policies.postcall(args_, result);
|
||||
}
|
||||
|
||||
static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies)
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
from_python<Class*> c0(PyTuple_GET_ITEM(args_, 0));
|
||||
if (!c0.convertible()) return 0;
|
||||
|
||||
typedef typename add_const<Data>::type target1;
|
||||
typedef typename add_reference<target1>::type target;
|
||||
from_python<target> c1(PyTuple_GET_ITEM(args_, 1));
|
||||
|
||||
if (!c1.convertible()) return 0;
|
||||
|
||||
if (!policies.precall(args_)) return 0;
|
||||
|
||||
(c0(PyTuple_GET_ITEM(args_, 0)))->*pm = c1(PyTuple_GET_ITEM(args_, 1));
|
||||
|
||||
return policies.postcall(args_, detail::none());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class C, class D>
|
||||
objects::function* make_getter(D C::*pm)
|
||||
{
|
||||
typedef return_value_policy<copy_non_const_reference> default_policy;
|
||||
return new objects::function(
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,default_policy>::get, pm, _1, _2
|
||||
, default_policy()))
|
||||
, 1);
|
||||
}
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
objects::function* make_getter(D C::*pm, Policies const& policies)
|
||||
{
|
||||
return new objects::function(
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,Policies>::get, pm, _1, _2
|
||||
, policies))
|
||||
, 1);
|
||||
}
|
||||
|
||||
template <class C, class D>
|
||||
objects::function* make_setter(D C::*pm)
|
||||
{
|
||||
return new objects::function(
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,default_call_policies>::set, pm, _1, _2
|
||||
, default_call_policies()))
|
||||
, 2);
|
||||
}
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
objects::function* make_setter(D C::*pm, Policies const& policies)
|
||||
{
|
||||
return new objects::function(
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,Policies>::set, pm, _1, _2
|
||||
, policies))
|
||||
, 2);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // DATA_MEMBERS_DWA2002328_HPP
|
||||
@@ -11,7 +11,11 @@
|
||||
#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
# define ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/python/detail/char_array.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/mpl/aux_/preprocessor.hpp>
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
@@ -20,203 +24,29 @@ namespace boost { namespace python { namespace detail {
|
||||
// (member) function of the given type.
|
||||
template <class F> struct arg_tuple_size;
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__)
|
||||
// Include the pre-expanded version of the code
|
||||
# ifndef BOOST_PYTHON_GENERATE_CODE
|
||||
# include <boost/python/preprocessed/arg_tuple_size.hpp>
|
||||
# endif
|
||||
|
||||
template <class R>
|
||||
struct arg_tuple_size<R (*)()>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 0);
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
// Specializations for function pointers
|
||||
# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \
|
||||
template <class R BOOST_PP_COMMA_IF(args) BOOST_MPL_TEMPLATE_PARAMETERS(0, args, class A)> \
|
||||
struct arg_tuple_size<BOOST_PYTHON_FN(*,0,args)> \
|
||||
{ \
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = args); \
|
||||
};
|
||||
|
||||
template <class R, class A1>
|
||||
struct arg_tuple_size<R (*)(A1)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
// Specializations for member function pointers
|
||||
# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \
|
||||
template <class R, BOOST_MPL_TEMPLATE_PARAMETERS(0, args, class A)> \
|
||||
struct arg_tuple_size<BOOST_PYTHON_FN(A0::*,1,args) cv()> \
|
||||
{ \
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = args); \
|
||||
};
|
||||
|
||||
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
|
||||
@@ -230,103 +60,22 @@ struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5) const volatile>
|
||||
// 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);
|
||||
# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \
|
||||
template <class R BOOST_PP_COMMA_IF(args) BOOST_MPL_TEMPLATE_PARAMETERS(0, args, class A)> \
|
||||
char_array<args> arg_tuple_size_helper(BOOST_PYTHON_FN(*,0,args));
|
||||
|
||||
# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \
|
||||
template <class R, BOOST_MPL_TEMPLATE_PARAMETERS(0, args, class A)> \
|
||||
char_array<args> arg_tuple_size_helper(BOOST_PYTHON_FN(A0::*,1,args)cv());
|
||||
|
||||
# endif
|
||||
|
||||
BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PF, nil)
|
||||
|
||||
// Generate a series for each cv-qualification
|
||||
BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PMF)
|
||||
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__)
|
||||
template <class F>
|
||||
struct arg_tuple_size
|
||||
{
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
# 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>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/mpl/aux_/preprocessor.hpp>
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -24,192 +26,41 @@ 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);
|
||||
}
|
||||
# ifndef BOOST_PYTHON_GENERATE_CODE
|
||||
# include <boost/python/preprocessed/caller.hpp>
|
||||
# endif
|
||||
|
||||
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);
|
||||
}
|
||||
# define BOOST_PYTHON_CALLER_PF(args_, ignored) \
|
||||
template < \
|
||||
class P \
|
||||
, class R \
|
||||
BOOST_PP_COMMA_IF(args_) BOOST_MPL_TEMPLATE_PARAMETERS(0, args_, class A) \
|
||||
> \
|
||||
PyObject* operator()( \
|
||||
BOOST_PYTHON_FN(*f,0,args_) \
|
||||
, 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);
|
||||
}
|
||||
BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALLER_PF, nil)
|
||||
|
||||
// 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);
|
||||
}
|
||||
# define BOOST_PYTHON_CALLER_PMF(args_, cv) \
|
||||
template <class P, class R, BOOST_MPL_TEMPLATE_PARAMETERS(0, args_, class A)> \
|
||||
PyObject* operator()( \
|
||||
BOOST_PYTHON_FN(A0::*f,1,args_)cv() \
|
||||
, 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);
|
||||
}
|
||||
BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_CALLER_PMF)
|
||||
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -33,10 +33,15 @@
|
||||
# define BOOST_MSVC6_OR_EARLIER 1
|
||||
# endif
|
||||
|
||||
# pragma warning (disable : 4786)
|
||||
# pragma warning (disable : 4786)
|
||||
|
||||
# elif defined(__ICL) && __ICL < 600 // Intel C++ 5
|
||||
|
||||
# pragma warning(disable: 985) // identifier was truncated in debug information
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
// Work around the broken library implementation/strict ansi checking on some
|
||||
// EDG-based compilers (e.g. alpha), which incorrectly warn that the result of
|
||||
// offsetof() is not an integer constant expression.
|
||||
@@ -74,32 +79,16 @@
|
||||
// backwards compatibility:
|
||||
#ifdef BOOST_PYTHON_STATIC_LIB
|
||||
# define BOOST_PYTHON_STATIC_LINK
|
||||
# elif !defined(BOOST_PYTHON_DYNAMIC_LIB)
|
||||
# define BOOST_PYTHON_DYNAMIC_LIB
|
||||
#endif
|
||||
|
||||
#if defined(__MWERKS__) \
|
||||
#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)
|
||||
@@ -107,54 +96,26 @@
|
||||
# else
|
||||
# define BOOST_PYTHON_DECL __declspec(dllimport)
|
||||
# endif
|
||||
|
||||
// MinGW, at least, has some problems exporting template instantiations
|
||||
# if defined(__GNUC__) && __GNUC__ < 3 && !defined(__CYGWIN__)
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
# 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
|
||||
#ifndef BOOST_PYTHON_EXPORT
|
||||
# define BOOST_PYTHON_EXPORT extern
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD
|
||||
#if !defined(BOOST_PYTHON_NO_TEMPLATE_EXPORT)
|
||||
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL instantiation
|
||||
#else
|
||||
# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD
|
||||
#endif
|
||||
|
||||
# ifndef BOOST_PYTHON_EXPORT_TEMPLATE
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template
|
||||
# endif
|
||||
|
||||
# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL
|
||||
|
||||
// Borland C++ Fix/error check:
|
||||
#if defined(__BORLANDC__)
|
||||
# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
|
||||
// problems with std::basic_string and dll RTL:
|
||||
# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)
|
||||
# ifdef BOOST_PYTHON_BUILD_DLL
|
||||
# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL
|
||||
# else
|
||||
# pragma warn defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!
|
||||
# endif
|
||||
# endif
|
||||
# ifndef _RTLDLL
|
||||
// this is harmless for a static link:
|
||||
# define _RWSTD_COMPILE_INSTANTIATE
|
||||
# endif
|
||||
# endif
|
||||
//
|
||||
// VCL support:
|
||||
// if we're building a console app then there can't be any VCL (can there?)
|
||||
# if !defined(__CONSOLE__) && !defined(_NO_VCL)
|
||||
# define BOOST_PYTHON_USE_VCL
|
||||
# endif
|
||||
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef EVAL_DWA2002124_HPP
|
||||
# define EVAL_DWA2002124_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class T> struct undefined;
|
||||
template <class UnaryMetaFunction, class T>
|
||||
struct eval
|
||||
{
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
|
||||
// based on the (non-conforming) MSVC trick from MPL
|
||||
template<bool>
|
||||
struct unarymetafunction_vc : UnaryMetaFunction {};
|
||||
|
||||
// illegal C++ which causes VC to admit that unarymetafunction_vc
|
||||
// can have a nested template:
|
||||
template<>
|
||||
struct unarymetafunction_vc<true>
|
||||
{
|
||||
template<class> struct apply;
|
||||
};
|
||||
|
||||
typedef typename unarymetafunction_vc<
|
||||
::boost::mpl::detail::msvc_never_true<UnaryMetaFunction>::value
|
||||
>::template apply<T>::type type;
|
||||
# else
|
||||
typedef typename UnaryMetaFunction::template apply<T>::type type;
|
||||
# endif
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // EVAL_DWA2002124_HPP
|
||||
@@ -70,10 +70,8 @@ namespace detail
|
||||
|
||||
} // 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
|
||||
BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(class_t<detail::extension_instance>);
|
||||
BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(meta_class<detail::extension_instance>);
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -257,10 +255,8 @@ class python_extension_class_converters
|
||||
return static_cast<T*>(target);
|
||||
}
|
||||
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
|
||||
boost::python::throw_argument_error();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Convert to T*
|
||||
@@ -288,10 +284,9 @@ class python_extension_class_converters
|
||||
return held->ptr();
|
||||
}
|
||||
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
|
||||
boost::python::throw_argument_error();
|
||||
|
||||
return *(PtrType*)obj;
|
||||
}
|
||||
|
||||
// Extract from obj a reference to the PtrType object which is holding a
|
||||
|
||||
117
include/boost/python/detail/if_else.hpp
Normal file
117
include/boost/python/detail/if_else.hpp
Normal file
@@ -0,0 +1,117 @@
|
||||
// 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 IF_ELSE_DWA2002322_HPP
|
||||
# define IF_ELSE_DWA2002322_HPP
|
||||
# include <boost/config.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class T> struct elif_selected;
|
||||
|
||||
template <class T>
|
||||
struct if_selected
|
||||
{
|
||||
template <bool b>
|
||||
struct elif : elif_selected<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class U>
|
||||
struct else_
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
# if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
|
||||
namespace msvc70_aux {
|
||||
|
||||
template< bool > struct inherit_from
|
||||
{
|
||||
template< typename T > struct result
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<> struct inherit_from<true>
|
||||
{
|
||||
template< typename T > struct result
|
||||
{
|
||||
struct type {};
|
||||
};
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct never_true
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
} // namespace msvc70_aux
|
||||
|
||||
#endif // # if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
|
||||
|
||||
template <class T>
|
||||
struct elif_selected
|
||||
{
|
||||
# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407)
|
||||
template <class U> class then;
|
||||
# elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
|
||||
template <class U>
|
||||
struct then : msvc70_aux::inherit_from< msvc70_aux::never_true<U>::value >
|
||||
::template result< if_selected<T> >::type
|
||||
{
|
||||
};
|
||||
# else
|
||||
template <class U>
|
||||
struct then : if_selected<T>
|
||||
{
|
||||
};
|
||||
# endif
|
||||
};
|
||||
|
||||
# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407)
|
||||
template <class T>
|
||||
template <class U>
|
||||
class elif_selected<T>::then : public if_selected<T>
|
||||
{
|
||||
};
|
||||
# endif
|
||||
|
||||
template <bool b> struct if_
|
||||
{
|
||||
template <class T>
|
||||
struct then : if_selected<T>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct if_unselected
|
||||
{
|
||||
template <bool b> struct elif : if_<b>
|
||||
{
|
||||
};
|
||||
|
||||
template <class U>
|
||||
struct else_
|
||||
{
|
||||
typedef U type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct if_<false>
|
||||
{
|
||||
template <class T>
|
||||
struct then : if_unselected
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // IF_ELSE_DWA2002322_HPP
|
||||
@@ -7,6 +7,7 @@
|
||||
# define INDIRECT_TRAITS_DWA2002131_HPP
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/function_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
@@ -24,6 +25,76 @@ struct is_reference_to_const<T const&>
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13012108 // vc7.01 alpha workaround
|
||||
template<class T>
|
||||
struct is_reference_to_const<T const volatile&>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
# endif
|
||||
|
||||
# if 0 // Corresponding code doesn't work on MSVC yet
|
||||
template <class T>
|
||||
struct is_reference_to_function
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_function<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_function<T const&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_function<T volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_function<T const volatile&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
# endif
|
||||
|
||||
template <class T>
|
||||
struct is_pointer_to_function
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_pointer_to_function<T*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_pointer_to_function<T const*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_pointer_to_function<T volatile*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_pointer_to_function<T const volatile*>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = is_function<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_non_const
|
||||
{
|
||||
@@ -49,6 +120,15 @@ struct is_reference_to_volatile<T volatile&>
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13012108 // vc7.01 alpha workaround
|
||||
template <class T>
|
||||
struct is_reference_to_volatile<T const volatile&>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
# endif
|
||||
|
||||
|
||||
template <class T>
|
||||
struct is_reference_to_pointer
|
||||
{
|
||||
@@ -114,6 +194,25 @@ struct is_pointer_help
|
||||
>::type type;
|
||||
};
|
||||
|
||||
# if 0 // doesn't seem to work yet
|
||||
template <class T>
|
||||
struct is_reference_to_function
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type));
|
||||
# endif
|
||||
|
||||
template <class T>
|
||||
struct is_pointer_to_function
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type));
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
typename is_const_help<V>::type reference_to_const_helper(V&);
|
||||
outer_no_type
|
||||
|
||||
@@ -168,6 +168,9 @@ template <class T, class A1, class A2, class A3, class A4, class A5, class A6, c
|
||||
template <class T>
|
||||
struct init_function
|
||||
{
|
||||
# ifdef BOOST_MSVC6_OR_EARLIER
|
||||
# define typename
|
||||
# endif
|
||||
static init* create(signature0) {
|
||||
return new init0<T>;
|
||||
}
|
||||
@@ -175,107 +178,110 @@ struct init_function
|
||||
template <class A1>
|
||||
static init* create(signature1<A1>) {
|
||||
return new init1<T,
|
||||
detail::parameter_traits<A1>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static init* create(signature2<A1, A2>) {
|
||||
return new init2<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static init* create(signature3<A1, A2, A3>) {
|
||||
return new init3<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static init* create(signature4<A1, A2, A3, A4>) {
|
||||
return new init4<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference,
|
||||
typename detail::parameter_traits<A4>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static init* create(signature5<A1, A2, A3, A4, A5>) {
|
||||
return new init5<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference,
|
||||
typename detail::parameter_traits<A4>::const_reference,
|
||||
typename detail::parameter_traits<A5>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static init* create(signature6<A1, A2, A3, A4, A5, A6>) {
|
||||
return new init6<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference,
|
||||
typename detail::parameter_traits<A4>::const_reference,
|
||||
typename detail::parameter_traits<A5>::const_reference,
|
||||
typename detail::parameter_traits<A6>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static init* create(signature7<A1, A2, A3, A4, A5, A6, A7>) {
|
||||
return new init7<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference,
|
||||
typename detail::parameter_traits<A4>::const_reference,
|
||||
typename detail::parameter_traits<A5>::const_reference,
|
||||
typename detail::parameter_traits<A6>::const_reference,
|
||||
typename detail::parameter_traits<A7>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static init* create(signature8<A1, A2, A3, A4, A5, A6, A7, A8>) {
|
||||
return new init8<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference,
|
||||
detail::parameter_traits<A8>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference,
|
||||
typename detail::parameter_traits<A4>::const_reference,
|
||||
typename detail::parameter_traits<A5>::const_reference,
|
||||
typename detail::parameter_traits<A6>::const_reference,
|
||||
typename detail::parameter_traits<A7>::const_reference,
|
||||
typename detail::parameter_traits<A8>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static init* create(signature9<A1, A2, A3, A4, A5, A6, A7, A8, A9>) {
|
||||
return new init9<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference,
|
||||
detail::parameter_traits<A8>::const_reference,
|
||||
detail::parameter_traits<A9>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference,
|
||||
typename detail::parameter_traits<A4>::const_reference,
|
||||
typename detail::parameter_traits<A5>::const_reference,
|
||||
typename detail::parameter_traits<A6>::const_reference,
|
||||
typename detail::parameter_traits<A7>::const_reference,
|
||||
typename detail::parameter_traits<A8>::const_reference,
|
||||
typename detail::parameter_traits<A9>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static init* create(signature10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>) {
|
||||
return new init10<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference,
|
||||
detail::parameter_traits<A8>::const_reference,
|
||||
detail::parameter_traits<A9>::const_reference,
|
||||
detail::parameter_traits<A10>::const_reference>;
|
||||
typename detail::parameter_traits<A1>::const_reference,
|
||||
typename detail::parameter_traits<A2>::const_reference,
|
||||
typename detail::parameter_traits<A3>::const_reference,
|
||||
typename detail::parameter_traits<A4>::const_reference,
|
||||
typename detail::parameter_traits<A5>::const_reference,
|
||||
typename detail::parameter_traits<A6>::const_reference,
|
||||
typename detail::parameter_traits<A7>::const_reference,
|
||||
typename detail::parameter_traits<A8>::const_reference,
|
||||
typename detail::parameter_traits<A9>::const_reference,
|
||||
typename detail::parameter_traits<A10>::const_reference>;
|
||||
}
|
||||
#ifdef BOOST_MSVC6_OR_EARLIER
|
||||
# undef typename
|
||||
#endif
|
||||
};
|
||||
|
||||
class BOOST_PYTHON_DECL init : public function
|
||||
@@ -293,7 +299,7 @@ struct init0 : init
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("")))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self
|
||||
);
|
||||
}
|
||||
@@ -308,7 +314,7 @@ struct init1 : init
|
||||
{
|
||||
PyObject* a1;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &a1))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>()))
|
||||
);
|
||||
@@ -325,7 +331,7 @@ struct init2 : init
|
||||
PyObject* a1;
|
||||
PyObject* a2;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>()))
|
||||
@@ -344,7 +350,7 @@ struct init3 : init
|
||||
PyObject* a2;
|
||||
PyObject* a3;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOO"), &a1, &a2, &a3))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
@@ -365,7 +371,7 @@ struct init4 : init
|
||||
PyObject* a3;
|
||||
PyObject* a4;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOO"), &a1, &a2, &a3, &a4))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
@@ -388,7 +394,7 @@ struct init5 : init
|
||||
PyObject* a4;
|
||||
PyObject* a5;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOO"), &a1, &a2, &a3, &a4, &a5))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
@@ -413,7 +419,7 @@ struct init6 : init
|
||||
PyObject* a5;
|
||||
PyObject* a6;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
@@ -440,7 +446,7 @@ struct init7 : init
|
||||
PyObject* a6;
|
||||
PyObject* a7;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
@@ -469,7 +475,7 @@ struct init8 : init
|
||||
PyObject* a7;
|
||||
PyObject* a8;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
@@ -500,7 +506,7 @@ struct init9 : init
|
||||
PyObject* a8;
|
||||
PyObject* a9;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
@@ -533,7 +539,7 @@ struct init10 : init
|
||||
PyObject* a9;
|
||||
PyObject* a10;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10))
|
||||
throw argument_error();
|
||||
throw_argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
|
||||
95
include/boost/python/detail/member_function_cast.hpp
Normal file
95
include/boost/python/detail/member_function_cast.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// 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 MEMBER_FUNCTION_CAST_DWA2002311_HPP
|
||||
# define MEMBER_FUNCTION_CAST_DWA2002311_HPP
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/mpl/aux_/preprocessor.hpp>
|
||||
# include <boost/preprocessor/comma_if.hpp>
|
||||
# include <boost/preprocessor/dec.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class S, class FT>
|
||||
struct cast_helper
|
||||
{
|
||||
struct yes_helper
|
||||
{
|
||||
static FT stage3(FT x) { return x; }
|
||||
};
|
||||
|
||||
struct no_helper
|
||||
{
|
||||
template <class T>
|
||||
static T stage3(T x) { return x; }
|
||||
};
|
||||
|
||||
static yes_helper stage2(S*) { return yes_helper(); }
|
||||
static no_helper stage2(void*) { return no_helper(); }
|
||||
};
|
||||
|
||||
struct non_member_function_cast_impl
|
||||
{
|
||||
template <class T>
|
||||
static non_member_function_cast_impl stage1(T) { return non_member_function_cast_impl(); }
|
||||
|
||||
template <class T>
|
||||
static non_member_function_cast_impl stage2(T) { return non_member_function_cast_impl(); }
|
||||
|
||||
template <class T>
|
||||
T stage3(T x) { return x; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct member_function_cast_impl
|
||||
{
|
||||
# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
template <class U>
|
||||
static non_member_function_cast_impl stage1(U)
|
||||
{
|
||||
return non_member_function_cast_impl();
|
||||
}
|
||||
# endif
|
||||
|
||||
// Member functions
|
||||
# ifndef BOOST_PYTHON_GENERATE_CODE
|
||||
# include <boost/python/preprocessed/member_function_cast.hpp>
|
||||
# endif
|
||||
|
||||
# define BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1(args, cv) \
|
||||
template < \
|
||||
class S \
|
||||
, class R \
|
||||
BOOST_PP_COMMA_IF(BOOST_PP_DEC(args)) BOOST_MPL_TEMPLATE_PARAMETERS(1, args, class A) \
|
||||
> \
|
||||
static cast_helper<S,BOOST_PYTHON_FN(T::*,1,args)cv()> \
|
||||
stage1(BOOST_PYTHON_FN(S::*,1,args)cv()) \
|
||||
{ \
|
||||
return cast_helper<S,BOOST_PYTHON_FN(T::*,1,args)cv()>(); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1)
|
||||
};
|
||||
|
||||
|
||||
template <class T, class SF>
|
||||
struct member_function_cast
|
||||
# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
: member_function_cast_impl<T>
|
||||
# else
|
||||
: mpl::select_type<
|
||||
is_member_function_pointer<SF>::value
|
||||
, member_function_cast_impl<T>
|
||||
, non_member_function_cast_impl
|
||||
>::type
|
||||
# endif
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // MEMBER_FUNCTION_CAST_DWA2002311_HPP
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
#include <boost/type.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <boost/type_traits/array_traits.hpp>
|
||||
#include <boost/type_traits/reference_traits.hpp>
|
||||
//
|
||||
// Fix for MSVC's broken typeid() implementation which doesn't strip
|
||||
// decoration. This fix doesn't handle cv-qualified array types. It
|
||||
@@ -62,35 +63,35 @@ inline typeinfo typeid_nonref(boost::type<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& (*)())
|
||||
inline typeinfo typeid_ref(T&(*)())
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_array(bool_t<false>, boost::type<T>* = 0)
|
||||
inline typeinfo array_ref_typeid(bool_t<true>, bool_t<false>, boost::type<T>* = 0)
|
||||
{
|
||||
typedef T (*x)();
|
||||
return typeid_ref((boost::type<T>*)0, x(0));
|
||||
return typeid_ref((T&(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_array(bool_t<true>, boost::type<T>* = 0)
|
||||
inline typeinfo array_ref_typeid(bool_t<false>, bool_t<true>, boost::type<T>* = 0)
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
return typeid_ref((T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo array_ref_typeid(bool_t<false>, bool_t<false>, boost::type<T>* = 0)
|
||||
{
|
||||
return typeid_ref((T&(*)())0);
|
||||
}
|
||||
|
||||
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);
|
||||
typedef bool_t<is_array<T>::value> array_tag;
|
||||
typedef bool_t<is_reference<T>::value> ref_tag;
|
||||
return array_ref_typeid(array_tag(), ref_tag(), (boost::type<T>*)0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
15
include/boost/python/detail/not_specified.hpp
Normal file
15
include/boost/python/detail/not_specified.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
// 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 NOT_SPECIFIED_DWA2002321_HPP
|
||||
# define NOT_SPECIFIED_DWA2002321_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct not_specified {};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // NOT_SPECIFIED_DWA2002321_HPP
|
||||
36
include/boost/python/detail/pointee.hpp
Normal file
36
include/boost/python/detail/pointee.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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 POINTEE_DWA2002323_HPP
|
||||
# define POINTEE_DWA2002323_HPP
|
||||
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <bool is_ptr = true>
|
||||
struct pointee_impl
|
||||
{
|
||||
template <class T> struct apply : remove_pointer<T> {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pointee_impl<false>
|
||||
{
|
||||
template <class T> struct apply
|
||||
{
|
||||
typedef typename T::element_type type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct pointee
|
||||
: pointee_impl<is_pointer<T>::value>::template apply<T>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // POINTEE_DWA2002323_HPP
|
||||
110
include/boost/python/detail/preprocessor.hpp
Normal file
110
include/boost/python/detail/preprocessor.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
// 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 PREPROCESSOR_DWA200247_HPP
|
||||
# define PREPROCESSOR_DWA200247_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/preprocessor/tuple/to_list.hpp>
|
||||
# include <boost/preprocessor/tuple/elem.hpp>
|
||||
# include <boost/preprocessor/list/for_each.hpp>
|
||||
# include <boost/preprocessor/repeat_from_to_2nd.hpp>
|
||||
# include <boost/preprocessor/inc.hpp>
|
||||
# include <boost/preprocessor/empty.hpp>
|
||||
# include <boost/preprocessor/enum.hpp>
|
||||
# include <boost/preprocessor/expr_if.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
# define BOOST_PYTHON_CONST() const
|
||||
# define BOOST_PYTHON_VOLATILE() volatile
|
||||
# define BOOST_PYTHON_CONST_VOLATILE() const volatile
|
||||
|
||||
# define BOOST_PYTHON_ALL_CV \
|
||||
BOOST_PP_TUPLE_TO_LIST(4, (BOOST_PP_EMPTY \
|
||||
, BOOST_PYTHON_CONST \
|
||||
, BOOST_PYTHON_VOLATILE \
|
||||
, BOOST_PYTHON_CONST_VOLATILE))
|
||||
|
||||
# if !defined(__MWERKS__) || __MWERKS__ > 0x2407
|
||||
# define BOOST_PYTHON_MEMBER_FUNCTION_CV BOOST_PYTHON_ALL_CV
|
||||
# else
|
||||
# define BOOST_PYTHON_MEMBER_FUNCTION_CV BOOST_PP_TUPLE_TO_LIST(1, (BOOST_PP_EMPTY))
|
||||
# endif
|
||||
|
||||
#ifndef BOOST_PYTHON_DEBUGGABLE_ARITY
|
||||
# define BOOST_PYTHON_DEBUGGABLE_ARITY 15
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_MAX_ARITY
|
||||
# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245
|
||||
// Generate at least two more arguments just to test the syntax
|
||||
# define BOOST_PYTHON_MAX_ARITY 17
|
||||
# else
|
||||
// Current EDG compilers have a really slow preprocessor which makes
|
||||
// it important not to generate new functions with it unless
|
||||
// absolutely neccessary
|
||||
# define BOOST_PYTHON_MAX_ARITY BOOST_PYTHON_DEBUGGABLE_ARITY
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_PYTHON_GENERATE_CODE
|
||||
# undef BOOST_STATIC_CONSTANT
|
||||
# define BOOST_PYTHON_ARITY_START 0
|
||||
# define BOOST_PYTHON_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY)
|
||||
# define BOOST_PYTHON_MF_ARITY_START 1
|
||||
# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY))
|
||||
#else
|
||||
# define BOOST_PYTHON_ARITY_START BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY)
|
||||
# define BOOST_PYTHON_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY)
|
||||
# define BOOST_PYTHON_MF_ARITY_START BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY))
|
||||
# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY))
|
||||
#endif
|
||||
|
||||
#if BOOST_PYTHON_MAX_ARITY > BOOST_PYTHON_DEBUGGABLE_ARITY
|
||||
|
||||
# define BOOST_PYTHON_FN(inner,start,count) \
|
||||
R(inner)(BOOST_MPL_TEMPLATE_PARAMETERS(start,count,A))
|
||||
|
||||
# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) \
|
||||
BOOST_PP_REPEAT_FROM_TO_2ND( \
|
||||
BOOST_PYTHON_ARITY_START, BOOST_PYTHON_ARITY_FINISH \
|
||||
, function, data)
|
||||
|
||||
# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data) \
|
||||
BOOST_PP_REPEAT_FROM_TO_2ND( \
|
||||
BOOST_PYTHON_MF_ARITY_START, BOOST_PYTHON_MF_ARITY_FINISH \
|
||||
, function, data)
|
||||
|
||||
# define BOOST_PYTHON_REPEAT_PMF_CV(index, function, cv) \
|
||||
BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,cv)
|
||||
|
||||
# define BOOST_PYTHON_REPEAT_MF_CV_2ND(function) \
|
||||
BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_REPEAT_PMF_CV,function,BOOST_PYTHON_MEMBER_FUNCTION_CV)
|
||||
|
||||
# define BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(function) \
|
||||
BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_REPEAT_PMF_CV,function,BOOST_PYTHON_ALL_CV)
|
||||
|
||||
#define BOOST_PYTHON_NUMBER_PAIR(Index, Pair) \
|
||||
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,Pair),Index) \
|
||||
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,1,Pair),Index)
|
||||
|
||||
#define BOOST_PYTHON_ENUM_PARAMS2(N, Pair) BOOST_PP_ENUM(N, BOOST_PYTHON_NUMBER_PAIR, Pair)
|
||||
|
||||
# define BOOST_PYTHON_PROJECT_1ST(a1,a2) a1
|
||||
# define BOOST_PYTHON_PROJECT_2ND(a1,a2) a2
|
||||
#else
|
||||
|
||||
# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data)
|
||||
# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data)
|
||||
# define BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(function)
|
||||
# define BOOST_PYTHON_REPEAT_MF_CV_2ND(function)
|
||||
# define BOOST_PYTHON_REPEAT_PMF_CV(index, function, cv)
|
||||
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // PREPROCESSOR_DWA200247_HPP
|
||||
@@ -1,183 +0,0 @@
|
||||
#error obsolete
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2000
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE regex_libary_include.hpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers.
|
||||
* Note this is an internal header file included
|
||||
* by regex.hpp, do not include on its own.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
#define BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
#ifndef BOOST_REGEX_NO_LIB
|
||||
|
||||
#if defined(BOOST_MSVC) && !defined(BOOST_REGEX_BUILD_DLL)
|
||||
#ifdef __SGI_STL_PORT
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#if defined(_DEBUG) && defined(__STL_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300ddl.lib")
|
||||
#elif defined(_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc6-stlport-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc6-stlport-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#if defined(_DEBUG) && defined(__STL_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300ddm.lib")
|
||||
#elif defined(_DEBUG)
|
||||
#pragma comment(lib, "vc6-stlport-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-stlport-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
// STLPort does not support single threaded builds:
|
||||
#error STLPort does not support single threaded builds
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#elif _MSC_VER < 1300
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc6-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc6-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc6-re300d.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc6-re300.lib")
|
||||
#endif //_DEBUG
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#else
|
||||
#ifdef _DLL
|
||||
// All these are multithreaded:
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300dl.lib")
|
||||
#elif defined(BOOST_REGEX_STATIC_LINK)
|
||||
// static regex lib, dll runtime
|
||||
#pragma comment(lib, "vc7-re300ls.lib")
|
||||
#else // DEBUG
|
||||
#pragma comment(lib, "vc7-re300l.lib")
|
||||
#endif // _DEBUG
|
||||
#else // _DLL
|
||||
#ifdef _MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300dm.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc7-re300m.lib")
|
||||
#endif //_DEBUG
|
||||
#else //_MT
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "vc7-re300d.lib")
|
||||
#else //_DEBUG
|
||||
#pragma comment(lib, "vc7-re300.lib")
|
||||
#endif //_DEBUG
|
||||
#endif //_MT
|
||||
#endif //_DLL
|
||||
#endif // __SGI_STL_PORT
|
||||
#endif //BOOST_MSVC
|
||||
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(BOOST_REGEX_BUILD_DLL)
|
||||
|
||||
#if __BORLANDC__ < 0x550
|
||||
|
||||
#ifdef BOOST_REGEX_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "bcb4re300lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "bcb4re300v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb4re300lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb4re300l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb4re300m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb4re300.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#else // C++ Builder 5:
|
||||
|
||||
#ifdef BOOST_REGEX_USE_VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#pragma comment(lib, "bcb5re300lv.lib")
|
||||
#else
|
||||
#pragma comment(lib, "bcb5re300v.lib")
|
||||
#endif
|
||||
|
||||
#else // VCL
|
||||
|
||||
#ifdef _RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb5re300lm.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb5re300l.lib")
|
||||
#endif // __MT__
|
||||
#else //_RTLDLL
|
||||
#ifdef __MT__
|
||||
#pragma comment(lib, "bcb5re300m.lib")
|
||||
#else // __MT__
|
||||
#pragma comment(lib, "bcb5re300.lib")
|
||||
#endif // __MT__
|
||||
#endif // _RTLDLL
|
||||
|
||||
#endif // VCL
|
||||
|
||||
#endif
|
||||
|
||||
#endif //__BORLANDC__
|
||||
|
||||
#endif //BOOST_REGEX_NO_LIB
|
||||
|
||||
#endif // BOOST_REGEX_LIBRARY_INCLUDE_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,217 +0,0 @@
|
||||
// (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
|
||||
|
||||
@@ -68,13 +68,6 @@ struct unwind_helper<false>
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
|
||||
34
include/boost/python/detail/void_ptr.hpp
Normal file
34
include/boost/python/detail/void_ptr.hpp
Normal 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 VOID_PTR_DWA200239_HPP
|
||||
# define VOID_PTR_DWA200239_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class U>
|
||||
inline U& void_ptr_to_reference(void const volatile* p, U&(*)())
|
||||
{
|
||||
return *(U*)p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void write_void_ptr(void const volatile* storage, void* ptr, T*)
|
||||
{
|
||||
*(T**)storage = (T*)ptr;
|
||||
}
|
||||
|
||||
// writes U(ptr) into the storage
|
||||
template <class U>
|
||||
inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)())
|
||||
{
|
||||
// stripping CV qualification suppresses warnings on older EDGs
|
||||
typedef typename remove_cv<U>::type u_stripped;
|
||||
write_void_ptr(storage, ptr, u_stripped(0));
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // VOID_PTR_DWA200239_HPP
|
||||
@@ -9,6 +9,8 @@
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/type_traits/ice.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
@@ -21,34 +23,16 @@ namespace boost { namespace python { namespace detail {
|
||||
// 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 <class F>
|
||||
inline PyObject* wrap_function_aux(F f, PyObject*) { return f; }
|
||||
|
||||
template<>
|
||||
struct wrap_function_select<false>
|
||||
{
|
||||
template <class F>
|
||||
static F execute(F f)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
};
|
||||
template <class F>
|
||||
inline PyObject* wrap_function_aux(F f, ...) { return make_function(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);
|
||||
return wrap_function_aux(f, f);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -36,20 +36,25 @@
|
||||
//
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# if defined(__GNUC__) && defined(__CYGWIN__)
|
||||
|
||||
# define SIZEOF_LONG 4
|
||||
|
||||
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2
|
||||
|
||||
typedef int pid_t;
|
||||
|
||||
# define WORD_BIT 32
|
||||
# define hypot _hypot
|
||||
# include <stdio.h>
|
||||
|
||||
# if PY_MAJOR_VERSION < 2
|
||||
# define HAVE_CLOCK
|
||||
# define HAVE_STRFTIME
|
||||
# define HAVE_STRERROR
|
||||
# endif
|
||||
|
||||
# define NT_THREADS
|
||||
# if __GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3
|
||||
# define WITH_THREAD
|
||||
# endif
|
||||
|
||||
# ifndef NETSCAPE_PI
|
||||
# define USE_SOCKET
|
||||
# endif
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
struct error_already_set {};
|
||||
struct argument_error : error_already_set {};
|
||||
struct BOOST_PYTHON_DECL error_already_set {};
|
||||
struct BOOST_PYTHON_DECL argument_error : error_already_set {};
|
||||
|
||||
// Handles exceptions caught just before returning to Python code.
|
||||
// Returns true iff an exception was caught.
|
||||
@@ -35,14 +35,17 @@ inline void handle_exception()
|
||||
handle_exception(detail::rethrow);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x);
|
||||
BOOST_PYTHON_DECL PyObject* expect_non_null_impl(PyObject* x);
|
||||
|
||||
template <class T>
|
||||
T* expect_non_null(T* x)
|
||||
inline T* expect_non_null(T* x)
|
||||
{
|
||||
return (T*)expect_non_null((PyObject*)x);
|
||||
return (T*)expect_non_null_impl((PyObject*)x);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_argument_error();
|
||||
BOOST_PYTHON_DECL void throw_error_already_set();
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // ERRORS_DWA052500_H_
|
||||
|
||||
@@ -39,7 +39,7 @@ struct from_python<PyObject* const&>
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
from_python<T>::from_python(PyObject* source)
|
||||
inline from_python<T>::from_python(PyObject* source)
|
||||
: base(source)
|
||||
{
|
||||
}
|
||||
|
||||
22
include/boost/python/has_back_reference.hpp
Normal file
22
include/boost/python/has_back_reference.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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 HAS_BACK_REFERENCE_DWA2002323_HPP
|
||||
# define HAS_BACK_REFERENCE_DWA2002323_HPP
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// traits class which users can specialize to indicate that a class
|
||||
// contains a back-reference to its owning PyObject*
|
||||
template <class T>
|
||||
struct has_back_reference
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // HAS_BACK_REFERENCE_DWA2002323_HPP
|
||||
28
include/boost/python/implicit.hpp
Normal file
28
include/boost/python/implicit.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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 IMPLICIT_DWA2002325_HPP
|
||||
# define IMPLICIT_DWA2002325_HPP
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/python/converter/implicit.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class Source, class Target>
|
||||
void implicitly_convertible(boost::type<Source>* = 0, boost::type<Target>* = 0)
|
||||
{
|
||||
typedef converter::implicit<Source,Target> functions;
|
||||
|
||||
converter::registry::push_back(
|
||||
&functions::convertible
|
||||
, &functions::construct
|
||||
, converter::undecorated_type_id<Target>());
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // IMPLICIT_DWA2002325_HPP
|
||||
@@ -35,8 +35,8 @@ objects::function* make_function(F f, Policies const& policies)
|
||||
, detail::arg_tuple_size<F>::value);
|
||||
}
|
||||
|
||||
template <class T, class ArgList, class Generator>
|
||||
objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0)
|
||||
template <class ArgList, class Holder>
|
||||
objects::function* make_constructor(Holder* = 0, ArgList* = 0)
|
||||
{
|
||||
enum { nargs = mpl::size<ArgList>::value };
|
||||
|
||||
@@ -44,11 +44,25 @@ objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0)
|
||||
objects::py_function(
|
||||
::boost::bind<PyObject*>(detail::caller(),
|
||||
objects::make_holder<nargs>
|
||||
::template apply<T,Generator,ArgList>::execute
|
||||
::template apply<Holder,ArgList>::execute
|
||||
, _1, _2, default_call_policies()))
|
||||
, nargs + 1);
|
||||
}
|
||||
|
||||
template <class ArgList, class Holder, class Policies>
|
||||
objects::function* make_constructor(Policies const& policies, Holder* = 0, ArgList* = 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<Holder,ArgList>::execute
|
||||
, _1, _2, policies))
|
||||
, nargs + 1);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // MAKE_FUNCTION_DWA20011221_HPP
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
# 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 {
|
||||
@@ -38,6 +37,8 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable
|
||||
|
||||
// Retrieve the underlying object
|
||||
ref object() const { return m_object; }
|
||||
void add_property(char const* name, ref const& fget);
|
||||
void add_property(char const* name, ref const& fget, ref const& fset);
|
||||
private:
|
||||
ref m_object;
|
||||
};
|
||||
@@ -55,27 +56,11 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable
|
||||
virtual void* holds(converter::undecorated_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;
|
||||
};
|
||||
// This macro is needed for implementation of derived holders
|
||||
# define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward<A##N>::type)(a##N)
|
||||
|
||||
// Each extension instance will be one of these
|
||||
struct instance
|
||||
@@ -84,20 +69,6 @@ struct instance
|
||||
instance_holder* objects;
|
||||
};
|
||||
|
||||
// Given an undecorated 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::undecorated_type_id_t);
|
||||
|
||||
// This produces a function with the right signature for use in from_python conversions
|
||||
template <class T>
|
||||
struct instance_finder
|
||||
{
|
||||
static inline void* execute(PyObject* p)
|
||||
{
|
||||
return find_instance_impl(p, converter::undecorated_type_id<T>());
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_DECL ref class_metatype();
|
||||
BOOST_PYTHON_DECL ref class_type();
|
||||
|
||||
|
||||
@@ -10,27 +10,11 @@
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/object/find_instance.hpp>
|
||||
# include <boost/python/object/inheritance.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
|
||||
class_wrapper<Derived> m_wrapper;
|
||||
};
|
||||
|
||||
//
|
||||
// Implementation details
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// register_base_of<T> -
|
||||
@@ -85,13 +69,17 @@ struct register_base_of
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// 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>
|
||||
class_converters<Derived,Bases>::class_converters(ref const& type_object)
|
||||
: m_wrapper(type_object)
|
||||
inline void register_class_from_python(Derived* = 0, Bases* = 0)
|
||||
{
|
||||
converter::registry::insert(
|
||||
&instance_finder<Derived>::execute
|
||||
, converter::undecorated_type_id<Derived>());
|
||||
// cause the static registration to be instantiated. Can't just
|
||||
// cast it to void on all compilers; some will skip its
|
||||
// initialization.
|
||||
void const* ignored = &instance_finder<Derived>::registration;
|
||||
(void)ignored;
|
||||
|
||||
// register all up/downcasts here
|
||||
register_dynamic_id<Derived>();
|
||||
|
||||
@@ -6,15 +6,14 @@
|
||||
#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>
|
||||
template <class T, class Holder>
|
||||
struct class_wrapper
|
||||
: to_python_converter<T, class_wrapper<T> >
|
||||
: to_python_converter<T,class_wrapper<T,Holder> >
|
||||
{
|
||||
class_wrapper(ref const& type_)
|
||||
: m_class_object_keeper(type_)
|
||||
@@ -39,7 +38,7 @@ struct class_wrapper
|
||||
|
||||
// Build a value_holder to contain the object using the copy
|
||||
// constructor
|
||||
value_holder<T>* p = new value_holder<T>(raw_result, cref(x));
|
||||
Holder* p = new Holder(raw_result, cref(x));
|
||||
|
||||
// Install it in the instance
|
||||
p->install(raw_result);
|
||||
@@ -53,8 +52,8 @@ struct class_wrapper
|
||||
static PyTypeObject* m_class_object;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
PyTypeObject* class_wrapper<T>::m_class_object;
|
||||
template <class T, class Holder>
|
||||
PyTypeObject* class_wrapper<T,Holder>::m_class_object;
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
|
||||
40
include/boost/python/object/find_instance.hpp
Normal file
40
include/boost/python/object/find_instance.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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 FIND_INSTANCE_DWA2002312_HPP
|
||||
# define FIND_INSTANCE_DWA2002312_HPP
|
||||
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
// Given an undecorated 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::undecorated_type_id_t);
|
||||
|
||||
// This produces a function with the right signature for use in from_python conversions
|
||||
template <class T>
|
||||
struct instance_finder
|
||||
{
|
||||
instance_finder()
|
||||
{
|
||||
converter::registry::insert(&execute, converter::undecorated_type_id<T>());
|
||||
}
|
||||
|
||||
static instance_finder const registration;
|
||||
private:
|
||||
static inline void* execute(PyObject* p)
|
||||
{
|
||||
return find_instance_impl(p, converter::undecorated_type_id<T>());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
instance_finder<T> const instance_finder<T>::registration;
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // FIND_INSTANCE_DWA2002312_HPP
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user