diff --git a/Jamfile b/Jamfile deleted file mode 100644 index fec34d51..00000000 --- a/Jamfile +++ /dev/null @@ -1,53 +0,0 @@ -subproject libs/python ; - -# bring in the rules for python -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -PYTHON_PROPERTIES - += <*>"-inline deferred" - <*>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers - BOOST_PYTHON_DYNAMIC_LIB - BOOST_PYTHON_V2 - ; - -{ - dll bpl - : - src/converter/from_python.cpp - src/converter/registry.cpp - src/converter/type_id.cpp - src/object/class.cpp - src/object/function.cpp - src/object/inheritance.cpp - src/errors.cpp - src/module.cpp - src/objects.cpp - src/converter/builtin_converters.cpp - : - $(PYTHON_PROPERTIES) - BOOST_PYTHON_SOURCE - ; - - extension m1 : test/m1.cpp bpl # BOOST_PYTHON_TRACE - : - : debug-python - ; - - extension m2 : test/m2.cpp bpl # BOOST_PYTHON_TRACE - : - : debug-python ; - - boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; - - extension builtin_converters_ext : test/test_builtin_converters.cpp bpl - : - : debug-python - ; - - boost-python-runtest test_builtin_converters : test/test_builtin_converters.py - builtin_converters_ext - : - : debug-python - ; -} diff --git a/build/Jamfile b/build/Jamfile deleted file mode 100644 index 1ea3665d..00000000 --- a/build/Jamfile +++ /dev/null @@ -1,156 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# Boost.Python build and test Jamfile -# -# To run all tests quietly: jam test -# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test -# -# Declares the following targets: -# 1. libboost_python, a static link library to be linked with all -# Boost.Python modules -# -# 2. pairs of test targets of the form .test and .run -# .test runs the test when it is out-of-date, and the "test" -# pseudotarget depends on it. .run runs -# a test unconditionally, and can be used to force a test to run.. Each -# test target builds one or more Boost.Python modules and runs a Python -# script to test them. The test names are: -# -# from ../test -# -# comprehensive - a comprehensive test of Boost.Python features -# -# from ../example: -# abstract - -# getting_started1 - -# getting_started2 - -# simple_vector - -# do_it_yourself_convts - -# pickle1 - -# pickle2 - -# pickle3 - -# -# dvect1 - -# dvect2 - -# ivect1 - -# ivect2 - -# noncopyable - -# -# subproject-specific environment/command-line variables: -# -# PYTHON - How to invoke the Python interpreter. Defaults to "python" -# -# PYTHON_ROOT - Windows only: where Python is installed. Defaults to "c:/tools/python" -# -# PYTHON_VERSION - Version of Python. Defaults to "2.1" on Windows, "1.5" on Unix -# -# PYTHON_TEST_ARGS - specifies arguments to be passed to test scripts on -# the command line. "-v" can be useful if you want to -# see the output of successful tests. -# -# PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for -# the dvect and ivect tests above. - -# declare the location of this subproject relative to the root -subproject libs/python/build ; - -# bring in the rules for python -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_DYNAMIC_LIB ; - -####################### -rule bpl-test ( test-name : sources + ) -{ - boost-python-test $(test-name) : $(sources) libboost_python ; -} - -####################### - -# -# Declare the boost python static link library -# - -# Base names of the source files for libboost_python -local CPP_SOURCES = - types classes conversions extension_class functions - init_function module_builder objects cross_module errors - ; - -lib libboost_python_static : ../src/$(CPP_SOURCES).cpp - # requirements - : $(BOOST_PYTHON_INCLUDES) - true - BOOST_PYTHON_STATIC_LIB=1 - $(PYTHON_PROPERTIES) ; - -dll libboost_python - # $(SUFDLL[1]) - : ../src/$(CPP_SOURCES).cpp - # requirements - : $(BOOST_PYTHON_INCLUDES) - true - dynamic - BOOST_PYTHON_HAS_DLL_RUNTIME=1 - $(PYTHON_PROPERTIES) - ; - -############# comprehensive module and test ########### -bpl-test boost_python_test - : ../test/comprehensive.cpp ; - -boost-python-runtest comprehensive - : ../test/comprehensive.py boost_python_test libboost_python ; - -############# simple tests from ../example ############ - -rule boost-python-example-runtest ( name ) -{ - bpl-test $(name) - : ../example/$(name).cpp ; - - boost-python-runtest $(name) - : ../example/test_$(name).py $(name) ; -} - - -boost-python-example-runtest abstract ; -boost-python-example-runtest getting_started1 ; -boost-python-example-runtest getting_started2 ; -boost-python-example-runtest simple_vector ; -boost-python-example-runtest do_it_yourself_convts ; -boost-python-example-runtest pickle1 ; -boost-python-example-runtest pickle2 ; -boost-python-example-runtest pickle3 ; - - -bpl-test ivect : ../example/ivect.cpp ; -bpl-test dvect : ../example/dvect.cpp ; -bpl-test noncopyable_export : ../example/noncopyable_export.cpp ; -bpl-test noncopyable_import : ../example/noncopyable_import.cpp ; - -############## cross-module tests from ../example ########## - -# A simple rule to build a test which depends on multiple modules in the PYTHONPATH -rule boost-python-multi-example-runtest ( test-name : modules + ) -{ - boost-python-runtest $(test-name) - : ../example/tst_$(test-name).py $(modules) libboost_python - : : : $(PYTHON_VECT_ITERATIONS) ; -} - -PYTHON_VECT_ITERATIONS ?= 10 ; - -boost-python-multi-example-runtest dvect1 : ivect dvect ; -boost-python-multi-example-runtest dvect2 : ivect dvect ; - -boost-python-multi-example-runtest ivect1 : ivect dvect ; -boost-python-multi-example-runtest ivect2 : ivect dvect ; - -boost-python-multi-example-runtest - noncopyable : noncopyable_import noncopyable_export ; - diff --git a/build/bpl_static.dsp b/build/bpl_static.dsp deleted file mode 100644 index ca70236d..00000000 --- a/build/bpl_static.dsp +++ /dev/null @@ -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 diff --git a/build/build.dsw b/build/build.dsw deleted file mode 100644 index 8de38493..00000000 --- a/build/build.dsw +++ /dev/null @@ -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> -{{{ -}}} - -############################################################################### - diff --git a/build/build.opt b/build/build.opt deleted file mode 100644 index 89eb84a7..00000000 Binary files a/build/build.opt and /dev/null differ diff --git a/build/como.mak b/build/como.mak deleted file mode 100644 index edf05f83..00000000 --- a/build/como.mak +++ /dev/null @@ -1,59 +0,0 @@ -# Revision History: -# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) UNTESTED! -# 06 Mar 01 Fixed typo in use of "PYTHON_LIB" (Dave Abrahams) -# 04 Mar 01 Changed library name to libboost_python.a (David Abrahams) - -LIBSRC = \ - classes.cpp \ - conversions.cpp \ - cross_module.cpp \ - errors.cpp \ - extension_class.cpp \ - functions.cpp \ - init_function.cpp \ - module_builder.cpp \ - objects.cpp \ - types.cpp - -LIBOBJ = $(LIBSRC:.cpp=.o) -OBJ = $(LIBOBJ) - - -ifeq "$(OS)" "Windows_NT" -PYTHON_LIB=c:/tools/python/libs/python15.lib -INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -Ic:/tools/python/include -MODULE_EXTENSION=dll -else -INC = -I/usr/local/include/python1.5 -MODULE_EXTENSION=so -endif - -%.o: ../src/%.cpp - como --pic $(INC) -o $*.o -c $< - -%.d: ../src/%.cpp - @echo creating $@ - @set -e; como -M $(INC) -c $< \ - | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ - [ -s $@ ] || rm -f $@ - -getting_started1: getting_started1.o libboost_python.a - como-dyn-link -o ../example/getting_started1.$(MODULE_EXTENSION) $(PYTHON_LIB) getting_started1.o -L. -lboost_python - ln -s ../test/doctest.py ../example - python ../example/test_getting_started1.py - -getting_started1.o: ../example/getting_started1.cpp - como --pic $(INC) -o $*.o -c $< - -clean: - rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out - -libboost_python.a: $(LIBOBJ) - rm -f libboost_python.a - ar cq libboost_python.a $(LIBOBJ) - -DEP = $(OBJ:.o=.d) - -ifneq "$(MAKECMDGOALS)" "clean" -include $(DEP) -endif diff --git a/build/example1/example1.dsp b/build/example1/example1.dsp deleted file mode 100644 index 4d95aa97..00000000 --- a/build/example1/example1.dsp +++ /dev/null @@ -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 diff --git a/build/filemgr.py b/build/filemgr.py deleted file mode 100644 index 93cef1cb..00000000 --- a/build/filemgr.py +++ /dev/null @@ -1,146 +0,0 @@ -# Revision history: -# 12 Apr 01 use os.path, shutil -# Initial version: R.W. Grosse-Kunstleve - -bpl_src = "/libs/python/src" -bpl_tst = "/libs/python/test" -bpl_exa = "/libs/python/example" -files = ( -bpl_src + "/classes.cpp", -bpl_src + "/conversions.cpp", -bpl_src + "/errors.cpp", -bpl_src + "/extension_class.cpp", -bpl_src + "/functions.cpp", -bpl_src + "/init_function.cpp", -bpl_src + "/module_builder.cpp", -bpl_src + "/objects.cpp", -bpl_src + "/types.cpp", -bpl_src + "/cross_module.cpp", -bpl_tst + "/comprehensive.cpp", -bpl_tst + "/comprehensive.hpp", -bpl_tst + "/comprehensive.py", -bpl_tst + "/doctest.py", -bpl_exa + "/abstract.cpp", -bpl_exa + "/getting_started1.cpp", -bpl_exa + "/getting_started2.cpp", -bpl_exa + "/simple_vector.cpp", -bpl_exa + "/do_it_yourself_convts.cpp", -bpl_exa + "/nested.cpp", -bpl_exa + "/pickle1.cpp", -bpl_exa + "/pickle2.cpp", -bpl_exa + "/pickle3.cpp", -bpl_exa + "/test_abstract.py", -bpl_exa + "/test_getting_started1.py", -bpl_exa + "/test_getting_started2.py", -bpl_exa + "/test_simple_vector.py", -bpl_exa + "/test_do_it_yourself_convts.py", -bpl_exa + "/test_nested.py", -bpl_exa + "/test_pickle1.py", -bpl_exa + "/test_pickle2.py", -bpl_exa + "/test_pickle3.py", -bpl_exa + "/noncopyable.h", -bpl_exa + "/noncopyable_export.cpp", -bpl_exa + "/noncopyable_import.cpp", -bpl_exa + "/dvect.h", -bpl_exa + "/dvect.cpp", -bpl_exa + "/dvect_conversions.cpp", -bpl_exa + "/dvect_defs.cpp", -bpl_exa + "/ivect.h", -bpl_exa + "/ivect.cpp", -bpl_exa + "/ivect_conversions.cpp", -bpl_exa + "/ivect_defs.cpp", -bpl_exa + "/tst_noncopyable.py", -bpl_exa + "/tst_dvect1.py", -bpl_exa + "/tst_dvect2.py", -bpl_exa + "/tst_ivect1.py", -bpl_exa + "/tst_ivect2.py", -bpl_exa + "/test_cross_module.py", -bpl_exa + "/vector_wrapper.h", -bpl_exa + "/richcmp1.cpp", -bpl_exa + "/richcmp2.cpp", -bpl_exa + "/richcmp3.cpp", -bpl_exa + "/test_richcmp1.py", -bpl_exa + "/test_richcmp2.py", -bpl_exa + "/test_richcmp3.py", -) - -defs = ( -"boost_python_test", -"abstract", -"getting_started1", -"getting_started2", -"simple_vector", -"do_it_yourself_convts", -"nested", -"pickle1", -"pickle2", -"pickle3", -"noncopyable_export", -"noncopyable_import", -"ivect", -"dvect", -"richcmp1", -"richcmp2", -"richcmp3", -) - -if (__name__ == "__main__"): - - import sys, os, shutil - - path = sys.argv[1] - mode = sys.argv[2] - if (not mode in ("softlinks", "unlink", "cp", "rm", "copy", "del")): - raise RuntimeError, \ - "usage: python filemgr.py path " - - if (mode in ("cp", "copy")): - for fn in files: - f = os.path.basename(fn) - print "Copying: " + f - shutil.copy(path + fn, ".") - - elif (mode == "softlinks"): - for fn in files: - f = os.path.basename(fn) - if (os.path.exists(f)): - print "File exists: " + f - else: - print "Linking: " + f - os.symlink(path + fn, f) - - elif (mode in ("rm", "del")): - for fn in files: - f = os.path.basename(fn) - if (os.path.exists(f)): - print "Removing: " + f - try: os.unlink(f) - except: pass - - elif (mode == "unlink"): - for fn in files: - f = os.path.basename(fn) - if (os.path.exists(f)): - if (os.path.islink(f)): - print "Unlinking: " + f - try: os.unlink(f) - except: pass - else: - print "Not a softlink: " + f - - if (mode in ("softlinks", "cp", "copy")): - for d in defs: - fn = d + ".def" - print "Creating: " + fn - f = open(fn, "w") - f.write("EXPORTS\n") - f.write("\tinit" + d + "\n") - f.close() - - if (mode in ("unlink", "rm", "del")): - for d in defs: - fn = d + ".def" - if (os.path.exists(fn)): - print "Removing: " + fn - try: os.unlink(fn) - except: pass diff --git a/build/gcc.mak b/build/gcc.mak deleted file mode 100644 index b818030e..00000000 --- a/build/gcc.mak +++ /dev/null @@ -1,88 +0,0 @@ -# Revision History - -# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) -# 17 Apr 01 build shared library (patch provided by Dan Nuffer) -# 04 Mar 01 Changed library name to libboost_python.a, various cleanups, -# attempted Cygwin compatibility. Still needs testing on Linux -# (David Abrahams) - - -LIBSRC = \ - classes.cpp \ - conversions.cpp \ - cross_module.cpp \ - errors.cpp \ - extension_class.cpp \ - functions.cpp \ - init_function.cpp \ - module_builder.cpp \ - objects.cpp \ - types.cpp - -LIBOBJ = $(LIBSRC:.cpp=.o) -OBJ = $(LIBOBJ) - -LIBNAME = libboost_python -# libpython2.0.dll - -ifeq "$(OS)" "Windows_NT" -ROOT=c:/cygnus -INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -I$(PYTHON_INC) -MODULE_EXTENSION=dll -PYTHON_LIB=c:/cygnus/usr/local/lib/python2.0/config/libpython2.0.dll.a -SHARED_LIB = $(LIBNAME).dll -else -PYTHON_INC=$(ROOT)/usr/local/Python-2.0/include/python2.0 -BOOST_INC=../../.. -INC = -I$(BOOST_INC) -I$(PYTHON_INC) -MODULE_EXTENSION=so -VERSION=1 -SHARED_LIB = $(LIBNAME).so.$(VERSION) -endif - -%.o: ../src/%.cpp - g++ -fPIC -Wall -W $(INC) $(CXXFLAGS) -o $*.o -c $< - -%.d: ../src/%.cpp - @echo creating $@ - @set -e; g++ -M $(INC) -c $< \ - | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ - [ -s $@ ] || rm -f $@ - - -PYTHON = python - -all: test $(SHARED_LIB) getting_started1 - -test: comprehensive.o $(LIBNAME).a $(SHARED_LIB) - g++ $(CXXFLAGS) -shared -o ../test/boost_python_test.$(MODULE_EXTENSION) comprehensive.o -L. -lboost_python $(PYTHON_LIB) - $(PYTHON) ../test/comprehensive.py - -comprehensive.o: ../test/comprehensive.cpp - g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< - - -getting_started1: getting_started1.o $(LIBNAME).a - g++ $(CXXFLAGS) -shared -o ../example/getting_started1.$(MODULE_EXTENSION) getting_started1.o -L. -lboost_python $(PYTHON_LIB) - ln -s ../test/doctest.py ../example - $(PYTHON) ../example/test_getting_started1.py - -getting_started1.o: ../example/getting_started1.cpp - g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< - - -clean: - rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out - -$(LIBNAME).a: $(LIBOBJ) - rm -f $@ - ar cqs $@ $(LIBOBJ) - -$(SHARED_LIB): $(LIBOBJ) - g++ $(CXXFLAGS) -shared -o $@ -Wl,--soname=$(LIBNAME).$(MODULE_EXTENSION) - -DEP = $(OBJ:.o=.d) - -ifneq "$(MAKECMDGOALS)" "clean" -include $(DEP) -endif diff --git a/build/getting_started1/getting_started1.dsp b/build/getting_started1/getting_started1.dsp deleted file mode 100644 index a41eb057..00000000 --- a/build/getting_started1/getting_started1.dsp +++ /dev/null @@ -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 diff --git a/build/getting_started2/getting_started2.dsp b/build/getting_started2/getting_started2.dsp deleted file mode 100644 index 284bab21..00000000 --- a/build/getting_started2/getting_started2.dsp +++ /dev/null @@ -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 diff --git a/build/irix_CC.mak b/build/irix_CC.mak deleted file mode 100644 index f7d6004e..00000000 --- a/build/irix_CC.mak +++ /dev/null @@ -1,184 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Adjust the pathnames below. -# -# make softlinks Create softlinks to source code and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make unlink Remove softlinks -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=$(HOME) -BOOST=$(ROOT)/boost - -#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python -PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 -STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers - -STDOPTS= -WARNOPTS=-woff 1001,1234,1682 -OPTOPTS=-g - -CPP=CC -LANG:std -n32 -mips4 -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) -MAKEDEP=-M - -LD=CC -LANG:std -n32 -mips4 -LDOPTS=-shared - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o -DEPOBJ=$(OBJ) \ - comprehensive.o \ - abstract.o \ - getting_started1.o getting_started2.o \ - simple_vector.o \ - do_it_yourself_convts.o \ - nested.o \ - pickle1.o pickle2.o pickle3.o \ - noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o \ - richcmp1.o richcmp2.o richcmp3.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - boost_python_test.so \ - abstract.so \ - getting_started1.so getting_started2.so \ - simple_vector.so \ - do_it_yourself_convts.so \ - nested.so \ - pickle1.so pickle2.so pickle3.so \ - noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so \ - richcmp1.so richcmp2.so richcmp3.so - -libboost_python.a: $(OBJ) - rm -f libboost_python.a - $(CPP) -ar -o libboost_python.a $(OBJ) - -boost_python_test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm - -abstract.so: $(OBJ) abstract.o - $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so - -getting_started1.so: $(OBJ) getting_started1.o - $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so - -getting_started2.so: $(OBJ) getting_started2.o - $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so - -simple_vector.so: $(OBJ) simple_vector.o - $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so - -do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so - -nested.so: $(OBJ) nested.o - $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so - -pickle1.so: $(OBJ) pickle1.o - $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so - -pickle2.so: $(OBJ) pickle2.o - $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so - -pickle3.so: $(OBJ) pickle3.o - $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so - -noncopyable_export.so: $(OBJ) noncopyable_export.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_export.o -o noncopyable_export.so - -noncopyable_import.so: $(OBJ) noncopyable_import.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_import.o -o noncopyable_import.so - -ivect.so: $(OBJ) ivect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so - -dvect.so: $(OBJ) dvect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so - -richcmp1.so: $(OBJ) richcmp1.o - $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so - -richcmp2.so: $(OBJ) richcmp2.o - $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so - -richcmp3.so: $(OBJ) richcmp3.o - $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.so - rm -f abstract.o abstract.so - rm -f getting_started1.o getting_started1.so - rm -f getting_started2.o getting_started2.so - rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_convts.o do_it_yourself_convts.so - rm -f nested.o nested.so - rm -f pickle1.o pickle1.so - rm -f pickle2.o pickle2.so - rm -f pickle3.o pickle3.so - rm -f noncopyable_export.o noncopyable_export.so - rm -f noncopyable_import.o noncopyable_import.so - rm -f ivect.o ivect.so - rm -f dvect.o dvect.so - rm -f richcmp1.o richcmp1.so - rm -f richcmp2.o richcmp2.so - rm -f richcmp3.o richcmp3.so - rm -f so_locations *.pyc - rm -rf ii_files - -softlinks: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks - -unlink: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink - -cp: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp - -rm: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm - -depend: - @ cat Makefile.nodepend; \ - for obj in $(DEPOBJ); \ - do \ - bn=`echo "$$obj" | cut -d. -f1`; \ - $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ - done - diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak deleted file mode 100644 index 3b466e7d..00000000 --- a/build/linux_gcc.mak +++ /dev/null @@ -1,184 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Adjust the pathnames below. -# -# make softlinks Create softlinks to source code and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make unlink Remove softlinks -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=$(HOME) -BOOST=$(ROOT)/boost - -#PYEXE=PYTHONPATH=. /usr/bin/python -#PYINC=-I/usr/include/python1.5 -#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python -PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 - -STDOPTS=-fPIC -ftemplate-depth-21 -WARNOPTS= -OPTOPTS=-g - -CPP=g++ -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) -MAKEDEP=-M - -LD=$(CPP) -LDOPTS=-shared - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o -DEPOBJ=$(OBJ) \ - comprehensive.o \ - abstract.o \ - getting_started1.o getting_started2.o \ - simple_vector.o \ - do_it_yourself_convts.o \ - nested.o \ - pickle1.o pickle2.o pickle3.o \ - noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o \ - richcmp1.o richcmp2.o richcmp3.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - boost_python_test.so \ - abstract.so \ - getting_started1.so getting_started2.so \ - simple_vector.so \ - do_it_yourself_convts.so \ - nested.so \ - pickle1.so pickle2.so pickle3.so \ - noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so \ - richcmp1.so richcmp2.so richcmp3.so - -libboost_python.a: $(OBJ) - rm -f libboost_python.a - ar r libboost_python.a $(OBJ) - -boost_python_test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm - -abstract.so: $(OBJ) abstract.o - $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so - -getting_started1.so: $(OBJ) getting_started1.o - $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so - -getting_started2.so: $(OBJ) getting_started2.o - $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so - -simple_vector.so: $(OBJ) simple_vector.o - $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so - -do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so - -nested.so: $(OBJ) nested.o - $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so - -pickle1.so: $(OBJ) pickle1.o - $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so - -pickle2.so: $(OBJ) pickle2.o - $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so - -pickle3.so: $(OBJ) pickle3.o - $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so - -noncopyable_export.so: $(OBJ) noncopyable_export.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_export.o -o noncopyable_export.so - -noncopyable_import.so: $(OBJ) noncopyable_import.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_import.o -o noncopyable_import.so - -ivect.so: $(OBJ) ivect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so - -dvect.so: $(OBJ) dvect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so - -richcmp1.so: $(OBJ) richcmp1.o - $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so - -richcmp2.so: $(OBJ) richcmp2.o - $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so - -richcmp3.so: $(OBJ) richcmp3.o - $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.so - rm -f abstract.o abstract.so - rm -f getting_started1.o getting_started1.so - rm -f getting_started2.o getting_started2.so - rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_convts.o do_it_yourself_convts.so - rm -f nested.o nested.so - rm -f pickle1.o pickle1.so - rm -f pickle2.o pickle2.so - rm -f pickle3.o pickle3.so - rm -f noncopyable_export.o noncopyable_export.so - rm -f noncopyable_import.o noncopyable_import.so - rm -f ivect.o ivect.so - rm -f dvect.o dvect.so - rm -f richcmp1.o richcmp1.so - rm -f richcmp2.o richcmp2.so - rm -f richcmp3.o richcmp3.so - rm -f so_locations *.pyc - -softlinks: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks - -unlink: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink - -cp: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp - -rm: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm - -depend: - @ cat Makefile.nodepend; \ - for obj in $(DEPOBJ); \ - do \ - bn=`echo "$$obj" | cut -d. -f1`; \ - $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ - done - diff --git a/build/mingw32.mak b/build/mingw32.mak deleted file mode 100644 index d8c31b68..00000000 --- a/build/mingw32.mak +++ /dev/null @@ -1,222 +0,0 @@ -# Usage: -# -# make copy Copy the sources and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make del Remove the sources and tests -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -# To install mingw32, follow instructions at: -# http://starship.python.net/crew/kernr/mingw32/Notes.html -# In particular, install: -# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/gcc-2.95.2-msvcrt.exe -# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/fixes/quote-fix-msvcrt.exe -# http://starship.python.net/crew/kernr/mingw32/Python-1.5.2-mingw32.zip -# Unpack the first two archives in the default locations and update your PATH. -# Unpack the third archive in \usr. - -# Note: comprehensive.cpp generates compiler errors and later crashes. -# L:\boost\boost\python\detail\extension_class.hpp:643: warning: -# alignment of `vtable for class -# boost::python::detail::held_instance' -# is greater than maximum object file alignment. Using 16. -# Could this be fixed with compiler options? -# -fhuge-objects looks interesting, but requires recompiling the C++ library. -# (what exactly does that mean?) -# -fvtable-thunks eliminates the compiler warning, but -# "import boost_python_test" still causes a crash. - -ROOT=R: -BOOST_WIN="$(ROOT)\boost" -BOOST_UNIX=$(HOME)/boost - -PYEXE="C:\Program files\Python\python.exe" -PYINC=-I"C:\usr\include\python1.5" -PYLIB="C:\usr\lib\libpython15.a" -#PYEXE="C:\Python21\python.exe" -#PYINC=-I"C:\usr\include\python2.1" -#PYLIB="C:\usr\lib\libpython21.a" - -STDOPTS=-ftemplate-depth-21 -WARNOPTS= -OPTOPTS=-g - -CPP=g++ -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) - -LD=g++ -LDOPTS=-shared - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - abstract.pyd \ - getting_started1.pyd getting_started2.pyd \ - simple_vector.pyd \ - do_it_yourself_convts.pyd \ - nested.pyd \ - pickle1.pyd pickle2.pyd pickle3.pyd \ - noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd \ - richcmp1.pyd richcmp2.pyd richcmp3.pyd - -libboost_python.a: $(OBJ) - -del libboost_python.a - ar r libboost_python.a $(OBJ) - -DLLWRAPOPTS=-s --driver-name g++ -s \ - --entry _DllMainCRTStartup@12 --target=i386-mingw32 - -boost_python_test.pyd: $(OBJ) comprehensive.o - dllwrap $(DLLWRAPOPTS) \ - --dllname boost_python_test.pyd \ - --def boost_python_test.def \ - $(OBJ) comprehensive.o $(PYLIB) - -abstract.pyd: $(OBJ) abstract.o - dllwrap $(DLLWRAPOPTS) \ - --dllname abstract.pyd \ - --def abstract.def \ - $(OBJ) abstract.o $(PYLIB) - -getting_started1.pyd: $(OBJ) getting_started1.o - dllwrap $(DLLWRAPOPTS) \ - --dllname getting_started1.pyd \ - --def getting_started1.def \ - $(OBJ) getting_started1.o $(PYLIB) - -getting_started2.pyd: $(OBJ) getting_started2.o - dllwrap $(DLLWRAPOPTS) \ - --dllname getting_started2.pyd \ - --def getting_started2.def \ - $(OBJ) getting_started2.o $(PYLIB) - -simple_vector.pyd: $(OBJ) simple_vector.o - dllwrap $(DLLWRAPOPTS) \ - --dllname simple_vector.pyd \ - --def simple_vector.def \ - $(OBJ) simple_vector.o $(PYLIB) - -do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.o - dllwrap $(DLLWRAPOPTS) \ - --dllname do_it_yourself_convts.pyd \ - --def do_it_yourself_convts.def \ - $(OBJ) do_it_yourself_convts.o $(PYLIB) - -nested.pyd: $(OBJ) nested.o - dllwrap $(DLLWRAPOPTS) \ - --dllname nested.pyd \ - --def nested.def \ - $(OBJ) nested.o $(PYLIB) - -pickle1.pyd: $(OBJ) pickle1.o - dllwrap $(DLLWRAPOPTS) \ - --dllname pickle1.pyd \ - --def pickle1.def \ - $(OBJ) pickle1.o $(PYLIB) - -pickle2.pyd: $(OBJ) pickle2.o - dllwrap $(DLLWRAPOPTS) \ - --dllname pickle2.pyd \ - --def pickle2.def \ - $(OBJ) pickle2.o $(PYLIB) - -pickle3.pyd: $(OBJ) pickle3.o - dllwrap $(DLLWRAPOPTS) \ - --dllname pickle3.pyd \ - --def pickle3.def \ - $(OBJ) pickle3.o $(PYLIB) - -noncopyable_export.pyd: $(OBJ) noncopyable_export.o - dllwrap $(DLLWRAPOPTS) \ - --dllname noncopyable_export.pyd \ - --def noncopyable_export.def \ - $(OBJ) noncopyable_export.o $(PYLIB) - -noncopyable_import.pyd: $(OBJ) noncopyable_import.o - dllwrap $(DLLWRAPOPTS) \ - --dllname noncopyable_import.pyd \ - --def noncopyable_import.def \ - $(OBJ) noncopyable_import.o $(PYLIB) - -ivect.pyd: $(OBJ) ivect.o - dllwrap $(DLLWRAPOPTS) \ - --dllname ivect.pyd \ - --def ivect.def \ - $(OBJ) ivect.o $(PYLIB) - -dvect.pyd: $(OBJ) dvect.o - dllwrap $(DLLWRAPOPTS) \ - --dllname dvect.pyd \ - --def dvect.def \ - $(OBJ) dvect.o $(PYLIB) - -richcmp1.pyd: $(OBJ) richcmp1.o - dllwrap $(DLLWRAPOPTS) \ - --dllname richcmp1.pyd \ - --def richcmp1.def \ - $(OBJ) richcmp1.o $(PYLIB) - -richcmp2.pyd: $(OBJ) richcmp2.o - dllwrap $(DLLWRAPOPTS) \ - --dllname richcmp2.pyd \ - --def richcmp2.def \ - $(OBJ) richcmp2.o $(PYLIB) - -richcmp3.pyd: $(OBJ) richcmp3.o - dllwrap $(DLLWRAPOPTS) \ - --dllname richcmp3.pyd \ - --def richcmp3.def \ - $(OBJ) richcmp3.o $(PYLIB) - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: -# $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - -del *.o - -del *.a - -del *.pyd - -del *.pyc - -softlinks: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks - -unlink: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink - -cp: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp - -rm: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm - -copy: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy - -del: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/rwgk1/rwgk1.dsp b/build/rwgk1/rwgk1.dsp deleted file mode 100644 index 67476984..00000000 --- a/build/rwgk1/rwgk1.dsp +++ /dev/null @@ -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 diff --git a/build/test/test.dsp b/build/test/test.dsp deleted file mode 100644 index 4bd2822a..00000000 --- a/build/test/test.dsp +++ /dev/null @@ -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 diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak deleted file mode 100644 index a64927b1..00000000 --- a/build/tru64_cxx.mak +++ /dev/null @@ -1,199 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Adjust the pathnames below. -# -# make softlinks Create softlinks to source code and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make unlink Remove softlinks -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=$(HOME) -BOOST=$(ROOT)/boost - -#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python -PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 -#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport -#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport -#STLPORTOPTS= \ -# -D__USE_STD_IOSTREAM \ -# -D__STL_NO_SGI_IOSTREAMS \ -# -D__STL_USE_NATIVE_STRING \ -# -D__STL_NO_NEW_C_HEADERS \ -# -D_RWSTD_COMPILE_INSTANTIATE=1 -STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers - -STDOPTS=-std strict_ansi -# use -msg_display_number to obtain integer tags for -msg_disable -WARNOPTS=-msg_disable 186,450,1115 -OPTOPTS=-g - -CPP=cxx -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) -MAKEDEP=-Em - -LD=cxx -LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*' - -#HIDDEN=-hidden - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o -DEPOBJ=$(OBJ) \ - comprehensive.o \ - abstract.o \ - getting_started1.o getting_started2.o \ - simple_vector.o \ - do_it_yourself_convts.o \ - nested.o \ - pickle1.o pickle2.o pickle3.o \ - noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o \ - richcmp1.o richcmp2.o richcmp3.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - boost_python_test.so \ - abstract.so \ - getting_started1.so getting_started2.so \ - simple_vector.so \ - do_it_yourself_convts.so \ - nested.so \ - pickle1.so pickle2.so pickle3.so \ - noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so \ - richcmp1.so richcmp2.so richcmp3.so - -libboost_python.a: $(OBJ) - rm -f libboost_python.a - cd cxx_repository; \ - ls -1 > ../libboost_python.a.input; \ - ar r ../libboost_python.a -input ../libboost_python.a.input - rm -f libboost_python.a.input - ar r libboost_python.a $(OBJ) - -boost_python_test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm - -abstract.so: $(OBJ) abstract.o - $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so - -getting_started1.so: $(OBJ) getting_started1.o - $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so - -getting_started2.so: $(OBJ) getting_started2.o - $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so - -simple_vector.so: $(OBJ) simple_vector.o - $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so - -do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so - -nested.so: $(OBJ) nested.o - $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so - -pickle1.so: $(OBJ) pickle1.o - $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so - -pickle2.so: $(OBJ) pickle2.o - $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so - -pickle3.so: $(OBJ) pickle3.o - $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so - -noncopyable_export.so: $(OBJ) noncopyable_export.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_export.o -o noncopyable_export.so - -noncopyable_import.so: $(OBJ) noncopyable_import.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_import.o -o noncopyable_import.so - -ivect.so: $(OBJ) ivect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so - -dvect.so: $(OBJ) dvect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so - -richcmp1.so: $(OBJ) richcmp1.o - $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so - -richcmp2.so: $(OBJ) richcmp2.o - $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so - -richcmp3.so: $(OBJ) richcmp3.o - $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.so - rm -f abstract.o abstract.so - rm -f getting_started1.o getting_started1.so - rm -f getting_started2.o getting_started2.so - rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_convts.o do_it_yourself_convts.so - rm -f nested.o nested.so - rm -f pickle1.o pickle1.so - rm -f pickle2.o pickle2.so - rm -f pickle3.o pickle3.so - rm -f noncopyable_export.o noncopyable_export.so - rm -f noncopyable_import.o noncopyable_import.so - rm -f ivect.o ivect.so - rm -f dvect.o dvect.so - rm -f richcmp1.o richcmp1.so - rm -f richcmp2.o richcmp2.so - rm -f richcmp3.o richcmp3.so - rm -f so_locations *.pyc - rm -rf cxx_repository - -softlinks: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks - -unlink: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink - -cp: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp - -rm: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm - -depend: - @ cat Makefile.nodepend; \ - for obj in $(DEPOBJ); \ - do \ - bn=`echo "$$obj" | cut -d. -f1`; \ - $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ - done - diff --git a/build/vc60.mak b/build/vc60.mak deleted file mode 100644 index 6f303791..00000000 --- a/build/vc60.mak +++ /dev/null @@ -1,150 +0,0 @@ -# Usage: -# -# make copy Copy the sources and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make del Remove the sources and tests -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=R: -BOOST_WIN="$(ROOT)\boost" -BOOST_UNIX=$(HOME)/boost - -#PYEXE="C:\Program files\Python\python.exe" -#PYINC=/I"C:\Program files\Python\include" -#PYLIB="C:\Program files\Python\libs\python15.lib" -PYEXE="C:\Python21\python.exe" -PYINC=/I"C:\Python21\include" -PYLIB="C:\Python21\libs\python21.lib" - -STDOPTS=/nologo /MD /GR /GX /Zm200 /DBOOST_PYTHON_STATIC_LIB -WARNOPTS= -OPTOPTS= - -CPP=cl.exe -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) - -LD=link.exe -LDOPTS=/nologo /dll /incremental:no - -OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \ - init_function.obj module_builder.obj \ - objects.obj types.obj cross_module.obj - -.SUFFIXES: .obj .cpp - -all: boost_python.lib \ - boost_python_test.pyd \ - abstract.pyd \ - getting_started1.pyd getting_started2.pyd \ - simple_vector.pyd \ - do_it_yourself_convts.pyd \ - nested.pyd \ - pickle1.pyd pickle2.pyd pickle3.pyd \ - noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd \ - richcmp1.pyd richcmp2.pyd richcmp3.pyd - -boost_python.lib: $(OBJ) - $(LD) -lib /nologo /out:boost_python.lib $(OBJ) - -boost_python_test.pyd: $(OBJ) comprehensive.obj - $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) /export:initboost_python_test /out:"boost_python_test.pyd" - -abstract.pyd: $(OBJ) abstract.obj - $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) /export:initabstract /out:"abstract.pyd" - -getting_started1.pyd: $(OBJ) getting_started1.obj - $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) /export:initgetting_started1 /out:"getting_started1.pyd" - -getting_started2.pyd: $(OBJ) getting_started2.obj - $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd" - -simple_vector.pyd: $(OBJ) simple_vector.obj - $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd" - -do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) /export:initdo_it_yourself_convts /out:"do_it_yourself_convts.pyd" - -nested.pyd: $(OBJ) nested.obj - $(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) /export:initnested /out:"nested.pyd" - -pickle1.pyd: $(OBJ) pickle1.obj - $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd" - -pickle2.pyd: $(OBJ) pickle2.obj - $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) /export:initpickle2 /out:"pickle2.pyd" - -pickle3.pyd: $(OBJ) pickle3.obj - $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) /export:initpickle3 /out:"pickle3.pyd" - -noncopyable_export.pyd: $(OBJ) noncopyable_export.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) /export:initnoncopyable_export /out:"noncopyable_export.pyd" - -noncopyable_import.pyd: $(OBJ) noncopyable_import.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) /export:initnoncopyable_import /out:"noncopyable_import.pyd" - -ivect.pyd: $(OBJ) ivect.obj - $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) /export:initivect /out:"ivect.pyd" - -dvect.pyd: $(OBJ) dvect.obj - $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd" - -richcmp1.pyd: $(OBJ) richcmp1.obj - $(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) /export:initrichcmp1 /out:"richcmp1.pyd" - -richcmp2.pyd: $(OBJ) richcmp2.obj - $(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) /export:initrichcmp2 /out:"richcmp2.pyd" - -richcmp3.pyd: $(OBJ) richcmp3.obj - $(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) /export:initrichcmp3 /out:"richcmp3.pyd" - -.cpp.obj: - $(CPP) $(CPPOPTS) /c $*.cpp - -test: - $(PYEXE) comprehensive.py --broken-auto-ptr - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py --broken-auto-ptr - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - -del *.obj - -del *.lib - -del *.exp - -del *.idb - -del *.pyd - -del *.pyc - -softlinks: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks - -unlink: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink - -cp: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp - -rm: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm - -copy: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy - -del: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/win32_mwcc.mak b/build/win32_mwcc.mak deleted file mode 100755 index c49af71c..00000000 --- a/build/win32_mwcc.mak +++ /dev/null @@ -1,149 +0,0 @@ -# Usage: -# -# make copy Copy the sources and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make del Remove the sources and tests -# -# Revision history: -# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve) - -ROOT=R: -BOOST_WIN="$(ROOT)\boost" -BOOST_UNIX=$(HOME)/boost - -#PYEXE="C:\Program files\Python\python.exe" -#PYINC=-I"C:\Program files\Python\include" -#PYLIB="C:\Program files\Python\libs\python15.lib" -PYEXE="C:\Python21\python.exe" -PYINC=-I"C:\Python21\include" -PYLIB="C:\Python21\libs\python21.lib" - -STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB -WARNOPTS=-warn on,nounusedexpr,nounused -OPTOPTS=-O - -CPP=mwcc -CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \ - $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) - -LD=mwld -LDOPTS=-export dllexport -shared - -OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \ - init_function.obj module_builder.obj \ - objects.obj types.obj cross_module.obj - -.SUFFIXES: .obj .cpp - -all: libboost_python.lib \ - boost_python_test.pyd \ - abstract.pyd \ - getting_started1.pyd getting_started2.pyd \ - simple_vector.pyd \ - do_it_yourself_convts.pyd \ - nested.pyd \ - pickle1.pyd pickle2.pyd pickle3.pyd \ - noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd \ - richcmp1.pyd richcmp2.pyd richcmp3.pyd - -libboost_python.lib: $(OBJ) - $(LD) -library -o libboost_python.lib $(OBJ) - -boost_python_test.pyd: $(OBJ) comprehensive.obj - $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) -o boost_python_test.pyd - -abstract.pyd: $(OBJ) abstract.obj - $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) -o abstract.pyd - -getting_started1.pyd: $(OBJ) getting_started1.obj - $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) -o getting_started1.pyd - -getting_started2.pyd: $(OBJ) getting_started2.obj - $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) -o getting_started2.pyd - -simple_vector.pyd: $(OBJ) simple_vector.obj - $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) -o simple_vector.pyd - -do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) -o do_it_yourself_convts.pyd - -nested.pyd: $(OBJ) nested.obj - $(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) -o nested.pyd - -pickle1.pyd: $(OBJ) pickle1.obj - $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) -o pickle1.pyd - -pickle2.pyd: $(OBJ) pickle2.obj - $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) -o pickle2.pyd - -pickle3.pyd: $(OBJ) pickle3.obj - $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) -o pickle3.pyd - -noncopyable_export.pyd: $(OBJ) noncopyable_export.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) -o noncopyable_export.pyd - -noncopyable_import.pyd: $(OBJ) noncopyable_import.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) -o noncopyable_import.pyd - -ivect.pyd: $(OBJ) ivect.obj - $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) -o ivect.pyd - -dvect.pyd: $(OBJ) dvect.obj - $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) -o dvect.pyd - -richcmp1.pyd: $(OBJ) richcmp1.obj - $(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) -o richcmp1.pyd - -richcmp2.pyd: $(OBJ) richcmp2.obj - $(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) -o richcmp2.pyd - -richcmp3.pyd: $(OBJ) richcmp3.obj - $(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) -o richcmp3.pyd - -.cpp.obj: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - -del *.obj - -del *.lib - -del *.exp - -del *.idb - -del *.pyd - -del *.pyc - -softlinks: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks - -unlink: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink - -cp: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp - -rm: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm - -copy: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy - -del: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/win32_mwcc_setup.bat b/build/win32_mwcc_setup.bat deleted file mode 100755 index 30f84be8..00000000 --- a/build/win32_mwcc_setup.bat +++ /dev/null @@ -1,2 +0,0 @@ -call "c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat" -set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib diff --git a/doc/building.html b/doc/building.html deleted file mode 100644 index f9458c42..00000000 --- a/doc/building.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - Building an Extension Module - -
-

c++boost.gif (8819 bytes)Building an - Extension Module

- -

The build process for Boost is currently undergoing some evolution, - and, it is to be hoped, improvement. The following facts may help: - -


- Makefiles for various platforms and a Visual Studio project - reside in the Boost subdirectory libs/python/build. - Build targets include: - -
    -
  • The boost_python library for static linking with your - extension module. On the various Unices, this library will be - called libboost_python.a. When using Visual C++, the - library will be called boost_python.lib. - -

    -

  • 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 doctest. Source code for the module - and tests is available in the Boost subdirectory - libs/python/test. - -

    -

  • Various examples from the Boost subdirectory - libs/python/example. - All these examples include a doctest modeled - on the comprehensive test above. - -
- -
- There is a group of makefiles with support for simultaneous - compilation on multiple platforms and a consistent set of - features that build the boost_python library for static - linking, the comprehensive test, and all examples in - libs/python/example: - - - Usage of these makefiles is described here. - -
- 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. - - - -
- A project workspace for Microsoft Visual Studio is provided at libs/python/build/build.dsw. The - include paths for this project may need to be changed for your - installation. They currently assume that python has been installed at - c:\tools\python. Three configurations of all targets are - supported: - -
    -
  • Release (optimization, -DNDEBUG) - -
  • Debug (no optimization -D_DEBUG) - -
  • DebugPython (no optimization, -D_DEBUG - -DBOOST_DEBUG_PYTHON) -
- -

When extension modules are built with Visual C++ using - -D_DEBUG, Python defaults to force 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 boost/python/detail/wrap_python.hpp - to temporarily undefine _DEBUG when Python.h is - #included. - -

If you want the extra runtime checks available with the debugging - version of the library, #define BOOST_DEBUG_PYTHON to - re-enable library forcing, and link with the DebugPython version of - boost_python.lib. You'll need to get the debugging version - of the Python executable (python_d.exe) and DLL - (python20_d.dll or python15_d.dll). The Python - sources include project files for building these. If you download them, change the name of the - top-level directory to src, and install it under - c:\tools\python, the workspace supplied by Boost.Python will - be able to use it without modification. Just open - c:\tools\python\src\pcbuild\pcbuild.dsw and invoke "build - all" to generate all the debugging targets. - -

If you do not #define BOOST_DEBUG_PYTHON, be sure that - any source files #include <boost/python/detail/wrap_python.hpp> - instead of the usual Python.h, or you will have link - incompatibilities.
- -


- If your platform isn't directly supported, you can build a static - library from the following source files (in the Boost subdirectory - libs/python/src), or compile them directly and link the - resulting objects into your extension module: - - - -
- Next: Wrapping Enums Previous: A Peek Under the Hood Up: Top - -
-

© Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as is'' without - express or implied warranty, and with no claim as to its suitability for - any purpose. - -

Updated: Apr 17, 2001 (R.W. Grosse-Kunstleve) -

diff --git a/doc/comparisons.html b/doc/comparisons.html deleted file mode 100644 index 57cec744..00000000 --- a/doc/comparisons.html +++ /dev/null @@ -1,231 +0,0 @@ - - - Comparisons with Other Systems - -
-

- c++boost.gif (8819 bytes)
- Comparisons with - Other Systems -

- -

CXX

-

- Like Boost.Python, CXX attempts to - provide a C++-oriented interface to Python. In most cases, as with the - boost library, it relieves the user from worrying about - reference-counts. Both libraries automatically convert thrown C++ - exceptions into Python exceptions. As far as I can tell, CXX has no - support for subclassing C++ extension types in Python. An even - more significant difference is that a user's C++ code is still basically - ``dealing with Python objects'', though they are wrapped in - C++ classes. This means such jobs as argument parsing and conversion are - still left to be done explicitly by the user. - -

- CXX claims to interoperate well with the C++ Standard Library - (a.k.a. STL) by providing iterators into Python Lists and Dictionaries, - but the claim is unfortunately unsupportable. The problem is that in - general, access to Python sequence and mapping elements through - iterators requires the use of proxy objects as the return value of - iterator dereference operations. This usage conflicts with the basic - ForwardIterator requirements in - section 24.1.3 of the standard (dereferencing must produce a - reference). Although you may be able to use these iterators with some - operations in some standard library implementations, it is neither - guaranteed to work nor portable. - -

- As far as I can tell, CXX enables one to write what is essentially - idiomatic Python code in C++, manipulating Python objects through the - same fully-generic interfaces we use in Python. While you're hardly - programming directly to the ``bare metal'' with CXX, it basically - presents a ``C++-ized'' version of the Python 'C' API. Some fraction of - that capability is available in Boost.Python through boost/python/objects.hpp, - which provides C++ objects corresponding to Python lists, tuples, - strings, and dictionaries, and through boost/python/callback.hpp, - which allows you to call back into python with C++ arguments. - -

- Paul F. Dubois, the original - author of CXX, has told me that what I've described is only half of the - picture with CXX, but I never understood his explanation well-enough to - fill in the other half. Here is his response to the commentary above: - -

-``My intention with CXX was not to do what you are doing. It was to enable a -person to write an extension directly in C++ rather than C. I figured others had -the wrapping business covered. I thought maybe CXX would provide an easier -target language for those making wrappers, but I never explored -that.''
-Paul Dubois -
- -

SWIG

-

- SWIG is an impressively mature tool - for exporting an existing ANSI 'C' interface into various scripting - languages. Swig relies on a parser to read your source code and produce - additional source code files which can be compiled into a Python (or - Perl or Tcl) extension module. It has been successfully used to create - many Python extension modules. Like Boost.Python, SWIG is trying to allow an - existing interface to be wrapped with little or no change to the - existing code. The documentation says ``SWIG parses a form of ANSI C - syntax that has been extended with a number of special directives. As a - result, interfaces are usually built by grabbing a header file and - tweaking it a little bit.'' For C++ interfaces, the tweaking has often - proven to amount to more than just a little bit. One user - writes: - -

``The problem with swig (when I used it) is that it - couldnt handle templates, didnt do func overloading properly etc. For - ANSI C libraries this was fine. But for usual C++ code this was a - problem. Simple things work. But for anything very complicated (or - realistic), one had to write code by hand. I believe Boost.Python doesn't have - this problem[sic]... IMHO overloaded functions are very important to - wrap correctly.''
-Prabhu Ramachandran -
- -

- By contrast, Boost.Python doesn't attempt to parse C++ - the problem is simply - too complex to do correctly. Technically, one does - write code by hand to use Boost.Python. The goal, however, has been to make - that code nearly as simple as listing the names of the classes and - member functions you want to expose in Python. - -

SIP

-

- SIP - is a system similar to SWIG, though seemingly more - C++-oriented. The author says that like Boost.Python, SIP supports overriding - extension class member functions in Python subclasses. It appears to - have been designed specifically to directly support some features of - PyQt/PyKDE, which is its primary client. Documentation is almost - entirely missing at the time of this writing, so a detailed comparison - is difficult. - -

ILU

-

- ILU - is a very ambitious project which tries to describe a module's interface - (types and functions) in terms of an Interface - Specification Language (ISL) so that it can be uniformly interfaced - to a wide range of computer languages, including Common Lisp, C++, C, - Modula-3, and Python. ILU can parse the ISL to generate a C++ language - header file describing the interface, of which the user is expected to - provide an implementation. Unlike Boost.Python, this means that the system - imposes implementation details on your C++ code at the deepest level. It - is worth noting that some of the C++ names generated by ILU are supposed - to be reserved to the C++ implementation. It is unclear from the - documentation whether ILU supports overriding C++ virtual functions in Python. - -

GRAD

-

- GRAD - is another very ambitious project aimed at generating Python wrappers for - interfaces written in ``legacy languages'', among which C++ is the first one - implemented. Like SWIG, it aims to parse source code and automatically - generate wrappers, though it appears to take a more sophisticated approach - to parsing in general and C++ in particular, so it should do a much better - job with C++. It appears to support function overloading. The - documentation is missing a lot of information I'd like to see, so it is - difficult to give an accurate and fair assessment. I am left with the - following questions: -

    -
  • Does it support overriding of virtual functions? -
  • What about overriding private or protected virtual functions (the documentation indicates -that only public interfaces are supported)? -
  • Which C++ language constructs are supportd? -
  • Does it support implicit conversions between wrapped C++ classes that have -an inheritance relationship? -
  • Does it support smart pointers? -
-

- Anyone in the possession of the answers to these questions will earn my - gratitude for a write-up ;-) - -

Zope ExtensionClasses

-

- - ExtensionClasses in Zope use the same underlying mechanism as Boost.Python - to support subclassing of extension types in Python, including - multiple-inheritance. Both systems support pickling/unpickling of - extension class instances in very similar ways. Both systems rely on the - same ``Don - Beaudry Hack'' that also inspired Don's MESS System. -

- The major differences are: -

    -
  • Zope is entirely 'C' language-based. It doesn't require a C++ - compiler, so it's much more portable than Boost.Python, which stresses - the limits of even some modern C++ implementations. - -
  • - Boost.Python lifts the burden on the user to parse and convert function - argument types. Zope provides no such facility. -
  • - Boost.Python lifts the burden on the user to maintain Python - reference-counts. -
  • - Boost.Python supports function overloading; Zope does not. -
  • - Boost.Python supplies a simple mechanism for exposing read-only and - read/write access to data members of the wrapped C++ type as Python - attributes. -
  • - Writing a Zope ExtensionClass is significantly more complex than - exposing a C++ class to python using Boost.Python (mostly a summary of the - previous 4 items). A - Zope Example illustrates the differences. -
  • - Zope's ExtensionClasses are specifically motivated by ``the need for a - C-based persistence mechanism''. Boost.Python's are motivated by the desire - to simply reflect a C++ API into Python with as little modification as - possible. -
  • - The following Zope restriction does not apply to Boost.Python: ``At most one - base extension direct or indirect super class may define C data - members. If an extension subclass inherits from multiple base - extension classes, then all but one must be mix-in classes that - provide extension methods but no data.'' -
  • - Zope requires use of the somewhat funky inheritedAttribute (search for - ``inheritedAttribute'' on this page) - method to access base class methods. In Boost.Python, base class methods can - be accessed in the usual way by writing - ``BaseClass.method''. -
  • - Zope supplies some creative but esoteric idioms such as - Acquisition. No specific support for this is built into Boost.Python. -
  • - Zope's ComputedAttribute support is designed to be used from Python. - The analogous feature of - Boost.Python can be used from C++ or Python. The feature is arguably - easier to use in Boost.Python. -
-

- Next: A Simple Example Using Boost.Python - Previous: A Brief Introduction to writing Python Extension Modules - Up: Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as is'' without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

- Updated: Mar 6, 2001 -

- diff --git a/doc/cross_module.html b/doc/cross_module.html deleted file mode 100644 index 08c39bfe..00000000 --- a/doc/cross_module.html +++ /dev/null @@ -1,336 +0,0 @@ - - -Cross-extension-module dependencies - -
- -c++boost.gif (8819 bytes) - -
-

Cross-extension-module dependencies

- -It is good programming practice to organize large projects as modules -that interact with each other via well defined interfaces. With -Boost.Python it is possible to reflect this organization at the C++ -level at the Python level. This is, each logical C++ module can be -organized as a separate Python extension module. - -

-At first sight this might seem natural and straightforward. However, it -is a fairly complex problem to establish cross-extension-module -dependencies while maintaining the same ease of use Boost.Python -provides for classes that are wrapped in the same extension module. To -a large extent this complexity can be hidden from the author of a -Boost.Python extension module, but not entirely. - -


-

The recipe

- -Suppose there is an extension module that exposes certain instances of -the C++ std::vector template library such that it can be used -from Python in the following manner: - -
-import std_vector
-v = std_vector.double([1, 2, 3, 4])
-v.push_back(5)
-v.size()
-
- -Suppose the std_vector module is done well and reflects all -C++ functions that are useful at the Python level, for all C++ built-in -data types (std_vector.int, std_vector.long, etc.). - -

-Suppose further that there is statistic module with a C++ class that -has constructors or member functions that use or return a -std::vector. For example: - -

-class xy {
-  public:
-    xy(const std::vector<double>& x, const std::vector<double>& y) : m_x(x), m_y(y) {}
-    const std::vector<double>& x() const { return m_x; }
-    const std::vector<double>& y() const { return m_y; }
-    double correlation();
-  private:
-    std::vector<double> m_x;
-    std::vector<double> m_y;
-}
-
- -What is more natural than reusing the std_vector extension -module to expose these constructors or functions to Python? - -

-Unfortunately, what seems natural needs a little work in both the -std_vector and the statistics module. - -

-In the std_vector extension module, -std::vector<double> is exposed to Python in the usual -way with the class_builder<> template. To also enable the -automatic conversion of std::vector<double> function -arguments or return values in other Boost.Python C++ modules, the -converters that convert a std::vector<double> C++ object -to a Python object and vice versa (i.e. the to_python() and -from_python() template functions) have to be exported. For -example: - -

-  #include <boost/python/cross_module.hpp>
-  //...
-  class_builder<std::vector<double> > v_double(std_vector_module, "double");
-  export_converters(v_double);
-
- -In the extension module that wraps class xy we can now import -these converters with the import_converters<> template. -For example: - -
-  #include <boost/python/cross_module.hpp>
-  //...
-  import_converters<std::vector<double> > v_double_converters("std_vector", "double");
-
- -That is all. All the attributes that are defined for -std_vector.double in the std_vector Boost.Python -module will be available for the returned objects of xy.x() -and xy.y(). Similarly, the constructor for xy will -accept objects that were created by the std_vectormodule. - -
-

Placement of import_converters<> template instantiations

- -import_converts<> can be viewed as a drop-in replacement -for class_wrapper<>, and the recommendations for the -placement of class_wrapper<> template instantiations -also apply to to import_converts<>. In particular, it is -important that an instantiation of class_wrapper<> is -visible to any code which wraps a C++ function with a T, -T*, const T&, etc. parameter or return value. -Therefore you may want to group all class_wrapper<> and -import_converts<> instantiations at the top of your -module's init function, then def() the member functions later -to avoid problems with inter-class dependencies. - -
-

Non-copyable types

- -export_converters() instantiates C++ template functions that -invoke the copy constructor of the wrapped type. For a type that is -non-copyable this will result in compile-time error messages. In such a -case, export_converters_noncopyable() can be used to export -the converters that do not involve the copy constructor of the wrapped -type. For example: - -
-class_builder<store> py_store(your_module, "store");
-export_converters_noncopyable(py_store);
-
- -The corresponding import_converters<> statement does not -need any special attention: - -
-import_converters<store> py_store("noncopyable_export", "store");
-
- -
-

Python module search path

- -The std_vector and statistics modules can now be used -in the following way: - -
-import std_vector
-import statistics
-x = std_vector.double([1, 2, 3, 4])
-y = std_vector.double([2, 4, 6, 8])
-xy = statistics.xy(x, y)
-xy.correlation()
-
- -In this example it is clear that Python has to be able to find both the -std_vector and the statistics extension module. In -other words, both extension modules need to be in the Python module -search path (sys.path). - -

-The situation is not always this obvious. Suppose the -statistics module has a random() function that -returns a vector of random numbers with a given length: - -

-import statistics
-x = statistics.random(5)
-y = statistics.random(5)
-xy = statistics.xy(x, y)
-xy.correlation()
-
- -A naive user will not easily anticipate that the std_vector -module is used to pass the x and y vectors around. If -the std_vector module is in the Python module search path, -this form of ignorance is of no harm. On the contrary, we are glad -that we do not have to bother the user with details like this. - -

-If the std_vector module is not in the Python module search -path, a Python exception will be raised: - -

-Traceback (innermost last):
-  File "foo.py", line 2, in ?
-    x = statistics.random(5)
-ImportError: No module named std_vector
-
- -As is the case with any system of a non-trivial complexity, it is -important that the setup is consistent and complete. - -
-

Two-way module dependencies

- -Boost.Python supports two-way module dependencies. This is best -illustrated by a simple example. - -

-Suppose there is a module ivect that implements vectors of -integers, and a similar module dvect that implements vectors -of doubles. We want to be able do convert an integer vector to a double -vector and vice versa. For example: - -

-import ivect
-iv = ivect.ivect((1,2,3,4,5))
-dv = iv.as_dvect()
-
- -The last expression will implicitly import the dvect module in -order to enable the conversion of the C++ representation of -dvect to a Python object. The analogous is possible for a -dvect: - -
-import dvect
-dv = dvect.dvect((1,2,3,4,5))
-iv = dv.as_ivect()
-
- -Now the ivect module is imported implicitly. - -

-Note that the two-way dependencies are possible because the -dependencies are resolved only when needed. This is, the initialization -of the ivect module does not rely on the dvect -module, and vice versa. Only if as_dvect() or -as_ivect() is actually invoked will the corresponding module -be implicitly imported. This also means that, for example, the -dvect module does not have to be available at all if -as_dvect() is never used. - -


-

Clarification of compile-time and link-time dependencies

- -Boost.Python's support for resolving cross-module dependencies at -runtime does not imply that compile-time dependencies are eliminated. -For example, the statistics extension module in the example above will -need to #include <vector>. This is immediately obvious -from the definition of class xy. - -

-If a library is wrapped that consists of both header files and compiled -components (e.g. libdvect.a, dvect.lib, etc.), both -the Boost.Python extension module with the -export_converters() statement and the module with the -import_converters<> statement need to be linked against -the object library. Ideally one would build a shared library (e.g. -libdvect.so, dvect.dll, etc.). However, this -introduces the issue of having to configure the search path for the -dynamic loading correctly. For small libraries it is therefore often -more convenient to ignore the fact that the object files are loaded -into memory more than once. - -


-

Summary of motivation for cross-module support

- -The main purpose of Boost.Python's cross-module support is to allow for -a modular system layout. With this support it is straightforward to -reflect C++ code organization at the Python level. Without the -cross-module support, a multi-purpose module like std_vector -would be impractical because the entire wrapper code would somehow have -to be duplicated in all extension modules that use it, making them -harder to maintain and harder to build. - -

-Another motivation for the cross-module support is that two extension -modules that wrap the same class cannot both be imported into Python. -For example, if there are two modules A and B that -both wrap a given class X, this will work: - -

-import A
-x = A.X()
-
- -This will also work: - -
-import B
-x = B.X()
-
- -However, this will fail: - -
-import A
-import B
-python: /net/cci/rwgk/boost/boost/python/detail/extension_class.hpp:866:
-static void boost::python::detail::class_registry<X>::register_class(boost::python::detail::extension_class_base *):
-Assertion `static_class_object == 0' failed.
-Abort
-
- -A good solution is to wrap class X only once. Depending on the -situation, this could be done by module A or B, or an -additional small extension module that only wraps and exports -class X. - -

-Finally, there can be important psychological or political reasons for -using the cross-module support. If a group of classes is lumped -together with many others in a huge module, the authors will have -difficulties in being identified with their work. The situation is -much more transparent if the work is represented by a module with a -recognizable name. This is not just a question of strong egos, but also -of getting credit and funding. - -


-

Why not use export_converters() universally?

- -There is some overhead associated with the Boost.Python cross-module -support. Depending on the platform, the size of the code generated by -export_converters() is roughly 10%-20% of that generated -by class_builder<>. For a large extension module with -many wrapped classes, this could mean a significant difference. -Therefore the general recommendation is to use -export_converters() only for classes that are likely to -be used as function arguments or return values in other modules. - -
-© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, -use, modify, sell and distribute this document is granted provided this -copyright notice appears in all copies. This document is provided "as -is" without express or implied warranty, and with no claim as to its -suitability for any purpose. - -

-Updated: April 2001 - -

diff --git a/doc/data_structures.txt b/doc/data_structures.txt deleted file mode 100644 index 90e41b91..00000000 --- a/doc/data_structures.txt +++ /dev/null @@ -1,192 +0,0 @@ -Given a real Python class 'A', a wrapped C++ class 'B', and this definition: - - class C(A, B): - def __init__(self): - B.__init__(self) - self.x = 1 - ... - - c = C() - -this diagram describes the internal structure of an instance of 'C', including -its inheritance relationships. Note that ExtensionClass is derived from -Class, and is in fact identical for all intents and purposes. - - MetaClass - +---------+ +---------+ -types.ClassType: | | | | - | | | | - | | | | - +---------+ +---------+ - ^ ^ ^ - PyClassObject | ExtensionClass | | - A: +------------+ | B: +------------+ | | - | ob_type -+-+ | ob_type -+-----+ | - | | ()<--+- __bases__ | | - | | | __dict__ -+->{...} | - | | 'B'<-+- __name__ | | - +------------+ +------------+ | - ^ ^ | - | | | - +-----+ +-------------+ | - | | | - | | Class | - | | C: +------------+ | - | | | ob_type -+------------+ - tuple:(*, *)<--+- __bases__ | - | __dict__ -+->{__module__, } - 'C' <-+- __name__ | - +------------+ - ^ (in case of inheritance from more than one - | extension class, this vector would contain - +---------------+ a pointer to an instance holder for the data - | of each corresponding C++ class) - | ExtensionInstance - | c: +---------------------+ std::vector - +----+- __class__ | +---+-- - | m_wrapped_objects -+->| * | ... - {'x': 1}<-+- __dict__ | +-|-+-- - +---------------------+ | InstanceValueHolder - | +--------------------------------+ - +-->| (contains a C++ instance of B) | - +--------------------------------+ - - - - - - -In our inheritance test cases in extclass_demo.cpp/test_extclass.py, we have the -following C++ inheritance hierarchy: - - +-----+ +----+ - | A1 | | A2 | - +-----+ +----+ - ^ ^ ^ ^ ^ - | | | | | - +-----+ | +---------+-----+ - | | | | - | +---+----------+ - .......!...... | | - : A_callback : +-+--+ +-+--+ - :............: | B1 | | B2 | - +----+ +----+ - ^ - | - +-------+---------+ - | | - +-+-+ ......!....... - | C | : B_callback : - +---+ :............: - - -A_callback and B_callback are used as part of the wrapping mechanism but not -represented in Python. C is also not represented in Python but is delivered -there polymorphically through a smart pointer. - -This is the data structure in Python. - - ExtensionClass - A1: +------------+ - ()<--+- __bases__ | - | __dict__ -+->{...} - +------------+ - ^ - | ExtensionInstance - | a1: +---------------------+ vec InstanceValueHolder - +---------+- __class__ | +---+ +---------------------+ - | | m_wrapped_objects -+->| *-+-->| contains A_callback | - | +---------------------+ +---+ +---------------------+ - | - | ExtensionInstance - | pa1_a1: +---------------------+ vec InstancePtrHolder,A1> - +---------+- __class__ | +---+ +---+ - | | m_wrapped_objects -+->| *-+-->| *-+-+ A1 - | +---------------------+ +---+ +---+ | +---+ - | +->| | - | ExtensionInstance +---+ - | pb1_a1: +---------------------+ vec InstancePtrHolder,A1> - +---------+- __class__ | +---+ +---+ - | | m_wrapped_objects -+->| *-+-->| *-+-+ B1 - | +---------------------+ +---+ +---+ | +---+ - | +->| | - | ExtensionInstance +---+ - | pb2_a1: +---------------------+ vec InstancePtrHolder,A1> - +---------+- __class__ | +---+ +---+ - | | m_wrapped_objects -+->| *-+-->| *-+-+ B2 - | +---------------------+ +---+ +---+ | +---+ - | +->| | - | +---+ - | ExtensionClass - | A2: +------------+ - | ()<--+- __bases__ | - | | __dict__ -+->{...} - | +------------+ - | ^ - | | ExtensionInstance - | a2: | +---------------------+ vec InstanceValueHolder - | +-+- __class__ | +---+ +-------------+ - | | | m_wrapped_objects -+->| *-+-->| contains A2 | - | | +---------------------+ +---+ +-------------+ - | | - | | ExtensionInstance - | pa2_a2: | +---------------------+ vec InstancePtrHolder,A2> - | +-+- __class__ | +---+ +---+ - | | | m_wrapped_objects -+->| *-+-->| *-+-+ A2 - | | +---------------------+ +---+ +---+ | +---+ - | | +->| | - | | ExtensionInstance +---+ - | pb1_a2: | +---------------------+ vec InstancePtrHolder,A2> - | +-+- __class__ | +---+ +---+ - | | | m_wrapped_objects -+->| *-+-->| *-+-+ B1 - | | +---------------------+ +---+ +---+ | +---+ - | | +->| | - | | +---+ - | | - | +---------------+------------------------------+ - | | | - +------+-------------------------+-|----------------------------+ | - | | | | | - | Class | | ExtensionClass | | ExtensionClass - | DA1: +------------+ | | B1: +------------+ | | B2: +------------+ -(*,)<---+- __bases__ | (*,*)<---+- __bases__ | (*,*)<---+- __bases__ | - | __dict__ -+->{...} | __dict__ -+->{...} | __dict__ -+->{...} - +------------+ +------------+ +------------+ - ^ ^ ^ - | ExtensionInstance | | - | da1: +---------------------+ | vec InstanceValueHolder - +-------+- __class__ | | +---+ +---------------------+ | - | m_wrapped_objects -+--|-->| *-+-->| contains A_callback | | - +---------------------+ | +---+ +---------------------+ | - +--------------------------------------+ | - | ExtensionInstance | - b1: | +---------------------+ vec InstanceValueHolder | - +-+- __class__ | +---+ +---------------------+ | - | | m_wrapped_objects -+->| *-+-->| contains B_callback | | - | +---------------------+ +---+ +---------------------+ | - | | - | ExtensionInstance | -pb1_b1: | +---------------------+ vec InstancePtrHolder,B1> | - +-+- __class__ | +---+ +---+ | - | | m_wrapped_objects -+->| *-+-->| *-+-+ B1 | - | +---------------------+ +---+ +---+ | +---+ | - | +->| | | - | ExtensionInstance +---+ | - pc_b1: | +---------------------+ vec InstancePtrHolder,B1> | - +-+- __class__ | +---+ +---+ | - | | m_wrapped_objects -+->| *-+-->| *-+-+ C | - | +---------------------+ +---+ +---+ | +---+ | - | +->| | | - | +---+ | - | | - | Class +---------------------------------------+ - | DB1: +------------+ | ExtensionInstance - (*,)<---+- __bases__ | a2: | +---------------------+ vec InstanceValueHolder - | __dict__ -+->{...} +-+- __class__ | +---+ +-------------+ - +------------+ | m_wrapped_objects -+->| *-+-->| contains A2 | - ^ +---------------------+ +---+ +-------------+ - | ExtensionInstance - db1: | +---------------------+ vec InstanceValueHolder - +-+- __class__ | +---+ +----------------------+ - | m_wrapped_objects -+-->| *-+-->| contains B1_callback | - +---------------------+ +---+ +----------------------+ diff --git a/doc/enums.html b/doc/enums.html deleted file mode 100644 index c58ca34d..00000000 --- a/doc/enums.html +++ /dev/null @@ -1,120 +0,0 @@ - - - Wrapping enums - -
-

- c++boost.gif (8819 bytes)
- Wrapping enums -

- -

Because there is in general no way to deduce that a value of arbitrary type T -is an enumeration constant, the Boost Python Library cannot automatically -convert enum values to and from Python. To handle this case, you need to decide -how you want the enum to show up in Python (since Python doesn't have -enums). Once you have done that, you can write some simple -from_python() and to_python() functions. - -

If you are satisfied with a Python int as a way to represent your enum -values, we provide a shorthand for these functions. You just need to cause -boost::python::enum_as_int_converters<EnumType> to be -instantiated, where -EnumType is your enumerated type. There are two convenient ways to do this: - -

    -
  1. Explicit instantiation: - -
    -  template class boost::python::enum_as_int_converters<my_enum>;
    -
    - -Some buggy C++ implementations require a class to be instantiated in the same -namespace in which it is defined. In that case, the simple incantation above becomes: - -
    -
    -   ...
    -} // close my_namespace
    -
    -// drop into namespace python and explicitly instantiate
    -namespace boost { namespace python {
    -  template class enum_as_int_converters<my_enum_type>;
    -}} // namespace boost::python
    -
    -namespace my_namespace { // re-open my_namespace
    -   ...
    -
    -
    - - -
  2. If you have such an implementation, you may find this technique more convenient -
    -// instantiate as base class in any namespace
    -struct EnumTypeConverters
    -    : boost::python::enum_as_int_converters<EnumType>
    -{
    -};
    -
    -
- -

Either of the above is equivalent to the following declarations: -

-BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
-
-  MyEnumType from_python(PyObject* x, boost::python::type<MyEnumType>)
-  {
-      return static_cast<MyEnum>(
-        from_python(x, boost::python::type<long>()));
-  }
-
-  MyEnumType from_python(PyObject* x, boost::python::type<const MyEnumType&>)
-  {
-      return static_cast<MyEnum>(
-        from_python(x, boost::python::type<long>()));
-  }
-
-  PyObject* to_python(MyEnumType x)
-  {
-      return to_python(static_cast<long>(x));
-  }
-BOOST_PYTHON_END_CONVERSION_NAMESPACE
-
- -

This technique defines the conversions of -MyEnumType in terms of the conversions for the built-in - long type. - -You may also want to add a bunch of lines like this to your module -initialization. These bind the corresponding enum values to the appropriate -names so they can be used from Python: - -

-mymodule.add(boost::python::make_ref(enum_value_1), "enum_value_1");
-mymodule.add(boost::python::make_ref(enum_value_2), "enum_value_2");
-...
-
- -You can also add these to an extension class definition, if your enum happens to -be local to a class and you want the analogous interface in Python: - -
-my_class_builder.add(boost::python::to_python(enum_value_1), "enum_value_1");
-my_class_builder.add(boost::python::to_python(enum_value_2), "enum_value_2");
-...
-
-

- Next: Pointers and Smart Pointers - Previous: Building an Extension Module - Up: Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as - is'' without express or implied warranty, and with no claim as to - its suitability for any purpose. -

- Updated: Mar 6, 2001 -

- diff --git a/doc/example1.html b/doc/example1.html deleted file mode 100644 index 402cc7a6..00000000 --- a/doc/example1.html +++ /dev/null @@ -1,82 +0,0 @@ - - - A Simple Example - -
-

- - -

-

- A Simple Example -

-

- Suppose we have the following C++ API which we want to expose in - Python: -

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

- Here is the C++ code for a python module called getting_started1 - which exposes the API. -

-
-#include <boost/python/class_builder.hpp>
-namespace python = boost::python;
-
-BOOST_PYTHON_MODULE_INIT(getting_started1)
-{
-  try
-  {
-    // Create an object representing this extension module.
-    python::module_builder this_module("getting_started1");
-
-    // Add regular functions to the module.
-    this_module.def(greet, "greet");
-    this_module.def(square, "square");
-  }
-  catch(...)
-  {
-    python::handle_exception(); // Deal with the exception for Python
-  }
-}
-
-
-

- That's it! If we build this shared library and put it on our - PYTHONPATH we can now access our C++ functions from - Python. -

-
->>> import getting_started1
->>> print getting_started1.greet()
-hello, world
->>> number = 11
->>> print number, '*', number, '=', getting_started1.square(number)
-11 * 11 = 121
-
-

- Next: Exporting Classes - Previous: Comparisons with other systems Up: - Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

- Updated: Mar 6, 2000 -

- diff --git a/doc/exporting_classes.html b/doc/exporting_classes.html deleted file mode 100644 index 61c5ef88..00000000 --- a/doc/exporting_classes.html +++ /dev/null @@ -1,150 +0,0 @@ - - - Exporting Classes - -
-

- - -

-

- Exporting Classes -

-

- Now let's expose a C++ class to Python: - -

-#include <iostream>
-#include <string>
-
-namespace { // Avoid cluttering the global namespace.
-
-  // A friendly class.
-  class hello
-  {
-    public:
-      hello(const std::string& country) { this->country = country; }
-      std::string greet() const { return "Hello from " + country; }
-    private:
-      std::string country;
-  };
-
-  // A function taking a hello object as an argument.
-  std::string invite(const hello& w) {
-    return w.greet() + "! Please come soon!";
-  }
-}
-
-

- To expose the class, we use a class_builder in addition to the - module_builder from the previous example. Class member functions - are exposed by using the def() member function on the - class_builder: -

-#include <boost/python/class_builder.hpp>
-namespace python = boost::python;
-
-BOOST_PYTHON_MODULE_INIT(getting_started2)
-{
-  try
-  {
-    // Create an object representing this extension module.
-    python::module_builder this_module("getting_started2");
-
-    // Create the Python type object for our extension class.
-    python::class_builder<hello> hello_class(this_module, "hello");
-
-    // Add the __init__ function.
-    hello_class.def(python::constructor<std::string>());
-    // Add a regular member function.
-    hello_class.def(&hello::greet, "greet");
-
-    // Add invite() as a regular function to the module.
-    this_module.def(invite, "invite");
-
-    // Even better, invite() can also be made a member of hello_class!!!
-    hello_class.def(invite, "invite");
-  }
-  catch(...)
-  {
-    python::handle_exception(); // Deal with the exception for Python
-  }
-}
-
-

-Now we can use the class normally from Python: - -

->>> from getting_started2 import *
->>> hi = hello('California')
->>> hi.greet()
-'Hello from California'
->>> invite(hi)
-'Hello from California! Please come soon!'
->>> hi.invite()
-'Hello from California! Please come soon!'
-
- -Notes:
    -
  • We expose the class' constructor by calling def() on the - class_builder with an argument whose type is - constructor<params>, where params - matches the list of constructor argument types: - - -
  • Regular member functions are defined by calling def() with a - member function pointer and its Python name: - -
  • Any function added to a class whose initial argument matches the class (or -any base) will act like a member function in Python. - -
  • To define a nested class, just pass the enclosing -class_builder (instead of a module_builder) as the -first argument to the nested class_builder's constructor. - - -
-

- We can even make a subclass of hello.world: - -

->>> class wordy(hello):
-...     def greet(self):
-...         return hello.greet(self) + ', where the weather is fine'
-...
->>> hi2 = wordy('Florida')
->>> hi2.greet()
-'Hello from Florida, where the weather is fine'
->>> invite(hi2)
-'Hello from Florida! Please come soon!'
-
-

- Pretty cool! You can't do that with an ordinary Python extension type! - - Of course, you may now have a slightly empty feeling in the pit of - your little pythonic stomach. Perhaps you wanted to see the following - wordy invitation: - -

-'Hello from Florida, where the weather is fine! Please come soon!'
-
- - After all, invite calls hello::greet(), and you - reimplemented that in your Python subclass, wordy. If so, read on... - -

- Next: Overridable virtual functions - Previous: A Simple Example Up: - Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

- Updated: Mar 6, 2001 -

- diff --git a/doc/extending.html b/doc/extending.html deleted file mode 100644 index 8839ab43..00000000 --- a/doc/extending.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - A Brief Introduction to writing Python extension modules - -

- c++boost.gif (8819 bytes) -

-

- A Brief Introduction to writing Python extension modules -

-

- Interfacing any language to Python involves building a module which can - be loaded by the Python interpreter, but which isn't written in Python. - This is known as an extension module. Many of the built-in Python - libraries are constructed in 'C' this way; Python even supplies its - fundamental - types using the same mechanism. An extension module can be statically - linked with the Python interpreter, but it more commonly resides in a - shared library or DLL. -

- As you can see from The Python Extending - and Embedding Tutorial, writing an extension module normally means - worrying about -

- This last item typically occupies a great deal of code in an extension - module. Remember that Python is a completely dynamic language. A callable - object receives its arguments in a tuple; it is up to that object to extract - those arguments from the tuple, check their types, and raise appropriate - exceptions. There are numerous other tedious details that need to be - managed; too many to mention here. The Boost Python Library is designed to - lift most of that burden.
-
- -

- Another obstacle that most people run into eventually when extending - Python is that there's no way to make a true Python class in an extension - module. The typical solution is to create a new Python type in the - extension module, and then write an additional module in 100% Python. The - Python module defines a Python class which dispatches to an instance of - the extension type, which it contains. This allows users to write - subclasses of the class in the Python module, almost as though they were - sublcassing the extension type. Aside from being tedious, it's not really - the same as having a true class, because there's no way for the user to - override a method of the extension type which is called from the - extension module. Boost.Python solves this problem by taking advantage of Python's metaclass - feature to provide objects which look, walk, and hiss almost exactly - like regular Python classes. Boost.Python classes are actually cleaner than - Python classes in some subtle ways; a more detailed discussion will - follow (someday).

-

Next: Comparisons with Other Systems Up: Top

-

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability for - any purpose.

- diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index f636e7a8..00000000 --- a/doc/index.html +++ /dev/null @@ -1,166 +0,0 @@ - - - The Boost Python Library (Boost.Python) - -

- c++boost.gif (8819 bytes)
The Boost Python Library (Boost.Python) -

- -

Synopsis

-

- Use the Boost Python Library to quickly and easily export a C++ library to Python such that the Python interface is - very similar to the C++ interface. It is designed to be minimally - 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 - should simply ``reflect'' your C++ classes and functions into - Python. The major features of Boost.Python include support for: -

-among others. - - -

Supported Platforms

-

Boost.Python is known to have been tested in the following configurations: - -

- -

Credits

-
    -
  • David Abrahams originated - and wrote most of the library, and continues to coordinate development. - -
  • Ullrich Koethe - had independently developed a similar system. When he discovered Boost.Python, - he generously contributed countless hours of coding and much insight into - improving it. He is responsible for an early version of the support for function overloading and wrote the support for - reflecting C++ inheritance - relationships. He has helped to improve error-reporting from both - Python and C++, and has designed an extremely easy-to-use way of - exposing numeric operators, including - a way to avoid explicit coercion by means of overloading. - -
  • Ralf W. - Grosse-Kunstleve contributed pickle support - and numerous other small improvements. He's working on a way to allow - types exported by multiple modules to interact. - -
  • The members of the boost mailing list and the Python community - supplied invaluable early feedback. In particular, Ron Clarke, Mark Evans, - Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott took the - brave step of trying to use Boost.Python while it was still in early - stages of development. - -
  • The development of Boost.Python wouldn't have been possible without - the generous support of Dragon - Systems/Lernout and Hauspie, Inc who supported its development as an - open-source project. -
- -

Table of Contents

- -
    -
  1. A Brief Introduction to writing Python - extension modules - -
  2. Comparisons between Boost.Python and other - systems for extending Python - -
  3. A Simple Example - -
  4. Exporting Classes - -
  5. Overridable Virtual Functions - -
  6. Function Overloading - -
  7. Inheritance - -
  8. Special Method and Operator Support - -
  9. A Peek Under the Hood - -
  10. Building an Extension Module - -
  11. Pickle Support - -
  12. Cross-Extension-Module Dependencies - -
  13. Wrapping Enums - -
  14. Pointers and Smart Pointers - -
  15. Internal Data Structures - -
- -

- Documentation is a major ongoing project; assistance is greatly - appreciated! In the meantime, useful examples of every Boost.Python feature should - be evident in the regression test files test/comprehensive.[py/hpp/cpp] - -

- Questions should be directed to the boost mailing list. - -

- © Copyright David Abrahams 2001. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as is'' without - express or implied warranty, and with no claim as to its suitability for - any purpose. -

- Updated: Mar 6, 2001 - diff --git a/doc/inheritance.html b/doc/inheritance.html deleted file mode 100644 index cd95c744..00000000 --- a/doc/inheritance.html +++ /dev/null @@ -1,173 +0,0 @@ - - - Inheritance - -

-

- c++boost.gif (8819 bytes)Inheritance -

- -

Inheritance in Python

- -

- Boost.Python extension classes support single and multiple-inheritance in - Python, just like regular Python classes. You can arbitrarily mix - built-in Python classes with extension classes in a derived class' - tuple of bases. Whenever a Boost.Python extension class is among the bases for a - new class in Python, the result is an extension class: -

-
->>> class MyPythonClass:
-...     def f(): return 'MyPythonClass.f()'
-...
->>> import my_extension_module
->>> class Derived(my_extension_module.MyExtensionClass, MyPythonClass):
-...     '''This is an extension class'''
-...     pass
-...
->>> x = Derived()
->>> x.f()
-'MyPythonClass.f()'
->>> x.g()
-'MyExtensionClass.g()'
-
-
- -

Reflecting C++ Inheritance Relationships

-

- Boost.Python also allows us to represent C++ inheritance relationships so that - wrapped derived classes may be passed where values, pointers, or - references to a base class are expected as arguments. The - declare_base member function of - class_builder<> is used to establish the relationship - between base and derived classes: - -

-
-#include <memory> // for std::auto_ptr<>
-
-struct Base {
-    virtual ~Base() {}
-    virtual const char* name() const { return "Base"; }
-};
-
-struct Derived : Base {
-    Derived() : x(-1) {}
-    virtual const char* name() const { return "Derived"; }
-    int x;
-};
-
-std::auto_ptr<Base> derived_as_base() {
-    return std::auto_ptr<Base>(new Derived);
-}
-
-const char* get_name(const Base& b) {
-    return b.name();
-}
-
-int get_derived_x(const Derived& d) {
-    return d.x;
-}
-    
-#include <boost/python/class_builder.hpp> - -// namespace alias for code brevity -namespace python = boost::python; - -BOOST_PYTHON_MODULE_INIT(my_module) -{ -    try -    { -       python::module_builder my_module("my_module"); - -       python::class_builder<Base> base_class(my_module, "Base"); -       base_class.def(python::constructor<void>()); - -       python::class_builder<Derived> derived_class(my_module, "Derived"); -       derived_class.def(python::constructor<void>()); - // Establish the inheritance relationship between Base and Derived - derived_class.declare_base(base_class); - - my_module.def(derived_as_base, "derived_as_base"); - my_module.def(get_name, "get_name"); - my_module.def(get_derived_x, "get_derived_x"); -    } -    catch(...) -    { -       python::handle_exception();    // Deal with the exception for Python -    } -} -
-
- -

- Then, in Python: -

-
->>> from my_module import *
->>> base = Base()
->>> derived = Derived()
->>> get_name(base)
-'Base'
-
-
-objects of wrapped class Derived may be passed where Base is expected -
-
->>> get_name(derived) 
-'Derived'
-
-
-objects of wrapped class Derived can be passed where Derived is -expected but where type information has been lost. -
-
->>> get_derived_x(derived_as_base()) 
--1
-
-
- -

Inheritance Without Virtual Functions

- -

- If for some reason your base class has no virtual functions but you still want - to represent the inheritance relationship between base and derived classes, - pass the special symbol boost::python::without_downcast as the 2nd parameter - to declare_base: - -

-
-struct Base2 {};
-struct Derived2 { int f(); };
-
- ... -   python::class_builder<Base> base2_class(my_module, "Base2"); -   base2_class.def(python::constructor<void>()); - -   python::class_builder<Derived2> derived2_class(my_module, "Derived2"); -   derived2_class.def(python::constructor<void>()); - derived_class.declare_base(base_class, python::without_downcast); -
-
- -

This approach will allow Derived2 objects to be passed where - Base2 is expected, but does not attempt to implicitly convert (downcast) - smart-pointers to Base2 into Derived2 pointers, - references, or values. - -

- Next: Special Method and Operator Support - Previous: Function Overloading - Up: Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

- Updated: Nov 26, 2000 -

- diff --git a/doc/new-conversions.html b/doc/new-conversions.html deleted file mode 100644 index cd8a5b19..00000000 --- a/doc/new-conversions.html +++ /dev/null @@ -1,326 +0,0 @@ - - - - -A New Type Conversion Mechanism for Boost.Python - - - - -

- -

A New Type Conversion Mechanism for Boost.Python

- -

By David Abrahams. - -

Introduction

- -This document describes a redesign of the mechanism for automatically -converting objects between C++ and Python. The current implementation -uses two functions for any type T: - -
-U from_python(PyObject*, type<T>);
-void to_python(V);
-
- -where U is convertible to T and T is convertible to V. These functions -are at the heart of C++/Python interoperability in Boost.Python, so -why would we want to change them? There are many reasons: - -

Bugs

-

Firstly, the current mechanism relies on a common C++ compiler -bug. This is not just embarrassing: as compilers get to be more -conformant, the library stops working. The issue, in detail, is the -use of inline friend functions in templates to generate -conversions. It is a very powerful, and legal technique as long as -it's used correctly: - -

-template <class Derived>
-struct add_some_functions
-{
-     friend return-type some_function1(..., Derived cv-*-&-opt, ...);
-     friend return-type some_function2(..., Derived cv-*-&-opt, ...);
-};
-
-template <class T>
-struct some_template : add_some_functions<some_template<T> >
-{
-};
-
- -The add_some_functions template generates free functions -which operate on Derived, or on related types. Strictly -speaking the related types are not just cv-qualified Derived -values, pointers and/or references. Section 3.4.2 in the standard -describes exactly which types you must use as parameters to these -functions if you want the functions to be found -(there is also a less-technical description in section 11.5.1 of -C++PL3 [1]). Suffice it to say that -with the current design, the from_python and -to_python functions are not supposed to be callable under any -conditions! - -

Compilation and Linking Time

- -The conversion functions generated for each wrapped class using the -above technique are not function templates, but regular functions. The -upshot is that they must all be generated regardless of whether -they are actually used. Generating all of those functions can slow -down module compilation, and resolving the references can slow down -linking. - -

Efficiency

- -The conversion functions are primarily used in (member) function -wrappers to convert the arguments and return values. Being functions, -converters have no interface which allows us to ask "will the -conversion succeed?" without calling the function. Since the -return value of the function must be the object to be passed as an -argument, Boost.Python currently uses C++ exception-handling to detect -an unsuccessful conversion. It's not a particularly good use of -exception-handling, since the failure is not handled very far from -where it occurred. More importantly, it means that C++ exceptions are -thrown during overload resolution as we seek an overload that matches -the arguments passed. Depending on the implementation, this approach -can result in significant slowdowns. - -

It is also unclear that the current library generates a minimal -amount of code for any type conversion. Many of the conversion -functions are nontrivial, and partly because of compiler limitations, -they are declared inline. Also, we could have done a better -job separating the type-specific conversion code from the code which -is type-independent. - -

Cross-module Support

- -The current strategy requires every module to contain the definition -of conversions it uses. In general, a new module can never supply -conversion code which is used by another module. Ralf Grosse-Kunstleve -designed a clever system which imports conversions directly from one -library into another using some explicit declarations, but it has some -disadvantages also: - -
    -
  1. The system Ullrich Koethe designed for implicit conversion between -wrapped classes related through inheritance does not currently work if -the classes are defined in separate modules. - -
  2. The writer of the importing module is required to know the name of -the module supplying the imported conversions. - -
  3. There can be only one way to extract any given C++ type from a -Python object in a given module. -
- -The first item might be addressed by moving Boost.Python into a shared -library, but the other two cannot. Ralf turned the limitation in item -two into a feature: the required module is loaded implicitly when a -conversion it defines is invoked. We will probably want to provide -that functionality anyway, but it's not clear that we should require -the declaration of all such conversions. The final item is a more -serious limitation. If, for example, new numeric types are defined in -separate modules, and these types can all be converted to -doubles, we have to choose just one conversion method. - -

Ease-of-use

- -One persistent source of confusion for users of Boost.Python has been -the fact that conversions for a class are not be visible at -compile-time until the declaration of that class has been seen. When -the user tries to expose a (member) function operating on or returning -an instance of the class in question, compilation fails...even though -the user goes on to expose the class in the same translation unit! - -

-The new system lifts all compile-time checks for the existence of -particular type conversions and replaces them with runtime checks, in -true Pythonic style. While this might seem cavalier, the compile-time -checks are actually not much use in the current system if many classes -are wrapped in separate modules, since the checks are based only on -the user's declaration that the conversions exist. - -

The New Design

- -

Motivation

- -The new design was heavily influenced by a desire to generate as -little code as possible in extension modules. Some of Boost.Python's -clients are enormous projects where link time is proportional to the -amount of object code, and there are many Python extension modules. As -such, we try to keep type-specific conversion code out of modules -other than the one the converters are defined in, and rely as much as -possible on centralized control through a shared library. - -

The Basics

- -The library contains a registry which maps runtime type -identifiers (actually an extension of std::type_info which -preserves references and constness) to entries containing type -converters. An entry can contain only one converter from C++ to Python -(wrapper), but many converters from Python to C++ -(unwrappers). What should happen if -multiple modules try to register wrappers for the same type?. Wrappers -and unwrappers are known as body objects, and are accessed -by the user and the library (in its function-wrapping code) through -corresponding handle (wrap<T> and -unwrap<T>) objects. The handle objects are -extremely lightweight, and delegate all of their operations to -the corresponding body. - -

-When a handle object is constructed, it accesses the -registry to find a corresponding body that can convert the -handle's constructor argument. Actually the registry record for any -type -Tused in a module is looked up only once and stored in a -static registration<T> object for efficiency. For -example, if the handle is an unwrap<Foo&> object, -the entry for Foo& is looked up in the -registry, and each unwrapper it contains is queried -to determine if it can convert the -PyObject* with which the unwrap was constructed. If -a body object which can perform the conversion is found, a pointer to -it is stored in the handle. A body object may at any point store -additional data in the handle to speed up the conversion process. - -

-Now that the handle has been constructed, the user can ask it whether -the conversion can be performed. All handles can be tested as though -they were convertible to bool; a true value -indicates success. If the user forges ahead and tries to do the -conversion without checking when no conversion is possible, an -exception will be thrown as usual. The conversion itself is performed -by the body object. - -

Handling complex conversions

- -

Some conversions may require a dynamic allocation. For example, -when a Python tuple is converted to a std::vector<double> -const&, we need some storage into which to construct the -vector so that a reference to it can be formed. Furthermore, multiple -conversions of the same type may need to be "active" -simultaneously, so we can't keep a single copy of the storage -anywhere. We could keep the storage in the body object, and -have the body clone itself in case the storage is used, but in that -case the storage in the body which lives in the registry is never -used. If the storage was actually an object of the target type (the -safest way in C++), we'd have to find a way to construct one for the -body in the registry, since it may not have a default constructor. - -

-The most obvious way out of this quagmire is to allocate the object using a -new-expression, and store a pointer to it in the handle. Since -the body object knows everything about the data it needs to -allocate (if any), it is also given responsibility for destroying that -data. When the handle is destroyed it asks the body -object to tear down any data it may have stored there. In many ways, -you can think of the body as a "dynamically-determined -vtable" for the handle. - -

Eliminating Redundancy

- -If you look at the current Boost.Python code, you'll see that there -are an enormous number of conversion functions generated for each -wrapped class. For a given class T, functions are generated -to extract the following types from_python: - -
-T*
-T const*
-T const* const&
-T* const&
-T&
-T const&
-T
-std::auto_ptr<T>&
-std::auto_ptr<T>
-std::auto_ptr<T> const&
-boost::shared_ptr<T>&
-boost::shared_ptr<T>
-boost::shared_ptr<T> const&
-
- -Most of these are implemented in terms of just a few conversions, and -if you're lucky, they will be inlined and cause no extra -overhead. In the new system, however, a significant amount of data -will be associated with each type that needs to be converted. We -certainly don't want to register a separate unwrapper object for all -of the above types. - -

Fortunately, much of the redundancy can be eliminated. For example, -if we generate an unwrapper for T&, we don't need an -unwrapper for T const& or T. Accordingly, the user's -request to wrap/unwrap a given type is translated at compile-time into -a request which helps to eliminate redundancy. The rules used to -unwrap a type are: - -

    -
  1. Treat built-in types specially: when unwrapping a value or - constant reference to one of these, use a value for the target - type. It will bind to a const reference if neccessary, and more - importantly, avoids having to dynamically allocate room for - an lvalue of types which can be cheaply copied. -
  2. - Reduce everything else to a reference to an un-cv-qualified type - where possible. Since cv-qualification is lost on Python - anyway, there's no point in trying to convert to a - const&. What about conversions - to values like the tuple->vector example above? It seems to me - that we don't want to make a vector<double>& - (non-const) converter available for that case. We may need to - rethink this slightly. -
- -

To handle the problem described above in item 2, we modify the -procedure slightly. To unwrap any non-scalar T, we seek an -unwrapper for add_reference<T>::type. Unwrappers for -T const& always return T&, and are -registered under both T & and -T const&. - -

For compilers not supporting partial specialization, unwrappers for -T const& must return T const& -(since constness can't be stripped), but a separate unwrapper object -need to be registered for T & and -T const& anyway, for the same reasons. - -We may want to make it possible to compile as -though partial specialization were unavailable even on compilers where -it is available, in case modules could be compiled by different -compilers with compatible ABIs (e.g. Intel C++ and MSVC6). - -

Efficient Argument Conversion

- -Since type conversions are primarily used in function wrappers, an -optimization is provided for the case where a group of conversions are -used together. Each handle class has a corresponding -"_more" class which does the same job, but has a -trivial destructor. Instead of asking each "_more" -handle to destroy its own body, it is linked into an endogenous list -managed by the first (ordinary) handle. The wrap and -unwrap destructors are responsible for traversing that list -and asking each body class to tear down its -handle. This mechanism is also used to determine if all of -the argument/return-value conversions can succeed with a single -function call in the function wrapping code. We -might need to handle return values in a separate step for Python -callbacks, since the availablility of a conversion won't be known -until the result object is retrieved. - -
-
-

References

- -

[1]B. Stroustrup, The C++ Programming Language -Special Edition Addison-Wesley, ISBN 0-201-70073-5. - -


-

Revised 19 December 2001

-

© Copyright David Abrahams, 2001

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

- c++boost.gif (8819 bytes)Function Overloading -

- -

An Example

-

- To expose overloaded functions in Python, simply def() each - one with the same Python name: -

-
-inline int f1() { return 3; }
-inline int f2(int x) { return x + 1; }
-
-class X {
-public:
-    X() : m_value(0) {}
-    X(int n) : m_value(n) {}
-    int value() const { return m_value; }
-    void value(int v) { m_value = v; }
-private:
-    int m_value;
-};
-  ...
-
-BOOST_PYTHON_MODULE_INIT(overload_demo)
-{
-    try
-    {
-        boost::python::module_builder overload_demo("overload_demo");
-        // Overloaded functions at module scope
-        overload_demo.def(f1, "f");
-        overload_demo.def(f2, "f");
-
-        boost::python::class_builder<X> x_class(overload_demo, "X");
-        // Overloaded constructors
-        x_class.def(boost::python::constructor<>());
-        x_class.def(boost::python::constructor<int>());
-
-        // Overloaded member functions
-        x_class.def((int (X::*)() const)&X::value, "value");
-        x_class.def((void (X::*)(int))&X::value, "value");
-  ...
-
-
- -

- Now in Python: -

-
->>> from overload_demo import *
->>> x0 = X()
->>> x1 = X(1)
->>> x0.value()
-0
->>> x1.value()
-1
->>> x0.value(3)
->>> x0.value()
-3
->>> X('hello')
-TypeError: No overloaded functions match (X, string). Candidates are:
-void (*)()
-void (*)(int)
->>> f()
-3
->>> f(4)
-5
-
-
- -

Discussion

-

- Notice that overloading in the Python module was produced three ways:

    -
  1. by combining the non-overloaded C++ functions int f1() - and int f2(int) and exposing them as f in Python. -
  2. by exposing the overloaded constructors of class X -
  3. by exposing the overloaded member functions X::value. -
-

- Techniques 1. and 3. above are really alternatives. In case 3, you need - to form a pointer to each of the overloaded functions. The casting - syntax shown above is one way to do that in C++. Case 1 does not require - complicated-looking casts, but may not be viable if you can't change - your C++ interface. N.B. There's really nothing unsafe about casting an - overloaded (member) function address this way: the compiler won't let - you write it at all unless you get it right. - -

An Alternative to Casting

-

- This approach is not neccessarily better, but may be preferable for some - people who have trouble writing out the types of (member) function - pointers or simply prefer to avoid all casts as a matter of principle: -

-
-// Forwarding functions for X::value
-inline void set_x_value(X& self, int v) { self.value(v); }
-inline int get_x_value(X& self) { return self.value(); }
-   ...
-        // Overloaded member functions
-        x_class.def(set_x_value, "value");
-        x_class.def(get_x_value, "value");
-
-
-

Here we are taking advantage of the ability to expose C++ functions at -namespace scope as Python member functions. - -

Overload Resolution

-

- The function overload resolution mechanism works as follows: - -

    - -
  • Attribute lookup for extension classes proceeds in the - usual Python way using a depth-first, left-to-right search. When a - class is found which has a matching attribute, only functions overloaded - in the context of that class are candidates for overload resolution. In - this sense, overload resolution mirrors the C++ mechanism, where a name - in a derived class ``hides'' all functions with the same name from a base - class. -

    - -

  • Within a name-space context (extension class or module), overloaded - functions are tried in the same order they were - def()ed. The first function whose signature can be made to - match each argument passed is the one which is ultimately called. - This means in particular that you cannot overload the same function on - both ``int'' and ``float'' because Python - automatically converts either of the two types into the other one. - If the ``float'' overload is found first, it is used - also used for arguments of type ``int'' as well, and the - ``int'' version of the function is never invoked. -
- -

- Next: Inheritance - Previous: Overridable Virtual Functions - Up: Top -

- © Copyright David Abrahams 2001. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as - is'' without express or implied warranty, and with no claim as to - its suitability for any purpose. -

- Updated: Mar 6, 2001 -

- diff --git a/doc/overriding.html b/doc/overriding.html deleted file mode 100644 index 02665be5..00000000 --- a/doc/overriding.html +++ /dev/null @@ -1,215 +0,0 @@ - - - - Overridable Virtual Functions - - c++boost.gif (8819 bytes) - -

Overridable Virtual Functions

- -

- In the previous example we exposed a simple - C++ class in Python and showed that we could write a subclass. We even - redefined one of the functions in our derived class. Now we will learn - how to make the function behave virtually when called from C++. - - -

Example

- -

In this example, it is assumed that hello::greet() is a virtual -member function: - -

-class hello
-{
- public:
-    hello(const std::string& country) { this->country = country; }
-    virtual std::string greet() const { return "Hello from " + country; }
-    virtual ~hello(); // Good practice 
-    ...
-};
-
- -

- We'll need a derived class* to help us - dispatch the call to Python. In our derived class, we need the following - elements: - -

    - -
  1. A PyObject* data member (usually - called self) that holds a pointer to the Python object corresponding - to our C++ hello instance. - -
  2. For each exposed constructor of the - base class T, a constructor which takes the same parameters preceded by an initial - PyObject* argument. The initial argument should be stored in the self data - member described above. - -
  3. If the class being wrapped is ever returned by - value from a wrapped function, be sure you do the same for the - T's copy constructor: you'll need a constructor taking arguments - (PyObject*, const T&). - -
  4. An implementation of each virtual function you may - wish to override in Python which uses - callback<return-type>::call_method(self, "name", args...) to call - the Python override. - -
  5. For each non-pure virtual function meant to be - overridable from Python, a static member function (or a free function) taking - a reference or pointer to the T as the first parameter and which - forwards any additional parameters neccessary to the default - implementation of the virtual function. See also this - note if the base class virtual function is private. - -
- -
-struct hello_callback : hello
-{
-    // hello constructor storing initial self_ parameter
-    hello_callback(PyObject* self_, const std::string& x) // 2
-        : hello(x), self(self_) {}
-
-    // In case hello is returned by-value from a wrapped function
-    hello_callback(PyObject* self_, const hello& x) // 3
-        : hello(x), self(self_) {}
-
-    // Override greet to call back into Python
-    std::string greet() const // 4
-        { return boost::python::callback<std::string>::call_method(self, "greet"); }
-
-    // Supplies the default implementation of greet
-    static std::string default_greet(const hello& self_) const // 5
-        { return self_.hello::greet(); }
- private:
-    PyObject* self; // 1
-};
-
- -

- Finally, we add hello_callback to the - class_builder<> declaration in our module initialization - function, and when we define the function, we must tell Boost.Python about the default - implementation: - -

-// Create the Python type object for our extension class
-boost::python::class_builder<hello,hello_callback> hello_class(hello, "hello");
-// Add a virtual member function
-hello_class.def(&hello::greet, "greet", &hello_callback::default_greet);
-
- -

- Now our Python subclass of hello behaves as expected: - -

->>> class wordy(hello):
-...     def greet(self):
-...         return hello.greet(self) + ', where the weather is fine'
-...
->>> hi2 = wordy('Florida')
->>> hi2.greet()
-'Hello from Florida, where the weather is fine'
->>> invite(hi2)
-'Hello from Florida, where the weather is fine! Please come soon!'
-
-

- *You may ask, "Why do we need this derived - class? This could have been designed so that everything gets done right - inside of hello." One of the goals of Boost.Python is to be - minimally intrusive on an existing C++ design. In principle, it should be - possible to expose the interface for a 3rd party library without changing - it. To unintrusively hook into the virtual functions so that a Python - override may be called, we must use a derived class. - -

Pure Virtual Functions

- -

- A pure virtual function with no implementation is actually a lot easier to - deal with than a virtual function with a default implementation. First of - all, you obviously don't need to supply - a default implementation. Secondly, you don't need to call - def() on the extension_class<> instance - for the virtual function. In fact, you wouldn't want to: if the - corresponding attribute on the Python class stays undefined, you'll get an - AttributeError in Python when you try to call the function, - indicating that it should have been implemented. For example: -

-
-struct baz {
-    virtual int pure(int) = 0;
-    int calls_pure(int x) { return pure(x) + 1000; }
-};
-
-struct baz_callback {
-    int pure(int x) { boost::python::callback<int>::call_method(m_self, "pure", x); }
-};
-
-BOOST_PYTHON_MODULE_INIT(foobar)
-{
-    try
-    {
-       boost::python::module_builder foobar("foobar");
-       boost::python::class_builder<baz,baz_callback> baz_class("baz");
-       baz_class.def(&baz::calls_pure, "calls_pure");
-    }
-    catch(...)
-    {
-       boost::python::handle_exception();    // Deal with the exception for Python
-    }
-}
-
-
-

- Now in Python: -

-
->>> from foobar import baz
->>> x = baz()
->>> x.pure(1)
-Traceback (innermost last):
-  File "<stdin>", line 1, in ?
-AttributeError: pure
->>> x.calls_pure(1)
-Traceback (innermost last):
-  File "<stdin>", line 1, in ?
-AttributeError: pure
->>> class mumble(baz):
-...    def pure(self, x): return x + 1
-...
->>> y = mumble()
->>> y.pure(99)
-100
->>> y.calls_pure(99)
-1100
-
- -

Private Non-Pure Virtual Functions

- -

This is one area where some minor intrusiveness on the wrapped library is -required. Once it has been overridden, the only way to call the base class -implementation of a private virtual function is to make the derived class a -friend of the base class. You didn't hear it from me, but most C++ -implementations will allow you to change the declaration of the base class in -this limited way without breaking binary compatibility (though it will certainly -break the ODR). - -


-

- Next: Function Overloading - Previous: Exporting Classes - Up: Top -

- © Copyright David Abrahams 2001. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability for - any purpose. -

- Updated: Mar 21, 2001 - diff --git a/doc/pickle.html b/doc/pickle.html deleted file mode 100644 index 994a78ab..00000000 --- a/doc/pickle.html +++ /dev/null @@ -1,272 +0,0 @@ - - -Boost.Python Pickle Support - -

- -c++boost.gif (8819 bytes) - -
-

Boost.Python Pickle Support

- -Pickle is a Python module for object serialization, also known -as persistence, marshalling, or flattening. - -

-It is often necessary to save and restore the contents of an object to -a file. One approach to this problem is to write a pair of functions -that read and write data from a file in a special format. A powerful -alternative approach is to use Python's pickle module. Exploiting -Python's ability for introspection, the pickle module recursively -converts nearly arbitrary Python objects into a stream of bytes that -can be written to a file. - -

-The Boost Python Library supports the pickle module by emulating the -interface implemented by Jim Fulton's ExtensionClass module that is -included in the -ZOPE -distribution. -This interface is similar to that for regular Python classes as -described in detail in the -Python Library Reference for pickle. - -


-

The Boost.Python Pickle Interface

- -At the user level, the Boost.Python pickle interface involves three special -methods: - -
-
-__getinitargs__ -
- When an instance of a Boost.Python extension class is pickled, the - pickler tests if the instance has a __getinitargs__ method. - This method must return a Python tuple (it is most convenient to use - a boost::python::tuple). When the instance is restored by the - unpickler, the contents of this tuple are used as the arguments for - the class constructor. - -

- If __getinitargs__ is not defined, the class constructor - will be called without arguments. - -

-

-__getstate__ - -
- When an instance of a Boost.Python extension class is pickled, the - pickler tests if the instance has a __getstate__ method. - This method should return a Python object representing the state of - the instance. - -

- If __getstate__ is not defined, the instance's - __dict__ is pickled (if it is not empty). - -

-

-__setstate__ - -
- When an instance of a Boost.Python extension class is restored by the - unpickler, it is first constructed using the result of - __getinitargs__ as arguments (see above). Subsequently the - unpickler tests if the new instance has a __setstate__ - method. If so, this method is called with the result of - __getstate__ (a Python object) as the argument. - -

- If __setstate__ is not defined, the result of - __getstate__ must be a Python dictionary. The items of this - dictionary are added to the instance's __dict__. - -

- -If both __getstate__ and __setstate__ are defined, -the Python object returned by __getstate__ need not be a -dictionary. The __getstate__ and __setstate__ methods -can do what they want. - -
-

Pitfalls and Safety Guards

- -In Boost.Python extension modules with many extension classes, -providing complete pickle support for all classes would be a -significant overhead. In general complete pickle support should only be -implemented for extension classes that will eventually be pickled. -However, the author of a Boost.Python extension module might not -anticipate correctly which classes need support for pickle. -Unfortunately, the pickle protocol described above has two important -pitfalls that the end user of a Boost.Python extension module might not -be aware of: - -
-
-Pitfall 1: -Both __getinitargs__ and __getstate__ are not defined. - -
- In this situation the unpickler calls the class constructor without - arguments and then adds the __dict__ that was pickled by - default to that of the new instance. - -

- However, most C++ classes wrapped with Boost.Python will have member - data that are not restored correctly by this procedure. To alert the - user to this problem, a safety guard is provided. If both - __getinitargs__ and __getstate__ are not defined, - Boost.Python tests if the class has an attribute - __dict_defines_state__. An exception is raised if this - attribute is not defined: - -

-    RuntimeError: Incomplete pickle support (__dict_defines_state__ not set)
-
- - In the rare cases where this is not the desired behavior, the safety - guard can deliberately be disabled. The corresponding C++ code for - this is, e.g.: - -
-    class_builder<your_class> py_your_class(your_module, "your_class");
-    py_your_class.dict_defines_state();
-
- - It is also possible to override the safety guard at the Python level. - E.g.: - -
-    import your_bpl_module
-    class your_class(your_bpl_module.your_class):
-      __dict_defines_state__ = 1
-
- -

-

-Pitfall 2: -__getstate__ is defined and the instance's __dict__ is not empty. - -
- The author of a Boost.Python extension class might provide a - __getstate__ method without considering the possibilities - that: - -

-

    -
  • - his class is used in Python as a base class. Most likely the - __dict__ of instances of the derived class needs to be - pickled in order to restore the instances correctly. - -

    -

  • - the user adds items to the instance's __dict__ directly. - Again, the __dict__ of the instance then needs to be - pickled. - -
-

- - To alert the user to this highly unobvious problem, a safety guard is - provided. If __getstate__ is defined and the instance's - __dict__ is not empty, Boost.Python tests if the class has - an attribute __getstate_manages_dict__. An exception is - raised if this attribute is not defined: - -

-    RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
-
- - To resolve this problem, it should first be established that the - __getstate__ and __setstate__ methods manage the - instances's __dict__ correctly. Note that this can be done - both at the C++ and the Python level. Finally, the safety guard - should intentionally be overridden. E.g. in C++: - -
-    class_builder<your_class> py_your_class(your_module, "your_class");
-    py_your_class.getstate_manages_dict();
-
- - In Python: - -
-    import your_bpl_module
-    class your_class(your_bpl_module.your_class):
-      __getstate_manages_dict__ = 1
-      def __getstate__(self):
-        # your code here
-      def __setstate__(self, state):
-        # your code here
-
-
- -
-

Practical Advice

- -
    -
  • - Avoid using __getstate__ if the instance can also be - reconstructed by way of __getinitargs__. This automatically - avoids Pitfall 2. - -

    -

  • - If __getstate__ is required, include the instance's - __dict__ in the Python object that is returned. - -
- -
-

Examples

- -There are three files in boost/libs/python/example that -show how so provide pickle support. - -

pickle1.cpp

- - The C++ class in this example can be fully restored by passing the - appropriate argument to the constructor. Therefore it is sufficient - to define the pickle interface method __getinitargs__. - -

pickle2.cpp

- - The C++ class in this example contains member data that cannot be - restored by any of the constructors. Therefore it is necessary to - provide the __getstate__/__setstate__ pair of - pickle interface methods. - -

- For simplicity, the __dict__ is not included in the result - of __getstate__. This is not generally recommended, but a - valid approach if it is anticipated that the object's - __dict__ will always be empty. Note that the safety guards - will catch the cases where this assumption is violated. - -

pickle3.cpp

- - This example is similar to pickle2.cpp. However, the - object's __dict__ is included in the result of - __getstate__. This requires more code but is unavoidable - if the object's __dict__ is not always empty. - -
-© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, -use, modify, sell and distribute this document is granted provided this -copyright notice appears in all copies. This document is provided "as -is" without express or implied warranty, and with no claim as to its -suitability for any purpose. - -

-Updated: March 21, 2001 -

diff --git a/doc/pointers.html b/doc/pointers.html deleted file mode 100644 index 11cfd8d9..00000000 --- a/doc/pointers.html +++ /dev/null @@ -1,148 +0,0 @@ - - - Pointers - -
-

- c++boost.gif (8819 bytes)Pointers -

- -

The Problem With Pointers

- -

-In general, raw pointers passed to or returned from functions are problematic -for Boost.Python because pointers have too many potential meanings. Is it an iterator? -A pointer to a single element? An array? When used as a return value, is the -caller expected to manage (delete) the pointed-to object or is the pointer -really just a reference? If the latter, what happens to Python references to the -referent when some C++ code deletes it? -

-There are a few cases in which pointers are converted automatically: -

    - -
  • Both const- and non-const pointers to wrapped class instances can be passed -to C++ functions. - -
  • Values of type const char* are interpreted as -null-terminated 'C' strings and when passed to or returned from C++ functions are -converted from/to Python strings. - -
- -

Can you avoid the problem?

- -

My first piece of advice to anyone with a case not covered above is -``find a way to avoid the problem.'' For example, if you have just one -or two functions that return a pointer to an individual const -T, and T is a wrapped class, you may be able to write a ``thin -converting wrapper'' over those two functions as follows: - -

-const Foo* f(); // original function
-const Foo& f_wrapper() { return *f(); }
-  ...
-my_module.def(f_wrapper, "f");
-
-

-Foo must have a public copy constructor for this technique to work, since Boost.Python -converts const T& values to_python by copying the T -value into a new extension instance. - -

Dealing with the problem

- -

The first step in handling the remaining cases is to figure out what the pointer -means. Several potential solutions are provided in the examples that follow: - -

Returning a pointer to a wrapped type

- -

Returning a const pointer

- -

If you have lots of functions returning a const T* for some -wrapped T, you may want to provide an automatic -to_python conversion function so you don't have to write lots of -thin wrappers. You can do this simply as follows: - -

-BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
-  PyObject* to_python(const Foo* p) {
-     return to_python(*p); // convert const Foo* in terms of const Foo&
-  }
-BOOST_PYTHON_END_CONVERSION_NAMESPACE
-
- -

If you can't (afford to) copy the referent, or the pointer is non-const

- -

If the wrapped type doesn't have a public copy constructor, if copying is -extremely costly (remember, we're dealing with Python here), or if the -pointer is non-const and you really need to be able to modify the referent from -Python, you can use the following dangerous trick. Why dangerous? Because python -can not control the lifetime of the referent, so it may be destroyed by your C++ -code before the last Python reference to it disappears: - -

-BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
-  PyObject* to_python(Foo* p)
-  {
-      return boost::python::python_extension_class_converters<Foo>::smart_ptr_to_python(p);
-  }
-
-  PyObject* to_python(const Foo* p)
-  {
-      return to_python(const_cast<Foo*>(p));
-  }
-BOOST_PYTHON_END_CONVERSION_NAMESPACE
-
- -This will cause the Foo* to be treated as though it were an owning smart -pointer, even though it's not. Be sure you don't use the reference for anything -from Python once the pointer becomes invalid, though. Don't worry too much about -the const_cast<> above: Const-correctness is completely lost -to Python anyway! - -

[In/]Out Parameters and Immutable Types

- -

If you have an interface that uses non-const pointers (or references) as -in/out parameters to types which in Python are immutable (e.g. int, string), -there simply is no way to get the same interface in Python. You must -resort to transforming your interface with simple thin wrappers as shown below: -

-const void f(int* in_out_x); // original function
-const int f_wrapper(int in_x) { f(in_x); return in_x; }
-  ...
-my_module.def(f_wrapper, "f");
-
- -

Of course, [in/]out parameters commonly occur only when there is already a -return value. You can handle this case by returning a Python tuple: -

-typedef unsigned ErrorCode;
-const char* f(int* in_out_x); // original function
- ...
-#include <boost/python/objects.hpp>
-const boost::python::tuple f_wrapper(int in_x) { 
-  const char* s = f(in_x); 
-  return boost::python::tuple(s, in_x);
-}
-  ...
-my_module.def(f_wrapper, "f");
-
-

Now, in Python: -

->>> str,out_x = f(3)
-
- -

- Previous: Enums - Up: Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

- Updated: Nov 26, 2000 -

- diff --git a/doc/richcmp.html b/doc/richcmp.html deleted file mode 100644 index d9ab7044..00000000 --- a/doc/richcmp.html +++ /dev/null @@ -1,106 +0,0 @@ - - -Rich Comparisons - -
- -c++boost.gif (8819 bytes) - -
-

Rich Comparisons

- -
-In Python versions up to and including Python 2.0, support for -implementing comparisons on user-defined classes and extension types -was quite simple. Classes could implement a __cmp__ method -that was given two instances of a class as arguments, and could only -return 0 if they were equal or +1 or -1 if -they were not. The method could not raise an exception or return -anything other than an integer value. -In Python 2.1, Rich Comparisons were added (see -PEP 207). -Python classes can now individually overload each of the <, <=, ->, >=, ==, and != operations. - -

-For more detailed information, search for "rich comparison" -here. - -

-Boost.Python supports both automatic overloading and manual overloading -of the Rich Comparison operators. The compile-time support is -independent of the Python version that is used when compiling -Boost.Python extension modules. That is, op_lt for example can -always be used, and the C++ operator< will always be bound -to the Python method __lt__. However, the run-time -behavior will depend on the Python version. - -

-With Python versions before 2.1, the Rich Comparison operators will not -be called by Python when any of the six comparison operators -(<, <=, ==, !=, ->, >=) is used in an expression. The only way -to access the corresponding methods is to call them explicitly, e.g. -a.__lt__(b). Only with Python versions 2.1 or higher will -expressions like a < b work as expected. - -

-To support Rich Comparisions, the Python C API was modified between -Python versions 2.0 and 2.1. A new slot was introduced in the -PyTypeObject structure: tp_richcompare. For backwards -compatibility, a flag (Py_TPFLAGS_HAVE_RICHCOMPARE) has to be -set to signal to the Python interpreter that Rich Comparisions are -supported by a particular type. -There is only one flag for all the six comparison operators. -When any of the six operators is wrapped automatically or -manually, Boost.Python will set this flag. Attempts to use comparison -operators at the Python level that are not defined at the C++ level -will then lead to an AttributeError when the Python 2.1 -(or higher) interpreter tries, e.g., a.__lt__(b). That -is, in general all six operators should be supplied. Automatically -wrapped operators and manually wrapped operators can be mixed. For -example:

-    boost::python::class_builder<code> py_code(this_module, "code");
-
-    py_code.def(boost::python::constructor<>());
-    py_code.def(boost::python::constructor<int>());
-    py_code.def(boost::python::operators<(  boost::python::op_eq
-                                          | boost::python::op_ne)>());
-    py_code.def(NotImplemented, "__lt__");
-    py_code.def(NotImplemented, "__le__");
-    py_code.def(NotImplemented, "__gt__");
-    py_code.def(NotImplemented, "__ge__");
-
- -NotImplemented is a simple free function that (currently) has -to be provided by the user. For example:
-  boost::python::ref
-  NotImplemented(const code&, const code&) {
-    return
-    boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count);
-  }
-
- -See also: - - -
-© Copyright Nicholas K. Sauter & Ralf W. Grosse-Kunstleve 2001. -Permission to copy, use, modify, sell and distribute this document is -granted provided this copyright notice appears in all copies. This -document is provided "as is" without express or implied warranty, and -with no claim as to its suitability for any purpose. - -

-Updated: July 2001 - -

diff --git a/doc/special.html b/doc/special.html deleted file mode 100644 index a72ec671..00000000 --- a/doc/special.html +++ /dev/null @@ -1,973 +0,0 @@ - - - Special Method and Operator Support - -
-

- c++boost.gif (8819 bytes)Special Method and - Operator Support -

-

- Overview -

-

- Boost.Python supports all of the standard - special method names supported by real Python class instances - except __complex__ (more on the reasons below). In addition, it can quickly and easily expose - suitable C++ functions and operators as Python operators. The following - categories of special method names are supported: -

- -

Basic Customization

- - -

- Python provides a number of special operators for basic customization of a - class. Only a brief description is provided below; more complete - documentation can be found here. - -

-
- __init__(self) -
- Initialize the class instance. For extension classes not subclassed in - Python, __init__ is defined by - -
    my_class.def(boost::python::constructor<...>())
- - (see section "A Simple Example Using Boost.Python").

-

- __del__(self) -
- Called when the extension instance is about to be destroyed. For extension classes - not subclassed in Python, __del__ is always defined automatically by - means of the class' destructor. -
- __repr__(self) -
- Create a string representation from which the object can be - reconstructed. -
- __str__(self) -
- Create a string representation which is suitable for printing. -
- __lt__(self, other) -
- __le__(self, other) -
- __eq__(self, other) -
- __ne__(self, other) -
- __gt__(self, other) -
- __ge__(self, other) -
- Rich Comparison methods. - New in Python 2.1. - See Rich Comparisons. -
- __cmp__(self, other) -
- Three-way compare function. - See Rich Comparisons. -
- __hash__(self) -
- Called for the key object for dictionary operations, and by the - built-in function hash(). Should return a 32-bit integer usable as a - hash value for dictionary operations (only allowed if __cmp__ is also - defined) -
- __nonzero__(self) -
- called if the object is used as a truth value (e.g. in an if - statement) -
- __call__ (self[, args...]) -
-Called when the instance is ``called'' as a function; if this method -is defined, x(arg1, arg2, ...) is a shorthand for -x.__call__(arg1, arg2, ...). -
- - If we have a suitable C++ function that supports any of these features, - we can export it like any other function, using its Python special name. - For example, suppose that class Foo provides a string - conversion function: -
-std::string to_string(Foo const& f)
-{
-    std::ostringstream s;
-    s << f;
-    return s.str();
-}
-
- This function would be wrapped like this: -
-boost::python::class_builder<Foo> foo_class(my_module, "Foo");
-foo_class.def(&to_string, "__str__");
-
- Note that Boost.Python also supports automatic wrapping of - __str__ and __cmp__. This is explained in the next section and the Table of - Automatically Wrapped Methods. - -

Numeric Operators

- -

- Numeric operators can be exposed manually, by defing C++ - [member] functions that support the standard Python numeric - protocols. This is the same basic technique used to expose - to_string() as __str__() above, and is covered in detail below. Boost.Python also supports - automatic wrapping of numeric operators whenever they have already - been defined in C++. - -

Exposing C++ Operators Automatically

- -

-Supose we wanted to expose a C++ class - BigNum which supports addition. That is, in C++ we can write: -

-BigNum a, b, c;
-...
-c = a + b;
-
-

- To enable the same functionality in Python, we first wrap the - BigNum class as usual: -

-boost::python::class_builder<BigNum> bignum_class(my_module, "BigNum");
-bignum_class.def(boost::python::constructor<>());
-...
-
- Then we export the addition operator like this: - -
-bignum_class.def(boost::python::operators<boost::python::op_add>());
-
- - Since BigNum also supports subtraction, multiplication, and division, we - want to export those also. This can be done in a single command by - ``or''ing the operator identifiers together (a complete list of these - identifiers and the corresponding operators can be found in the Table of Automatically Wrapped Methods): -
-bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>());
-
- [Note that the or-expression must be enclosed in parentheses.] - -

This form of operator definition can be used to wrap unary and - homogeneous binary operators (a homogeneous operator has left and - right operands of the same type). Now suppose that our C++ library also - supports addition of BigNums and plain integers: - -

-BigNum a, b;
-int i;
-...
-a = b + i;
-a = i + b;
-
- To wrap these heterogeneous operators, we need to specify a different type for - one of the operands. This is done using the right_operand - and left_operand templates: -
-bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::right_operand<int>());
-bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::left_operand<int>());
-
- Boost.Python uses overloading to register several variants of the same - operation (more on this in the context of - coercion). Again, several operators can be exported at once: -
-bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>(),
-                 boost::python::right_operand<int>());
-bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>(), 
-                 boost::python::left_operand<int>());
-
- The type of the operand not mentioned is taken from the class being wrapped. In - our example, the class object is bignum_class, and thus the - other operand's type is ``BigNum const&''. You can override - this default by explicitly specifying a type in the - operators template: -
-bignum_class.def(boost::python::operators<boost::python::op_add, BigNum>(), boost::python::right_operand<int>());
-
-

- Note that automatic wrapping uses the expression - ``left + right'' and can be used uniformly - regardless of whether the C++ operators are supplied as free functions - -

-BigNum operator+(BigNum, BigNum)
-
- - or as member functions - -
-BigNum::operator+(BigNum).
-
- -

- For the Python built-in functions pow() and - abs(), there is no corresponding C++ operator. Instead, - automatic wrapping attempts to wrap C++ functions of the same name. This - only works if those functions are known in namespace - python. On some compilers (e.g. MSVC) it might be - necessary to add a using declaration prior to wrapping: - -

-namespace boost { namespace python { 
-  using my_namespace::pow;
-  using my_namespace::abs;
-}
-
- -

Wrapping Numeric Operators Manually

-

- In some cases, automatic wrapping of operators may be impossible or - undesirable. Suppose, for example, that the modulo operation for BigNums - is defined by a set of functions called mod(): - -

-BigNum mod(BigNum const& left, BigNum const& right);
-BigNum mod(BigNum const& left, int right);
-BigNum mod(int left, BigNum const& right);
-
- -

- For automatic wrapping of the modulo function, operator%() would be needed. - Therefore, the mod()-functions must be wrapped manually. That is, we have - to export them explicitly with the Python special name "__mod__": - -

-bignum_class.def((BigNum (*)(BigNum const&, BigNum const&))&mod, "__mod__");
-bignum_class.def((BigNum (*)(BigNum const&, int))&mod, "__mod__");
-
- -

- The third form of mod() (with int as left operand) cannot - be wrapped directly. We must first create a function rmod() with the - operands reversed: - -

-BigNum rmod(BigNum const& right, int left)
-{
-    return mod(left, right);
-}
-
- - This function must be wrapped under the name "__rmod__" (standing for "reverse mod"): - -
-bignum_class.def(&rmod,  "__rmod__");
-
- - Many of the possible operator names can be found in the Table of Automatically Wrapped Methods. Special treatment is - necessary to export the ternary pow operator. - -

- Automatic and manual wrapping can be mixed arbitrarily. Note that you - cannot overload the same operator for a given extension class on both - ``int'' and ``float'', because Python implicitly - converts these types into each other. Thus, the overloaded variant - found first (be it ``int`` or ``float'') will be - used for either of the two types. - -

Inplace Operators

-

- Boost.Python can also be used to expose inplace numeric operations - (i.e., += and so forth). These operators must be wrapped - manually, as described in the previous section. For example, suppose - the class BigNum has an operator+=: - -

-BigNum& operator+= (BigNum const& right);
-
- - This can be exposed by first writing a wrapper function: - -
-BigNum& iadd (BigNum& self, const BigNum& right)
-{
-  return self += right;
-}
-
- - and then exposing the wrapper with - -
-bignum_class.def(&iadd, "__iadd__");
-
- - - - -

Coercion

- - - Plain Python can only execute operators with identical types on the left - and right hand side. If it encounters an expression where the types of - the left and right operand differ, it tries to coerce these types to a - common type before invoking the actual operator. Implementing good - coercion functions can be difficult if many type combinations must be - supported. -

- Boost.Python solves this problem the same way that C++ does: with overloading. This technique drastically - simplifies the code neccessary to support operators: you just register - operators for all desired type combinations, and Boost.Python automatically - ensures that the correct function is called in each case; there is no - need for user-defined coercion functions. To enable operator - overloading, Boost.Python provides a standard coercion which is implicitly - registered whenever automatic operator wrapping is used. -

- If you wrap all operator functions manually, but still want to use - operator overloading, you have to register the standard coercion - function explicitly: - -

-// this is not necessary if automatic operator wrapping is used
-bignum_class.def_standard_coerce();
-
- - If you encounter a situation where you absolutely need a customized - coercion, you can still define the "__coerce__" operator manually. The signature - of a coercion function should look like one of the following (the first is - the safest): - -
-boost::python::tuple custom_coerce(boost::python::reference left, boost::python::reference right);
-boost::python::tuple custom_coerce(PyObject* left, PyObject* right);
-PyObject* custom_coerce(PyObject* left, PyObject* right);
-
- - The resulting tuple must contain two elements which - represent the values of left and right - converted to the same type. Such a function is wrapped as usual: - -
-// this must be called before any use of automatic operator  
-// wrapping or a call to some_class.def_standard_coerce()
-some_class.def(&custom_coerce, "__coerce__");
-
- - Note that the standard coercion (defined by use of automatic - operator wrapping on a class_builder or a call to - class_builder::def_standard_coerce()) will never be applied if - a custom coercion function has been registered. Therefore, in - your coercion function you should call - -
-boost::python::standard_coerce(left, right);
-
- - for all cases that you don't want to handle yourself. - -

The Ternary pow() Operator

- -

- In addition to the usual binary pow(x, y) operator (meaning - xy), Python also provides a ternary variant that implements - xy mod z, presumably using a more efficient algorithm than - concatenation of power and modulo operators. Automatic operator wrapping - can only be used with the binary variant. Ternary pow() must - always be wrapped manually. For a homgeneous ternary pow(), - this is done as usual: - -

-BigNum power(BigNum const& first, BigNum const& second, BigNum const& modulus);
-typedef BigNum (ternary_function1)(const BigNum&, const BigNum&, const BigNum&);
-...
-bignum_class.def((ternary_function1)&power,  "__pow__");
-
- - If you want to support this function with non-uniform argument - types, wrapping is a little more involved. Suppose you have to wrap: - -
-BigNum power(BigNum const& first, int second, int modulus);
-BigNum power(int first, BigNum const& second, int modulus);
-BigNum power(int first, int second, BigNum const& modulus);
-
- - The first variant can be wrapped as usual: - -
-typedef BigNum (ternary_function2)(const BigNum&, int, int);
-bignum_class.def((ternary_function2)&power,  "__pow__");
-
- - In the second variant, however, BigNum appears only as second - argument, and in the last one it's the third argument. These functions - must be presented to Boost.Python such that that the BigNum - argument appears in first position: - -
-BigNum rpower(BigNum const& second, int first, int modulus)
-{
-    return power(first, second, modulus);
-}
-
-BigNum rrpower(BigNum const& modulus, int first, int second)
-{
-    return power(first, second, modulus);
-}
-
- -

These functions must be wrapped under the names "__rpow__" and "__rrpow__" - respectively: - -

-bignum_class.def((ternary_function2)&rpower,  "__rpow__");
-bignum_class.def((ternary_function2)&rrpower,  "__rrpow__");
-
- -Note that "__rrpow__" is an extension not present in plain Python. - -

Table of Automatically Wrapped Methods

-

- Boost.Python can automatically wrap the following - special methods: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
- Python Operator Name - - Python Expression - - C++ Operator Id - - C++ Expression Used For Automatic Wrapping
- with cpp_left = from_python(left, - type<Left>()),
- cpp_right = from_python(right, - type<Right>()),
- and cpp_oper = from_python(oper, type<Oper>()) -
- __add__, __radd__ - - left + right - - op_add - - cpp_left + cpp_right -
- __sub__, __rsub__ - - left - right - - op_sub - - cpp_left - cpp_right -
- __mul__, __rmul__ - - left * right - - op_mul - - cpp_left * cpp_right -
- __div__, __rdiv__ - - left / right - - op_div - - cpp_left / cpp_right -
- __mod__, __rmod__ - - left % right - - op_mod - - cpp_left % cpp_right -
- __divmod__, __rdivmod__ - - (quotient, remainder)
- = divmod(left, right)
-
- op_divmod - - cpp_left / cpp_right -
cpp_left % cpp_right -
- __pow__, __rpow__ - - pow(left, right)
- (binary power) -
- op_pow - - pow(cpp_left, cpp_right) -
- __rrpow__ - - pow(left, right, modulo)
- (ternary power modulo) -
- no automatic wrapping, special treatment - required -
- __lshift__, __rlshift__ - - left << right - - op_lshift - - cpp_left << cpp_right -
- __rshift__, __rrshift__ - - left >> right - - op_rshift - - cpp_left >> cpp_right -
- __and__, __rand__ - - left & right - - op_and - - cpp_left & cpp_right -
- __xor__, __rxor__ - - left ^ right - - op_xor - - cpp_left ^ cpp_right -
- __or__, __ror__ - - left | right - - op_or - - cpp_left | cpp_right - -
- __cmp__, __rcmp__ - - cmp(left, right)
-
See Rich Comparisons. -
- op_cmp - - cpp_left < cpp_right  -
cpp_right < cpp_left -
- __lt__ -
__le__ -
__eq__ -
__ne__ -
__gt__ -
__ge__ -
- left < right -
left <= right -
left == right -
left != right -
left > right -
left >= right -
See Rich Comparisons -
- op_lt -
op_le -
op_eq -
op_ne -
op_gt -
op_ge -
- cpp_left < cpp_right  -
cpp_left <= cpp_right  -
cpp_left == cpp_right  -
cpp_left != cpp_right  -
cpp_left > cpp_right  -
cpp_left >= cpp_right  - -
- __neg__ - - -oper  (unary negation) - - op_neg - - -cpp_oper -
- __pos__ - - +oper  (identity) - - op_pos - - +cpp_oper -
- __abs__ - - abs(oper)  (absolute value) - - op_abs - - abs(cpp_oper) -
- __invert__ - - ~oper  (bitwise inversion) - - op_invert - - ~cpp_oper -
- __int__ - - int(oper)  (integer conversion) - - op_int - - long(cpp_oper) -
- __long__ - - long(oper) 
- (infinite precision integer conversion) -
- op_long - - PyLong_FromLong(cpp_oper) -
- __float__ - - float(oper)  (float conversion) - - op_float - - double(cpp_oper) -
- __str__ - - str(oper)  (string conversion) - - op_str - - std::ostringstream s; s << oper; -
- __coerce__ - - coerce(left, right) - - usually defined automatically, otherwise - special treatment required -
- -

Sequence and Mapping Operators

- -

- Sequence and mapping operators let wrapped objects behave in accordance - to Python's iteration and access protocols. These protocols differ - considerably from the ones found in C++. For example, Python's typical - iteration idiom looks like - -

-for i in S:
-
- - while in C++ one writes - -
-for (iterator i = S.begin(), end = S.end(); i != end; ++i)
-
- -

One could try to wrap C++ iterators in order to carry the C++ idiom into - Python. However, this does not work very well because - -

    -
  1. It leads to - non-uniform Python code (wrapped sequences support a usage different from - Python built-in sequences) and - -
  2. Iterators (e.g. std::vector::iterator) are often implemented as plain C++ - pointers which are problematic for any automatic - wrapping system. -
- -

- It is a better idea to support the standard Python - sequence and mapping protocols for your wrapped containers. These - operators have to be wrapped manually because there are no corresponding - C++ operators that could be used for automatic wrapping. The Python - documentation lists the relevant - container operators. In particular, expose __getitem__, __setitem__ - and remember to raise the appropriate Python exceptions - (PyExc_IndexError for sequences, - PyExc_KeyError for mappings) when the requested item is not - present. - -

- In the following example, we expose std::map<std::size_t,std::string>: -

-
-typedef std::map<std::size_t, std::string> StringMap;
-
-// A helper function for dealing with errors. Throw a Python exception
-// if p == m.end().
-void throw_key_error_if_end(
-        const StringMap& m, 
-        StringMap::const_iterator p, 
-        std::size_t key)
-{
-    if (p == m.end())
-    {
-        PyErr_SetObject(PyExc_KeyError, boost::python::converters::to_python(key));
-        throw boost::python::error_already_set();
-    }
-}
-
-// Define some simple wrapper functions which match the Python  protocol
-// for __getitem__, __setitem__, and __delitem__.  Just as in Python, a
-// free function with a ``self'' first parameter makes a fine class method.
-
-const std::string& get_item(const StringMap& self, std::size_t key)
-{
-    const StringMap::const_iterator p = self.find(key);
-    throw_key_error_if_end(self, p, key);
-    return p->second;
-}
-
-// Sets the item corresponding to key in the map.
-void StringMapPythonClass::set_item(StringMap& self, std::size_t key, const std::string& value)
-{
-    self[key] = value;
-}
-
-// Deletes the item corresponding to key from the map.
-void StringMapPythonClass::del_item(StringMap& self, std::size_t key)
-{
-    const StringMap::iterator p = self.find(key);
-    throw_key_error_if_end(self, p, key);
-    self.erase(p);
-}
-
-class_builder<StringMap> string_map(my_module, "StringMap");
-string_map.def(boost::python::constructor<>());
-string_map.def(&StringMap::size, "__len__");
-string_map.def(get_item, "__getitem__");
-string_map.def(set_item, "__setitem__");
-string_map.def(del_item, "__delitem__");
-
-
-

- Then in Python: -

-
->>> m = StringMap()
->>> m[1]
-Traceback (innermost last):
-  File "<stdin>", line 1, in ?
-KeyError: 1
->>> m[1] = 'hello'
->>> m[1]
-'hello'
->>> del m[1]
->>> m[1]            # prove that it's gone
-Traceback (innermost last):
-  File "<stdin>", line 1, in ?
-KeyError: 1
->>> del m[2]
-Traceback (innermost last):
-  File "<stdin>", line 1, in ?
-KeyError: 2
->>> len(m)
-0
->>> m[0] = 'zero'
->>> m[1] = 'one'
->>> m[2] = 'two'
->>> m[3] = 'three'
->>> len(m)
-4
-
-
- -

Customized Attribute Access

- -

- Just like built-in Python classes, Boost.Python extension classes support special - the usual attribute access methods __getattr__, - __setattr__, and __delattr__. - Because writing these functions can - be tedious in the common case where the attributes being accessed are - known statically, Boost.Python checks the special names - -

    -
  • - __getattr__<name>__ -
  • - __setattr__<name>__ -
  • - __delattr__<name>__ -
- - to provide functional access to the attribute <name>. This - facility can be used from C++ or entirely from Python. For example, the - following shows how we can implement a ``computed attribute'' in Python: -
-
->>> class Range(AnyBoost.PythonExtensionClass):
-...    def __init__(self, start, end):
-...        self.start = start
-...        self.end = end
-...    def __getattr__length__(self):
-...        return self.end - self.start
-...
->>> x = Range(3, 9)
->>> x.length
-6
-
-
-

- Direct Access to Data Members -

-

- Boost.Python uses the special - __xxxattr__<name>__ functionality described above - to allow direct access to data members through the following special - functions on class_builder<> and - extension_class<>: -

    -
  • - def_getter(pointer-to-member, name) // - read access to the member via attribute name -
  • - def_setter(pointer-to-member, name) // - write access to the member via attribute name -
  • - def_readonly(pointer-to-member, name) - // read-only access to the member via attribute name -
  • - def_read_write(pointer-to-member, - name) // read/write access to the member via attribute - name -
-

- Note that the first two functions, used alone, may produce surprising - behavior. For example, when def_getter() is used, the - default functionality for setattr() and - delattr() remains in effect, operating on items in the extension - instance's name-space (i.e., its __dict__). For that - reason, you'll usually want to stick with def_readonly and - def_read_write. -

- For example, to expose a std::pair<int,long> we - might write: -

-
-typedef std::pair<int,long> Pil;
-int first(const Pil& x) { return x.first; }
-long second(const Pil& x) { return x.second; }
-   ...
-my_module.def(first, "first");
-my_module.def(second, "second");
-
-class_builder<Pil> pair_int_long(my_module, "Pair");
-pair_int_long.def(boost::python::constructor<>());
-pair_int_long.def(boost::python::constructor<int,long>());
-pair_int_long.def_read_write(&Pil::first, "first");
-pair_int_long.def_read_write(&Pil::second, "second");
-
-
-

- Now your Python class has attributes first and - second which, when accessed, actually modify or reflect the - values of corresponding data members of the underlying C++ object. Now - in Python: -

-
->>> x = Pair(3,5)
->>> x.first
-3
->>> x.second
-5
->>> x.second = 8
->>> x.second
-8
->>> second(x) # Prove that we're not just changing the instance __dict__
-8
-
-
-

- And what about __complex__? -

-

- That, dear reader, is one problem we don't know how to solve. The - Python source contains the following fragment, indicating the - special-case code really is hardwired: -

-
-/* XXX Hack to support classes with __complex__ method */
-if (PyInstance_Check(r)) { ...
-
-
-

-Next: A Peek Under the Hood -Previous: Inheritance -Up: Top -

- © Copyright David Abrahams and Ullrich Köthe 2000. - Permission to copy, use, modify, sell and distribute this document is - granted provided this copyright notice appears in all copies. This - document is provided ``as is'' without express or implied - warranty, and with no claim as to its suitability for any purpose. -

- Updated: Nov 26, 2000 -

- diff --git a/doc/under-the-hood.html b/doc/under-the-hood.html deleted file mode 100644 index ee0ecdfb..00000000 --- a/doc/under-the-hood.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - A Peek Under the Hood - -

- c++boost.gif (8819 bytes) -

-

- A Peek Under the Hood -

-

- Declaring a class_builder<T> causes the instantiation - of an extension_class<T> to which it forwards all - member function calls and which is doing most of the real work. - extension_class<T> is a subclass of - PyTypeObject, the struct which Python's 'C' API uses - to describe a type. An instance of the - extension_class<> becomes the Python type object - corresponding to hello::world. When we add it to the module it goes into the - module's dictionary to be looked up under the name "world". -

- Boost.Python uses C++'s template argument deduction mechanism to determine the - types of arguments to functions (except constructors, for which we must - provide an argument list - because they can't be named in C++). Then, it calls the appropriate - overloaded functions PyObject* - to_python(S) and - S'from_python(PyObject*, - type<S>) which convert between any C++ - type S and a PyObject*, the type which represents a - reference to any Python object in its 'C' API. The extension_class<T> - template defines a whole raft of these conversions (for T, T*, - T&, std::auto_ptr<T>, etc.), using the same inline - friend function technique employed by the boost operators - library. -

- Because the to_python and from_python functions - for a user-defined class are defined by - extension_class<T>, it is important that an instantiation of - extension_class<T> is visible to any code which wraps - a C++ function with a T, T*, const T&, etc. parameter or - return value. In particular, you may want to create all of the classes at - the top of your module's init function, then def the member - functions later to avoid problems with inter-class dependencies. -

- Next: Building a Module with Boost.Python - Previous: Special Method and Operator Support - Up: Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability for - any purpose. -

- Updated: Nov 26, 2000 - diff --git a/example/README b/example/README deleted file mode 100644 index 817facd0..00000000 --- a/example/README +++ /dev/null @@ -1,24 +0,0 @@ -To get started with the Boost Python Library, use the examples -getting_started1.cpp and getting_started2.cpp. - -Examples for providing pickle support can be found in: - pickle1.cpp - pickle2.cpp - pickle3.cpp -See also: libs/python/doc/pickle.html - -Other advanced concepts are introduced by: - abstract.cpp - simple_vector.cpp - do_it_yourself_convts.cpp - -Examples for the cross-module support are provided by: - noncopyable_export.cpp - noncopyable_import.cpp - dvect.cpp - ivect.cpp -See also: libs/python/doc/cross_module.html - -The files example1.cpp and rwgk1.cpp are obsolete. They are only -included because the Visual Studio project in the build directory still -refers to them. diff --git a/example/abstract.cpp b/example/abstract.cpp deleted file mode 100644 index 97e38c2e..00000000 --- a/example/abstract.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Example by Ullrich Koethe -#include "boost/python/class_builder.hpp" -#include - -struct Abstract -{ - virtual std::string test() = 0; -}; - -struct Abstract_callback: Abstract -{ - Abstract_callback(PyObject * self) - : m_self(self) - {} - - std::string test() - { - return boost::python::callback::call_method(m_self, "test"); - } - - PyObject * m_self; -}; - -BOOST_PYTHON_MODULE_INIT(abstract) -{ - boost::python::module_builder a("abstract"); - - boost::python::class_builder - a_class(a, "Abstract"); - a_class.def(boost::python::constructor<>()); // wrap a constructor - a_class.def(&Abstract::test, "test"); -} diff --git a/example/do_it_yourself_convts.cpp b/example/do_it_yourself_convts.cpp deleted file mode 100644 index 01be6ef6..00000000 --- a/example/do_it_yourself_convts.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -/* - - This example shows how to convert a class from and to native - Python objects, such as tuples. - - We do not want to expose the helper class MillerIndex as an - Extension Class. However, in order to simplify the wrapper code, - we want to define from_python() and to_python() functions for - class MillerIndex. - - Consider the alternatives: - - - Expose MillerIndex as an Extension Class. - We need a constructor MillerIndex(python::tuple). - Python function calls become more complex: - foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) - We need a method such as MillerIndex().as_tuple(). - - - Define a wrapper function for each function that we - want to expose, e.g.: - void add(const IndexingSet& ixset, const python::tuple PyMIx) - - The first alternative introduces a new type that the user has to - deal with. Other modules using Miller indices might organize them in - different ways, for example to increase runtime efficiency for - important procedures. This means, the user has to know how to - convert between the different kinds of Miller index representations. - This can quickly become a nuisance. Relying on native Python data - structures minimizes the number of special types the user has to - learn and convert. Of course, this argument is only valid for - small and relatively simply classes. - - If there are many member functions with MillerIndex arguments, the - second alternative is impractical, and concentrating the conversion - mechanism in one central place is essential for code - maintainability. An added benefit is that more convenient (smarter) - conversion functions can be provided without cluttering the rest of - the wrapper code. - - */ - -#include -#include -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // The helper class. - // - class MillerIndex { - public: - int v[3]; - }; - - // The main class. Imagine that there are MANY member functions - // like add() and get(). - // - class IndexingSet { - private: - std::vector VMIx; - public: - void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } - MillerIndex get(std::size_t i) const { return VMIx[i]; } - }; -} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - - // Convert a Python tuple to a MillerIndex object. - // - MillerIndex from_python(PyObject* p, python::type) - { - python::tuple tup - = python::tuple(python::ref(p, python::ref::increment_count)); - if (tup.size() != 3) { - PyErr_SetString(PyExc_ValueError, - "expecting exactly 3 values in tuple."); - throw python::error_already_set(); - } - MillerIndex result; - for (int i = 0; i < 3; i++) - result.v[i] = from_python(tup[i].get(), python::type()); - return result; - } - - // Similar conversion for MillerIndex objects passed by value. - // Not actually used, but included to show the principle. - // - MillerIndex from_python(PyObject* p, python::type) - { - return from_python(p, python::type()); - } - - // Convert a MillerIndex object to a Python tuple. - // - PyObject* to_python(const MillerIndex& hkl) - { - python::tuple result(3); - for (int i = 0; i < 3; i++) - result.set_item(i, python::ref(to_python(hkl.v[i]))); - return result.reference().release(); - } - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts) -{ - // Create an object representing this extension module. - python::module_builder this_module("do_it_yourself_convts"); - - // Create the Python type object for our extension class. - python::class_builder ixset_class(this_module, "IndexingSet"); - - // Add the __init__ function. - ixset_class.def(python::constructor<>()); - // Add the member functions. - ixset_class.def(&IndexingSet::add, "add"); - ixset_class.def(&IndexingSet::get, "get"); -} diff --git a/example/dvect.cpp b/example/dvect.cpp deleted file mode 100644 index fa1506fe..00000000 --- a/example/dvect.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include "dvect.h" -#include "ivect.h" -#include -namespace python = boost::python; - -namespace { - -# include "dvect_conversions.cpp" -# include "ivect_conversions.cpp" - - vects::ivect dvect_as_ivect(const vects::dvect& dv) - { - vects::ivect iv(dv.size()); - vects::ivect::iterator iviter = iv.begin(); - for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); - return iv; - } -} - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(dvect) -{ - python::module_builder this_module("dvect"); - - python::class_builder dvect_class(this_module, "dvect"); - python::export_converters(dvect_class); - - python::import_converters ivect_converters("ivect", "ivect"); - - dvect_class.def(python::constructor()); - dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); - dvect_class.def(dvect_as_ivect, "as_ivect"); - -# include "dvect_defs.cpp" -# include "ivect_defs.cpp" -} diff --git a/example/dvect.h b/example/dvect.h deleted file mode 100644 index d059f04d..00000000 --- a/example/dvect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DVECT_H -#define DVECT_H - -#include -#include - -namespace vects { - - struct dvect : public std::vector - { - dvect() : std::vector() {} - dvect(std::size_t n) : std::vector(n) {} - dvect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // DVECT_H diff --git a/example/dvect_conversions.cpp b/example/dvect_conversions.cpp deleted file mode 100644 index 21527243..00000000 --- a/example/dvect_conversions.cpp +++ /dev/null @@ -1,51 +0,0 @@ - // basics first: const reference converters - boost::python::tuple const_dvect_reference_as_tuple(const vects::dvect& dv) - { - return dv.as_tuple(); - } - - // to_python smart pointer conversions - std::auto_ptr dvect_as_auto_ptr(const vects::dvect& dv) - { - return std::auto_ptr(new vects::dvect(dv)); - } - boost::shared_ptr dvect_as_shared_ptr(const vects::dvect& dv) - { - return boost::shared_ptr(new vects::dvect(dv)); - } - - // smart pointers passed by value - boost::python::ref auto_ptr_value_dvect_as_tuple(std::auto_ptr dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_value_dvect_as_tuple(boost::shared_ptr dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - - // smart pointers passed by reference - boost::python::ref auto_ptr_reference_dvect_as_tuple(std::auto_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_reference_dvect_as_tuple(boost::shared_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - - // smart pointers passed by const reference - boost::python::ref auto_ptr_const_reference_dvect_as_tuple(const std::auto_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_const_reference_dvect_as_tuple(const boost::shared_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } diff --git a/example/dvect_defs.cpp b/example/dvect_defs.cpp deleted file mode 100644 index 2739b219..00000000 --- a/example/dvect_defs.cpp +++ /dev/null @@ -1,13 +0,0 @@ - this_module.def(dvect_as_auto_ptr, "dvect_as_auto_ptr"); - this_module.def(dvect_as_shared_ptr, "dvect_as_shared_ptr"); - - this_module.def(const_dvect_reference_as_tuple, "const_dvect_reference_as_tuple"); - - this_module.def(auto_ptr_value_dvect_as_tuple, "auto_ptr_value_dvect_as_tuple"); - this_module.def(shared_ptr_value_dvect_as_tuple, "shared_ptr_value_dvect_as_tuple"); - - this_module.def(auto_ptr_reference_dvect_as_tuple, "auto_ptr_reference_dvect_as_tuple"); - this_module.def(shared_ptr_reference_dvect_as_tuple, "shared_ptr_reference_dvect_as_tuple"); - - this_module.def(auto_ptr_const_reference_dvect_as_tuple, "auto_ptr_const_reference_dvect_as_tuple"); - this_module.def(shared_ptr_const_reference_dvect_as_tuple, "shared_ptr_const_reference_dvect_as_tuple"); diff --git a/example/example1.cpp b/example/example1.cpp deleted file mode 100644 index 7bc5a1b7..00000000 --- a/example/example1.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include - -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 - -// Python requires an exported function called init 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 world_class(hello, "world"); - - // Add the __init__ function - world_class.def(boost::python::constructor()); - // 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 -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) -{ - return 1; -} -#endif // _WIN32 diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp deleted file mode 100644 index 2f180633..00000000 --- a/example/getting_started1.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -#include - -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 -namespace python = boost::python; - -// Python requires an exported function called init in every -// extension module. This is where we build the module contents. -BOOST_PYTHON_MODULE_INIT(getting_started1) -{ - // Create an object representing this extension module. - python::module_builder this_module("getting_started1"); - - // Add regular functions to the module. - this_module.def(greet, "greet"); - this_module.def(square, "square"); -} diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp deleted file mode 100644 index 04fbcc29..00000000 --- a/example/getting_started2.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -#include -#include - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class hello - { - public: - hello(const std::string& country) { this->country = country; } - std::string greet() const { return "Hello from " + country; } - private: - std::string country; - }; - - // A function taking a hello object as an argument. - std::string invite(const hello& w) { - return w.greet() + "! Please come soon!"; - } -} - -#include -namespace python = boost::python; - -BOOST_PYTHON_MODULE_INIT(getting_started2) -{ - // Create an object representing this extension module. - python::module_builder this_module("getting_started2"); - - // Create the Python type object for our extension class. - python::class_builder hello_class(this_module, "hello"); - - // Add the __init__ function. - hello_class.def(python::constructor()); - // Add a regular member function. - hello_class.def(&hello::greet, "greet"); - - // Add invite() as a regular function to the module. - this_module.def(invite, "invite"); - - // Even better, invite() can also be made a member of hello_class!!! - hello_class.def(invite, "invite"); -} diff --git a/example/ivect.cpp b/example/ivect.cpp deleted file mode 100644 index 35662b10..00000000 --- a/example/ivect.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include "dvect.h" -#include "ivect.h" -#include -namespace python = boost::python; - -namespace { - -# include "dvect_conversions.cpp" -# include "ivect_conversions.cpp" - - vects::dvect ivect_as_dvect(const vects::ivect& iv) - { - vects::dvect dv(iv.size()); - vects::dvect::iterator dviter = dv.begin(); - for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); - return dv; - } -} - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(ivect) -{ - python::module_builder this_module("ivect"); - - python::class_builder ivect_class(this_module, "ivect"); - python::export_converters(ivect_class); - - python::import_converters dvect_converters("dvect", "dvect"); - - ivect_class.def(python::constructor()); - ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); - ivect_class.def(ivect_as_dvect, "as_dvect"); - -# include "dvect_defs.cpp" -# include "ivect_defs.cpp" -} - diff --git a/example/ivect.h b/example/ivect.h deleted file mode 100644 index b8d52246..00000000 --- a/example/ivect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef IVECT_H -#define IVECT_H - -#include -#include - -namespace vects { - - struct ivect : public std::vector - { - ivect() : std::vector() {} - ivect(std::size_t n) : std::vector(n) {} - ivect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // IVECT_H diff --git a/example/ivect_conversions.cpp b/example/ivect_conversions.cpp deleted file mode 100644 index 4f59573d..00000000 --- a/example/ivect_conversions.cpp +++ /dev/null @@ -1,51 +0,0 @@ - // basics first: const reference converters - boost::python::tuple const_ivect_reference_as_tuple(const vects::ivect& iv) - { - return iv.as_tuple(); - } - - // to_python smart pointer conversions - std::auto_ptr ivect_as_auto_ptr(const vects::ivect& iv) - { - return std::auto_ptr(new vects::ivect(iv)); - } - boost::shared_ptr ivect_as_shared_ptr(const vects::ivect& iv) - { - return boost::shared_ptr(new vects::ivect(iv)); - } - - // smart pointers passed by value - boost::python::ref auto_ptr_value_ivect_as_tuple(std::auto_ptr iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_value_ivect_as_tuple(boost::shared_ptr iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - - // smart pointers passed by reference - boost::python::ref auto_ptr_reference_ivect_as_tuple(std::auto_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_reference_ivect_as_tuple(boost::shared_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - - // smart pointers passed by const reference - boost::python::ref auto_ptr_const_reference_ivect_as_tuple(const std::auto_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_const_reference_ivect_as_tuple(const boost::shared_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } diff --git a/example/ivect_defs.cpp b/example/ivect_defs.cpp deleted file mode 100644 index 811c243d..00000000 --- a/example/ivect_defs.cpp +++ /dev/null @@ -1,13 +0,0 @@ - this_module.def(ivect_as_auto_ptr, "ivect_as_auto_ptr"); - this_module.def(ivect_as_shared_ptr, "ivect_as_shared_ptr"); - - this_module.def(const_ivect_reference_as_tuple, "const_ivect_reference_as_tuple"); - - this_module.def(auto_ptr_value_ivect_as_tuple, "auto_ptr_value_ivect_as_tuple"); - this_module.def(shared_ptr_value_ivect_as_tuple, "shared_ptr_value_ivect_as_tuple"); - - this_module.def(auto_ptr_reference_ivect_as_tuple, "auto_ptr_reference_ivect_as_tuple"); - this_module.def(shared_ptr_reference_ivect_as_tuple, "shared_ptr_reference_ivect_as_tuple"); - - this_module.def(auto_ptr_const_reference_ivect_as_tuple, "auto_ptr_const_reference_ivect_as_tuple"); - this_module.def(shared_ptr_const_reference_ivect_as_tuple, "shared_ptr_const_reference_ivect_as_tuple"); diff --git a/example/nested.cpp b/example/nested.cpp deleted file mode 100644 index a5632d16..00000000 --- a/example/nested.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how convert a nested Python tuple. - */ - -#include -#include - -namespace { - - boost::python::list - show_nested_tuples(boost::python::tuple outer) - { - boost::python::list result; - for (int i = 0; i < outer.size(); i++) { - boost::python::tuple inner( - BOOST_PYTHON_CONVERSION::from_python(outer[i].get(), - boost::python::type())); - for (int j = 0; j < inner.size(); j++) { - double x = BOOST_PYTHON_CONVERSION::from_python(inner[j].get(), - boost::python::type()); - char buf[128]; - sprintf(buf, "(%d,%d) %.6g", i, j, x); - result.append(BOOST_PYTHON_CONVERSION::to_python(std::string(buf))); - } - } - return result; - } - -} - -BOOST_PYTHON_MODULE_INIT(nested) -{ - boost::python::module_builder this_module("nested"); - this_module.def(show_nested_tuples, "show_nested_tuples"); -} diff --git a/example/noncopyable.h b/example/noncopyable.h deleted file mode 100644 index de7b3672..00000000 --- a/example/noncopyable.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NONCOPYABLE_H -#define NONCOPYABLE_H - -class store -{ - private: - store(const store&) { } // Disable the copy constructor. - int number; - public: - store(const int i) : number(i) { } - int recall() const { return number; } -}; - -#endif // NONCOPYABLE_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp deleted file mode 100644 index 3a81db75..00000000 --- a/example/noncopyable_export.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include -namespace python = boost::python; - -#include "noncopyable.h" - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(noncopyable_export) -{ - python::module_builder this_module("noncopyable_export"); - - python::class_builder store_class(this_module, "store"); - python::export_converters_noncopyable(store_class); - - store_class.def(python::constructor()); - store_class.def(&store::recall, "recall"); -} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp deleted file mode 100644 index d4227642..00000000 --- a/example/noncopyable_import.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include -namespace python = boost::python; - -#include "noncopyable.h" - -namespace { // Avoid cluttering the global namespace. - - // A function with store objects as both input and output parameters. - // Because the copy constructor is disabled, we cannot pass a store - // object by value. Instead, we pass a smart pointer. - std::auto_ptr add_stores(const store& s1, const store& s2) - { - int sum = s1.recall() + s2.recall(); - std::auto_ptr ss = std::auto_ptr(new store(sum)); - return ss; - } -} - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(noncopyable_import) -{ - python::module_builder this_module("noncopyable_import"); - - python::import_converters - dvect_converters("noncopyable_export", "store"); - - // Imagine all the additional classes with member functions - // that have store objects as input and output parameters. - // Lots and lots of them. - // However, to keep this example simple, we only define a - // module-level function. - this_module.def(add_stores, "add_stores"); -} diff --git a/example/pickle1.cpp b/example/pickle1.cpp deleted file mode 100644 index af041e72..00000000 --- a/example/pickle1.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below can be fully restored by passing the - appropriate argument to the constructor. Therefore it is sufficient - to define the pickle interface method __getinitargs__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - private: - std::string country; - int secret_number; - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle1) -{ - // Create an object representing this extension module. - python::module_builder this_module("pickle1"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); -} diff --git a/example/pickle2.cpp b/example/pickle2.cpp deleted file mode 100644 index 576180ee..00000000 --- a/example/pickle2.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - For simplicity, the __dict__ is not included in the result of - __getstate__. This is not generally recommended, but a valid - approach if it is anticipated that the object's __dict__ will - always be empty. Note that safety guard are provided to catch the - cases where this assumption is not true. - - pickle3.cpp shows how to include the object's __dict__ in the - result of __getstate__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - - using BOOST_PYTHON_CONVERSION::from_python; - - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - void world_setstate(world& w, python::tuple state) { - if (state.size() != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw python::error_already_set(); - } - int number = from_python(state[0].get(), python::type()); - if (number != 42) - w.set_secret_number(number); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle2) -{ - // Create an object representing this extension module. - python::module_builder this_module("pickle2"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def(world_getstate, "__getstate__"); - world_class.def(world_setstate, "__setstate__"); -} diff --git a/example/pickle3.cpp b/example/pickle3.cpp deleted file mode 100644 index 664bed0b..00000000 --- a/example/pickle3.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - The object's __dict__ is included in the result of __getstate__. - This requires more code (compare with pickle2.cpp), but is - unavoidable if the object's __dict__ is not always empty. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace boost { namespace python { - - ref getattr(PyObject* o, const std::string& attr_name) { - return ref(PyObject_GetAttrString(o, const_cast(attr_name.c_str()))); - } - ref getattr(const ref& r, const std::string& attr_name) { - return getattr(r.get(), attr_name); - } - -}} - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(python::tuple const & args, - python::dictionary const & keywords); - - PyObject* world_setstate(python::tuple const & args, - python::dictionary const & keywords); -} - -BOOST_PYTHON_MODULE_INIT(pickle3) -{ - // Create an object representing this extension module. - python::module_builder this_module("pickle3"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def_raw(world_getstate, "__getstate__"); - world_class.def_raw(world_setstate, "__setstate__"); - world_class.getstate_manages_dict(); -} - -namespace { - - using BOOST_PYTHON_CONVERSION::from_python; - using boost::python::type; - using boost::python::ref; - using boost::python::tuple; - using boost::python::list; - using boost::python::dictionary; - using boost::python::getattr; - - ref world_getstate(tuple const & args, dictionary const & keywords) - { - if(args.size() != 1 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::error_already_set(); - } - const world& w = from_python(args[0].get(), type()); - ref mydict = getattr(args[0], "__dict__"); - tuple result(2); - // store the object's __dict__ - result.set_item(0, mydict); - // store the internal state of the C++ object - result.set_item(1, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - PyObject* world_setstate(tuple const & args, dictionary const & keywords) - { - if(args.size() != 2 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::error_already_set(); - } - world& w = from_python(args[0].get(), type()); - ref mydict = getattr(args[0], "__dict__"); - tuple state = from_python(args[1].get(), type()); - if (state.size() != 2) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw python::error_already_set(); - } - // restore the object's __dict__ - dictionary odict = from_python(mydict.get(), type()); - const dictionary& pdict = from_python(state[0].get(), type()); - list pkeys(pdict.keys()); - for (int i = 0; i < pkeys.size(); i++) { - ref k(pkeys[i]); - //odict[k] = pdict[k]; // XXX memory leak! - odict[k] = pdict.get_item(k); // this does not leak. - } - // restore the internal state of the C++ object - int number = from_python(state[1].get(), type()); - if (number != 42) - w.set_secret_number(number); - return python::detail::none(); - } -} diff --git a/example/richcmp1.cpp b/example/richcmp1.cpp deleted file mode 100644 index f59aae65..00000000 --- a/example/richcmp1.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter -// This example shows how to use rich comparisons for a vector type. -// It also shows how to template the entire wrapping of a std::vector. -// See vector_wrapper.h. - -#include -#include "vector_wrapper.h" - -namespace vects { - - struct dvect : public std::vector - { - dvect() : std::vector() {} - dvect(size_t n) : std::vector(n) {} - dvect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (std::size_t i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (std::size_t i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - -# define DVECT_BINARY_OPERATORS(oper) \ - friend std::vector \ - operator##oper(const dvect& lhs, const dvect& rhs) \ - { \ - if (lhs.size() != rhs.size()) { \ - PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \ - throw boost::python::error_already_set(); \ - } \ - std::vector result(lhs.size()); \ - for (std::size_t i=0; i) - DVECT_BINARY_OPERATORS(>=) -# undef VECTOR_BINARY_OPERATORS - }; - -} // namespace - - -namespace { - - void init_module(boost::python::module_builder& this_module) - { - (void) example::wrap_vector(this_module, "vector_of_bool", bool()); - - boost::python::class_builder py_dvect(this_module, "dvect"); - - py_dvect.def(boost::python::constructor()); - py_dvect.def(&vects::dvect::as_tuple, "as_tuple"); - - const long - comp_operators = ( boost::python::op_lt | boost::python::op_le - | boost::python::op_eq | boost::python::op_ne - | boost::python::op_gt | boost::python::op_ge); - py_dvect.def(boost::python::operators()); - } - -} // namespace - -BOOST_PYTHON_MODULE_INIT(richcmp1) -{ - boost::python::module_builder this_module("richcmp1"); - // The actual work is done in a separate function in order - // to suppress a bogus VC60 warning. - init_module(this_module); -} diff --git a/example/richcmp2.cpp b/example/richcmp2.cpp deleted file mode 100644 index 993c6800..00000000 --- a/example/richcmp2.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// This example shows how to use rich comparisons for a type that -// does not support all six operators (<, <=, ==, !=, >, >=). -// To keep the example simple, we are using a "code" type does -// not really require rich comparisons. __cmp__ would be sufficient. -// However, with a more complicated type the main point of this -// example would be in danger of getting lost. - -#include - -namespace { - - // suppose operator< and operator> are not meaningful for code - class code { - public: - code(int c = 0) : m_code(c) {} - inline friend bool operator==(const code& lhs, const code& rhs) { - return lhs.m_code == rhs.m_code; - } - inline friend bool operator!=(const code& lhs, const code& rhs) { - return lhs.m_code != rhs.m_code; - } - private: - int m_code; - }; - -#if PYTHON_API_VERSION >= 1010 - boost::python::ref - NotImplemented(const code&, const code&) { - return - boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count); - } -#endif -} - -namespace { - - void init_module(boost::python::module_builder& this_module) - { - boost::python::class_builder py_code(this_module, "code"); - - py_code.def(boost::python::constructor<>()); - py_code.def(boost::python::constructor()); - py_code.def(boost::python::operators<( boost::python::op_eq - | boost::python::op_ne)>()); -#if PYTHON_API_VERSION >= 1010 - py_code.def(NotImplemented, "__lt__"); - py_code.def(NotImplemented, "__le__"); - py_code.def(NotImplemented, "__gt__"); - py_code.def(NotImplemented, "__ge__"); -#endif - } - -} // namespace - -BOOST_PYTHON_MODULE_INIT(richcmp2) -{ - boost::python::module_builder this_module("richcmp2"); - // The actual work is done in a separate function in order - // to suppress a bogus VC60 warning. - init_module(this_module); -} diff --git a/example/richcmp3.cpp b/example/richcmp3.cpp deleted file mode 100644 index 4be48fee..00000000 --- a/example/richcmp3.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter. -// Comprehensive operator overloading for two vector types and scalars. - -#include -#include "vector_wrapper.h" -#include "dvect.h" -#include "ivect.h" - -#define VECT_VECT_OPERATORS(result_type, vect_type1, oper, vect_type2) \ -namespace vects { \ - result_type \ - operator##oper (const vect_type1& lhs, const vect_type2& rhs) { \ - if (lhs.size() != rhs.size()) { \ - PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \ - throw boost::python::error_already_set(); \ - } \ - result_type result(lhs.size()); \ - for (std::size_t i=0; i, vect_type1, <, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, <=, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, ==, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, !=, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, >, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, >=, vect_type2) - -#define MATH_VECT_SCALAR_OPERATORS(result_type, vect_type, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, +, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, -, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, *, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, /, scalar_type) - -#define COMP_VECT_SCALAR_OPERATORS(vect_type, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, <, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, <=, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, ==, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, !=, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, >, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, >=, scalar_type) - -#define MATH_SCALAR_VECT_OPERATORS(result_type, scalar_type, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, +, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, -, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, *, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, /, vect_type) - -MATH_VECT_VECT_OPERATORS(dvect, dvect, dvect) -COMP_VECT_VECT_OPERATORS( dvect, dvect) -MATH_VECT_SCALAR_OPERATORS(dvect, dvect, double) -COMP_VECT_SCALAR_OPERATORS( dvect, double) -MATH_SCALAR_VECT_OPERATORS(dvect, double, dvect) -// comparison operators not needed since Python uses reflection - -MATH_VECT_VECT_OPERATORS(ivect, ivect, ivect) -COMP_VECT_VECT_OPERATORS( ivect, ivect) -MATH_VECT_SCALAR_OPERATORS(ivect, ivect, int) -COMP_VECT_SCALAR_OPERATORS( ivect, int) -MATH_SCALAR_VECT_OPERATORS(ivect, int, ivect) -// comparison operators not needed since Python uses reflection - -MATH_VECT_VECT_OPERATORS(dvect, dvect, ivect) -COMP_VECT_VECT_OPERATORS( dvect, ivect) -MATH_VECT_VECT_OPERATORS(dvect, ivect, dvect) -COMP_VECT_VECT_OPERATORS( ivect, dvect) - -#undef VECT_VECT_OPERATORS -#undef SCALAR_VECT_OPERATORS -#undef VECT_SCALAR_OPERATORS -#undef MATH_VECT_VECT_OPERATORS -#undef COMP_VECT_VECT_OPERATORS -#undef MATH_VECT_SCALAR_OPERATORS -#undef COMP_VECT_SCALAR_OPERATORS -#undef MATH_SCALAR_VECT_OPERATORS - -namespace { - - void init_module(boost::python::module_builder& this_module) - { - (void) example::wrap_vector(this_module, "vector_of_bool", bool()); - - const long - math_operators ( boost::python::op_mul | boost::python::op_add - | boost::python::op_div | boost::python::op_sub); - const long - comp_operators = ( boost::python::op_lt | boost::python::op_le - | boost::python::op_eq | boost::python::op_ne - | boost::python::op_gt | boost::python::op_ge); - - boost::python::class_builder - dvect_class(this_module, "dvect"); - boost::python::class_builder - ivect_class(this_module, "ivect"); - - dvect_class.def(boost::python::constructor()); - dvect_class.def(&vects::dvect::as_tuple,"as_tuple"); - - dvect_class.def(boost::python::operators()); - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - dvect_class.def(boost::python::operators(), - boost::python::left_operand() ); - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - - dvect_class.def(boost::python::operators()); - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - // left_operand not needed since Python uses reflection - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - - ivect_class.def(boost::python::constructor()); - ivect_class.def(&vects::ivect::as_tuple,"as_tuple"); - - ivect_class.def(boost::python::operators()); - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - ivect_class.def(boost::python::operators(), - boost::python::left_operand() ); - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - - ivect_class.def(boost::python::operators()); - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - // left_operand not needed since Python uses reflection - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - } - -} // namespace - -BOOST_PYTHON_MODULE_INIT(richcmp3) -{ - boost::python::module_builder this_module("richcmp3"); - // The actual work is done in a separate function in order - // to suppress a bogus VC60 warning. - init_module(this_module); -} diff --git a/example/rwgk1.cpp b/example/rwgk1.cpp deleted file mode 100644 index ca8bd22f..00000000 --- a/example/rwgk1.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include - -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 - -namespace python = boost::python; - -// Python requires an exported function called init 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"); -} diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp deleted file mode 100644 index e0f9e85e..00000000 --- a/example/simple_vector.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A wrapper is used to define additional constructors. - // - struct vector_double_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_double_wrapper(PyObject*, const std::vector& vd) - : std::vector(vd) {} - - vector_double_wrapper(PyObject* self) - : std::vector() {} - - vector_double_wrapper(PyObject* self, int n) - : std::vector(n) {} - - vector_double_wrapper(PyObject* self, python::tuple tuple) - : std::vector(tuple.size()) - { - std::vector::iterator vd = begin(); - for (int i = 0; i < tuple.size(); i++) - vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - python::type()); - } - }; - - void raise_vector_IndexError() { - PyErr_SetString(PyExc_IndexError, "vector index out of range"); - throw python::error_already_set(); - } - - double getitem(const std::vector& vd, std::size_t key) { - if (key >= vd.size()) raise_vector_IndexError(); - return vd[key]; - } - - void setitem(std::vector& vd, std::size_t key, double d) { - if (key >= vd.size()) raise_vector_IndexError(); - std::vector::iterator vditer = vd.begin(); - vditer[key] = d; - } - - void delitem(std::vector& vd, std::size_t key) { - if (key >= vd.size()) raise_vector_IndexError(); - std::vector::iterator vditer = vd.begin(); - vd.erase(vditer + key); - } - - // Convert vector_double to a regular Python tuple. - // - python::tuple as_tuple(const std::vector& vd) - { - python::tuple t(vd.size()); - for (int i = 0; i < vd.size(); i++) t.set_item(i, - python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); - return t; - } - - // Function returning a vector_double object to Python. - // - std::vector foo(int n) - { - std::vector vd(n); - std::vector::iterator vditer = vd.begin(); - for (int i = 0; i < n; i++) vditer[i] = double(i); - return vd; - } - - // Same as foo(), but avoid copying on return. - // - std::auto_ptr > bar(int n) - { - std::auto_ptr > vdptr(new std::vector(n)); - std::vector::iterator vditer = vdptr->begin(); - for (int i = 0; i < n; i++) vditer[i] = double(10 * i); - return vdptr; - } -} - -BOOST_PYTHON_MODULE_INIT(simple_vector) -{ - python::module_builder this_module("simple_vector"); - - python::class_builder, vector_double_wrapper> - vector_double(this_module, "vector_double"); - - vector_double.def(python::constructor<>()); - vector_double.def(python::constructor()); - vector_double.def(python::constructor()); - vector_double.def(&std::vector::size, "__len__"); - vector_double.def(getitem, "__getitem__"); - vector_double.def(setitem, "__setitem__"); - vector_double.def(delitem, "__delitem__"); - vector_double.def(as_tuple, "as_tuple"); - - this_module.def(foo, "foo"); - this_module.def(bar, "bar"); -} diff --git a/example/test_abstract.py b/example/test_abstract.py deleted file mode 100644 index a48aff1b..00000000 --- a/example/test_abstract.py +++ /dev/null @@ -1,24 +0,0 @@ -# Example by Ullrich Koethe -r'''>>> from abstract import * - >>> class A(Abstract): - ... def __init__(self, text): - ... Abstract.__init__(self) # call the base class constructor - ... self.text = text - ... def test(self): # implement abstract function - ... return self.text - ... - >>> a = A("Hello") - >>> a.test() - 'Hello' -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_abstract - return doctest.testmod(test_abstract) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_cross_module.py b/example/test_cross_module.py deleted file mode 100644 index c5e2bef6..00000000 --- a/example/test_cross_module.py +++ /dev/null @@ -1,140 +0,0 @@ -r'''>>> import tst_noncopyable - >>> tst_noncopyable.f() - 1 - 2 - 3 - >>> import tst_dvect1 - >>> tst_dvect1.f() - (1.0, 2.0, 3.0, 4.0, 5.0) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - >>> import tst_ivect1 - >>> tst_ivect1.f() - (1, 2, 3, 4, 5) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - >>> import sys - >>> if ("--broken-auto-ptr" in sys.argv): - ... broken_auto_ptr = 1 - ... else: - ... broken_auto_ptr = 0 - >>> import tst_dvect2 - >>> tst_dvect2.f(broken_auto_ptr) - 1. auto_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_value_ivect_as_tuple - None - 1. auto_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_value_dvect_as_tuple - None - 1. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - >>> import tst_ivect2 - >>> tst_ivect2.f(broken_auto_ptr) - 1. auto_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_value_dvect_as_tuple - None - 1. auto_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_value_ivect_as_tuple - None - 1. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_cross_module - return doctest.testmod(test_cross_module) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_do_it_yourself_convts.py b/example/test_do_it_yourself_convts.py deleted file mode 100644 index 6f5fa5a0..00000000 --- a/example/test_do_it_yourself_convts.py +++ /dev/null @@ -1,23 +0,0 @@ -r'''>>> import do_it_yourself_convts - >>> ixset = do_it_yourself_convts.IndexingSet() - >>> ixset.add((1,2,3)) - >>> ixset.add((4,5,6)) - >>> ixset.add((7,8,9)) - >>> print ixset.get(0) - (1, 2, 3) - >>> print ixset.get(1) - (4, 5, 6) - >>> print ixset.get(2) - (7, 8, 9) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_do_it_yourself_convts - return doctest.testmod(test_do_it_yourself_convts) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_example1.py b/example/test_example1.py deleted file mode 100644 index 3a30cb5b..00000000 --- a/example/test_example1.py +++ /dev/null @@ -1,51 +0,0 @@ -r''' -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -That's it! If we build this shared library and put it on our PYTHONPATH we can -now access our C++ class and function from Python. - - >>> import hello - >>> hi_world = hello.world(3) - >>> hi_world.get() - 'hi, world' - >>> hello.length(hi_world) - 9 - -We can even make a subclass of hello.world: - - - >>> class my_subclass(hello.world): - ... def get(self): - ... return 'hello, world' - ... - >>> y = my_subclass(2) - >>> y.get() - 'hello, world' - -Pretty cool! You can't do that with an ordinary Python extension type! - - >>> hello.length(y) - 9 - -Of course, you may now have a slightly empty feeling in the pit of your little -pythonic stomach. Perhaps you feel your subclass deserves to have a length() of -12? If so, read on... -''' -from hello import * - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_example1 - return doctest.testmod(test_example1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_getting_started1.py b/example/test_getting_started1.py deleted file mode 100644 index cd8fb59e..00000000 --- a/example/test_getting_started1.py +++ /dev/null @@ -1,18 +0,0 @@ -r'''>>> import getting_started1 - >>> print getting_started1.greet() - hello, world - >>> number = 11 - >>> print number, '*', number, '=', getting_started1.square(number) - 11 * 11 = 121 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_getting_started1 - return doctest.testmod(test_getting_started1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_getting_started2.py b/example/test_getting_started2.py deleted file mode 100644 index ccfaa4f1..00000000 --- a/example/test_getting_started2.py +++ /dev/null @@ -1,31 +0,0 @@ -r'''>>> from getting_started2 import * - >>> hi = hello('California') - >>> hi.greet() - 'Hello from California' - >>> invite(hi) - 'Hello from California! Please come soon!' - >>> hi.invite() - 'Hello from California! Please come soon!' - - >>> class wordy(hello): - ... def greet(self): - ... return hello.greet(self) + ', where the weather is fine' - ... - >>> hi2 = wordy('Florida') - >>> hi2.greet() - 'Hello from Florida, where the weather is fine' - >>> invite(hi2) - 'Hello from Florida! Please come soon!' -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_getting_started2 - return doctest.testmod(test_getting_started2) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_nested.py b/example/test_nested.py deleted file mode 100644 index e9abbf0f..00000000 --- a/example/test_nested.py +++ /dev/null @@ -1,23 +0,0 @@ -r'''>>> import nested - >>> s = nested.show_nested_tuples(((1,2,3), (4,5,6,7))) - >>> for l in s: - ... print l - (0,0) 1 - (0,1) 2 - (0,2) 3 - (1,0) 4 - (1,1) 5 - (1,2) 6 - (1,3) 7 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_nested - return doctest.testmod(test_nested) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_pickle1.py b/example/test_pickle1.py deleted file mode 100644 index 48c76a5f..00000000 --- a/example/test_pickle1.py +++ /dev/null @@ -1,33 +0,0 @@ -r'''>>> import pickle1 - >>> import re - >>> import pickle - >>> pickle1.world.__module__ - 'pickle1' - >>> pickle1.world.__safe_for_unpickling__ - 1 - >>> pickle1.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\)\)", - ... repr(pickle1.world('Hello').__reduce__())) - >>> - >>> wd = pickle1.world('California') - >>> pstr = pickle.dumps(wd) - >>> wl = pickle.loads(pstr) - >>> print wd.greet() - Hello from California! - >>> print wl.greet() - Hello from California! -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle1 - return doctest.testmod(test_pickle1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_pickle2.py b/example/test_pickle2.py deleted file mode 100644 index bafa9875..00000000 --- a/example/test_pickle2.py +++ /dev/null @@ -1,47 +0,0 @@ -r'''>>> import pickle2 - >>> import re - >>> import pickle - >>> pickle2.world.__module__ - 'pickle2' - >>> pickle2.world.__safe_for_unpickling__ - 1 - >>> pickle2.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\), \(0,\)\)", - ... repr(pickle2.world('Hello').__reduce__())) - >>> - >>> for number in (24, 42): - ... wd = pickle2.world('California') - ... wd.set_secret_number(number) - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number() - ... print wl.greet(), wl.get_secret_number() - Hello from California! 24 - Hello from California! 24 - Hello from California! 42 - Hello from California! 0 - -# Now show that the __dict__ is not taken care of. - >>> wd = pickle2.world('California') - >>> wd.x = 1 - >>> wd.__dict__ - {'x': 1} - >>> try: pstr = pickle.dumps(wd) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__getstate_manages_dict__ not set) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle2 - return doctest.testmod(test_pickle2) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_pickle3.py b/example/test_pickle3.py deleted file mode 100644 index 6ac83b18..00000000 --- a/example/test_pickle3.py +++ /dev/null @@ -1,39 +0,0 @@ -r'''>>> import pickle3 - >>> import re - >>> import pickle - >>> pickle3.world.__module__ - 'pickle3' - >>> pickle3.world.__safe_for_unpickling__ - 1 - >>> pickle3.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\), \(\{\}, 0\)\)", - ... repr(pickle3.world('Hello').__reduce__())) - >>> - >>> for number in (24, 42): - ... wd = pickle3.world('California') - ... wd.set_secret_number(number) - ... wd.x = 2 * number - ... wd.y = 'y' * number - ... wd.z = 3. * number - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z - ... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z - Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 - Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 - Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 - Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle3 - return doctest.testmod(test_pickle3) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_richcmp1.py b/example/test_richcmp1.py deleted file mode 100644 index d25fcc9c..00000000 --- a/example/test_richcmp1.py +++ /dev/null @@ -1,40 +0,0 @@ -r'''>>> import richcmp1 - >>> d1 = richcmp1.dvect((0, 1, 3, 3, 6, 7)) - >>> d2 = richcmp1.dvect((1, 2, 3, 4, 5, 6)) - >>> print d1.as_tuple() - (0.0, 1.0, 3.0, 3.0, 6.0, 7.0) - >>> print d2.as_tuple() - (1.0, 2.0, 3.0, 4.0, 5.0, 6.0) - >>> print (d1 < d2).as_tuple() - (1, 1, 0, 1, 0, 0) - >>> print (d1 <= d2).as_tuple() - (1, 1, 1, 1, 0, 0) - >>> print (d1 == d2).as_tuple() - (0, 0, 1, 0, 0, 0) - >>> print (d1 != d2).as_tuple() - (1, 1, 0, 1, 1, 1) - >>> print (d1 > d2).as_tuple() - (0, 0, 0, 0, 1, 1) - >>> print (d1 >= d2).as_tuple() - (0, 0, 1, 0, 1, 1) - >>> try: d1 == richcmp1.dvect((1, 2, 3, 4, 5)) - ... except ValueError, e: print str(e) - ... - vectors have different sizes -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_richcmp1 - return doctest.testmod(test_richcmp1) - -if __name__ == '__main__': - import sys - if ( hasattr(sys, 'version_info') - and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) - or sys.version_info[0] > 2)): - sys.exit(run()[0]) - else: - print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_richcmp2.py b/example/test_richcmp2.py deleted file mode 100644 index 859928c3..00000000 --- a/example/test_richcmp2.py +++ /dev/null @@ -1,41 +0,0 @@ -r'''>>> import richcmp2 - >>> c1 = richcmp2.code(1) - >>> c2 = richcmp2.code(2) - >>> c3 = richcmp2.code(2) - >>> print c1 == c2 - 0 - >>> print c1 != c2 - 1 - >>> print c2 == c3 - 1 - >>> print c2 != c3 - 0 - >>> print c1 < c2 - 1 - >>> print c1 <= c2 - 1 - >>> print c1 == c2 - 0 - >>> print c1 != c2 - 1 - >>> print c1 > c2 - 0 - >>> print c1 >= c2 - 0 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_richcmp1 - return doctest.testmod(test_richcmp1) - -if __name__ == '__main__': - import sys - if ( hasattr(sys, 'version_info') - and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) - or sys.version_info[0] > 2)): - sys.exit(run()[0]) - else: - print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_richcmp3.py b/example/test_richcmp3.py deleted file mode 100644 index a769af17..00000000 --- a/example/test_richcmp3.py +++ /dev/null @@ -1,77 +0,0 @@ -r'''>>> import richcmp3 - >>> - >>> iv = richcmp3.ivect((1,2,3,4,5)) - >>> print iv.as_tuple() - (1, 2, 3, 4, 5) - >>> dv = richcmp3.dvect((2,-2,3,8,-5)) - >>> print dv.as_tuple() - (2.0, -2.0, 3.0, 8.0, -5.0) - >>> - >>> print (iv+dv).as_tuple() - (3.0, 0.0, 6.0, 12.0, 0.0) - >>> print (iv+3).as_tuple() - (4, 5, 6, 7, 8) - >>> print (3+iv).as_tuple() - (4, 5, 6, 7, 8) - >>> - >>> print "vect vs. vect Comparisons:" - vect vs. vect Comparisons: - >>> print (iv < dv).as_tuple() - (1, 0, 0, 1, 0) - >>> print (iv <= dv).as_tuple() - (1, 0, 1, 1, 0) - >>> print (iv == dv).as_tuple() - (0, 0, 1, 0, 0) - >>> print (iv != dv).as_tuple() - (1, 1, 0, 1, 1) - >>> print (iv > dv).as_tuple() - (0, 1, 0, 0, 1) - >>> print (iv >= dv).as_tuple() - (0, 1, 1, 0, 1) - >>> - >>> print "vect vs. scalar Comparisons:" - vect vs. scalar Comparisons: - >>> print (iv < 3).as_tuple() - (1, 1, 0, 0, 0) - >>> print (iv <= 3).as_tuple() - (1, 1, 1, 0, 0) - >>> print (iv == 3).as_tuple() - (0, 0, 1, 0, 0) - >>> print (iv != 3).as_tuple() - (1, 1, 0, 1, 1) - >>> print (iv > 3).as_tuple() - (0, 0, 0, 1, 1) - >>> print (iv >= 3).as_tuple() - (0, 0, 1, 1, 1) - >>> - >>> print "scalar vs. vect Comparisons:" - scalar vs. vect Comparisons: - >>> print (3 < iv).as_tuple() - (0, 0, 0, 1, 1) - >>> print (3 <= iv).as_tuple() - (0, 0, 1, 1, 1) - >>> print (3 == iv).as_tuple() - (0, 0, 1, 0, 0) - >>> print (3 != iv).as_tuple() - (1, 1, 0, 1, 1) - >>> print (3 > iv).as_tuple() - (1, 1, 0, 0, 0) - >>> print (3 >= iv).as_tuple() - (1, 1, 1, 0, 0) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_richcmp3 - return doctest.testmod(test_richcmp3) - -if __name__ == '__main__': - import sys - if ( hasattr(sys, 'version_info') - and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) - or sys.version_info[0] > 2)): - sys.exit(run()[0]) - else: - print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_rwgk1.py b/example/test_rwgk1.py deleted file mode 100644 index 631eea3e..00000000 --- a/example/test_rwgk1.py +++ /dev/null @@ -1,19 +0,0 @@ -r'''>>> import rwgk1 - >>> print rwgk1.greet() - hello, world - >>> number = 11 - >>> print number, '*', number, '=', rwgk1.square(number) - 11 * 11 = 121 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_rwgk1 - return doctest.testmod(test_rwgk1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_simple_vector.py b/example/test_simple_vector.py deleted file mode 100644 index c6a2cd59..00000000 --- a/example/test_simple_vector.py +++ /dev/null @@ -1,42 +0,0 @@ -r'''>>> import simple_vector - >>> v=simple_vector.vector_double() - >>> print v.as_tuple() - () - >>> v=simple_vector.vector_double(5) - >>> print v.as_tuple() - (0.0, 0.0, 0.0, 0.0, 0.0) - >>> print len(v) - 5 - >>> v=simple_vector.vector_double((3,4,5)) - >>> print v.as_tuple() - (3.0, 4.0, 5.0) - >>> print v[1] - 4.0 - >>> v[1] = 40 - >>> print v.as_tuple() - (3.0, 40.0, 5.0) - >>> for e in v: - ... print e - 3.0 - 40.0 - 5.0 - >>> del v[1] - >>> print v.as_tuple() - (3.0, 5.0) - >>> print simple_vector.foo(11).as_tuple() - (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) - >>> print simple_vector.bar(12).as_tuple() - (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_simple_vector - return doctest.testmod(test_simple_vector) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/tst_dvect1.py b/example/tst_dvect1.py deleted file mode 100644 index 22315528..00000000 --- a/example/tst_dvect1.py +++ /dev/null @@ -1,20 +0,0 @@ -def f(): - import dvect - dv = dvect.dvect((1,2,3,4,5)) - print dv.as_tuple() - iv = dv.as_ivect() - print iv.as_tuple() - print dvect.const_ivect_reference_as_tuple(iv) - aiv = dvect.ivect_as_auto_ptr(iv) - print dvect.const_ivect_reference_as_tuple(aiv) - siv = dvect.ivect_as_shared_ptr(iv) - print dvect.const_ivect_reference_as_tuple(siv) - print aiv.as_tuple() - print siv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_dvect2.py b/example/tst_dvect2.py deleted file mode 100644 index 90d381a7..00000000 --- a/example/tst_dvect2.py +++ /dev/null @@ -1,104 +0,0 @@ -def f(broken_auto_ptr): - import dvect - import ivect - # - dv = dvect.dvect((1,2,3,4,5)) - iv = dv.as_ivect() - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_value_ivect_as_tuple' - print ivect.auto_ptr_value_ivect_as_tuple(aiv) - print '2. auto_ptr_value_ivect_as_tuple' - if (not broken_auto_ptr): - print ivect.auto_ptr_value_ivect_as_tuple(aiv) - else: - print None - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_value_dvect_as_tuple' - print ivect.auto_ptr_value_dvect_as_tuple(adv) - print '2. auto_ptr_value_dvect_as_tuple' - if (not broken_auto_ptr): - print ivect.auto_ptr_value_dvect_as_tuple(adv) - else: - print None - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_value_ivect_as_tuple' - print ivect.shared_ptr_value_ivect_as_tuple(siv) - print '2. shared_ptr_value_ivect_as_tuple' - print ivect.shared_ptr_value_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_value_dvect_as_tuple' - print ivect.shared_ptr_value_dvect_as_tuple(sdv) - print '2. shared_ptr_value_dvect_as_tuple' - print ivect.shared_ptr_value_dvect_as_tuple(sdv) - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_reference_ivect_as_tuple' - print ivect.auto_ptr_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_reference_ivect_as_tuple' - print ivect.auto_ptr_reference_ivect_as_tuple(aiv) - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_reference_dvect_as_tuple' - print ivect.auto_ptr_reference_dvect_as_tuple(adv) - print '2. auto_ptr_reference_dvect_as_tuple' - print ivect.auto_ptr_reference_dvect_as_tuple(adv) - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_reference_ivect_as_tuple' - print ivect.shared_ptr_reference_ivect_as_tuple(siv) - print '2. shared_ptr_reference_ivect_as_tuple' - print ivect.shared_ptr_reference_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_reference_dvect_as_tuple' - print ivect.shared_ptr_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_reference_dvect_as_tuple' - print ivect.shared_ptr_reference_dvect_as_tuple(sdv) - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_const_reference_ivect_as_tuple' - print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_const_reference_ivect_as_tuple' - print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_const_reference_dvect_as_tuple' - print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) - print '2. auto_ptr_const_reference_dvect_as_tuple' - print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_const_reference_ivect_as_tuple' - print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) - print '2. shared_ptr_const_reference_ivect_as_tuple' - print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_const_reference_dvect_as_tuple' - print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_const_reference_dvect_as_tuple' - print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) - -if (__name__ == "__main__"): - import sys, string - broken_auto_ptr = 0 - n = 1 - - if len(sys.argv) > 1: - argv = [] - - for x in sys.argv: - if x != '--broken-auto-ptr': - argv.append(x) - broken_auto_ptr = argv != sys.argv - sys.argv = argv - - if len(sys.argv) > 1: - n = string.atoi(sys.argv[1]) - - for i in xrange(n): - f(broken_auto_ptr) diff --git a/example/tst_ivect1.py b/example/tst_ivect1.py deleted file mode 100644 index 7369fdbf..00000000 --- a/example/tst_ivect1.py +++ /dev/null @@ -1,20 +0,0 @@ -def f(): - import ivect - iv = ivect.ivect((1,2,3,4,5)) - print iv.as_tuple() - dv = iv.as_dvect() - print dv.as_tuple() - print ivect.const_dvect_reference_as_tuple(dv) - adv = ivect.dvect_as_auto_ptr(dv) - print ivect.const_dvect_reference_as_tuple(adv) - sdv = ivect.dvect_as_shared_ptr(dv) - print ivect.const_dvect_reference_as_tuple(sdv) - print adv.as_tuple() - print sdv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_ivect2.py b/example/tst_ivect2.py deleted file mode 100644 index a9e6aeef..00000000 --- a/example/tst_ivect2.py +++ /dev/null @@ -1,104 +0,0 @@ -def f(broken_auto_ptr): - import ivect - import dvect - # - iv = ivect.ivect((1,2,3,4,5)) - dv = iv.as_dvect() - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_value_dvect_as_tuple' - print dvect.auto_ptr_value_dvect_as_tuple(adv) - print '2. auto_ptr_value_dvect_as_tuple' - if (not broken_auto_ptr): - print dvect.auto_ptr_value_dvect_as_tuple(adv) - else: - print None - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_value_ivect_as_tuple' - print dvect.auto_ptr_value_ivect_as_tuple(aiv) - print '2. auto_ptr_value_ivect_as_tuple' - if (not broken_auto_ptr): - print dvect.auto_ptr_value_ivect_as_tuple(aiv) - else: - print None - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_value_dvect_as_tuple' - print dvect.shared_ptr_value_dvect_as_tuple(sdv) - print '2. shared_ptr_value_dvect_as_tuple' - print dvect.shared_ptr_value_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_value_ivect_as_tuple' - print dvect.shared_ptr_value_ivect_as_tuple(siv) - print '2. shared_ptr_value_ivect_as_tuple' - print dvect.shared_ptr_value_ivect_as_tuple(siv) - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_reference_dvect_as_tuple' - print dvect.auto_ptr_reference_dvect_as_tuple(adv) - print '2. auto_ptr_reference_dvect_as_tuple' - print dvect.auto_ptr_reference_dvect_as_tuple(adv) - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_reference_ivect_as_tuple' - print dvect.auto_ptr_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_reference_ivect_as_tuple' - print dvect.auto_ptr_reference_ivect_as_tuple(aiv) - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_reference_dvect_as_tuple' - print dvect.shared_ptr_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_reference_dvect_as_tuple' - print dvect.shared_ptr_reference_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_reference_ivect_as_tuple' - print dvect.shared_ptr_reference_ivect_as_tuple(siv) - print '2. shared_ptr_reference_ivect_as_tuple' - print dvect.shared_ptr_reference_ivect_as_tuple(siv) - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_const_reference_dvect_as_tuple' - print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) - print '2. auto_ptr_const_reference_dvect_as_tuple' - print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_const_reference_ivect_as_tuple' - print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_const_reference_ivect_as_tuple' - print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_const_reference_dvect_as_tuple' - print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_const_reference_dvect_as_tuple' - print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_const_reference_ivect_as_tuple' - print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) - print '2. shared_ptr_const_reference_ivect_as_tuple' - print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) - -if (__name__ == "__main__"): - import sys, string - broken_auto_ptr = 0 - n = 1 - - if len(sys.argv) > 1: - argv = [] - - for x in sys.argv: - if x != '--broken-auto-ptr': - argv.append(x) - broken_auto_ptr = argv != sys.argv - sys.argv = argv - - if len(sys.argv) > 1: - n = string.atoi(sys.argv[1]) - - for i in xrange(n): - f(broken_auto_ptr) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py deleted file mode 100644 index 155910a5..00000000 --- a/example/tst_noncopyable.py +++ /dev/null @@ -1,16 +0,0 @@ -def f(): - import noncopyable_export - import noncopyable_import - s1 = noncopyable_export.store(1) - print s1.recall() - s2 = noncopyable_export.store(2) - print s2.recall() - s3 = noncopyable_import.add_stores(s1, s2) - print s3.recall() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/vector_wrapper.h b/example/vector_wrapper.h deleted file mode 100644 index d5bd7215..00000000 --- a/example/vector_wrapper.h +++ /dev/null @@ -1,117 +0,0 @@ -// Based on wrapVector.hh by Mike Owen and Jeff Johnson. -// http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/spheral/src/src/BPLWraps/CXXWraps/ - -#ifndef BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H -#define BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H - -#include - -namespace example { - - // A wrapper is used to define additional constructors. This wrapper - // is templated on the template parameter for its corresponding vector. - template - struct vector_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_wrapper(PyObject*, - const std::vector& vec): - std::vector(vec) {} - - vector_wrapper(PyObject* self): - std::vector() {} - - vector_wrapper(PyObject* self, - std::size_t n): - std::vector(n) {} - - vector_wrapper(PyObject* self, - boost::python::tuple tuple): - std::vector(tuple.size()) - { - std::vector::iterator vec = begin(); - for (std::size_t i = 0; i < tuple.size(); i++) - vec[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - }; - - void raise_vector_IndexError() { - PyErr_SetString(PyExc_IndexError, "vector index out of range"); - throw boost::python::error_already_set(); - } - - template - struct vector_access - { - static - T - getitem(const std::vector& vec, - std::size_t key) - { - if (key >= vec.size()) raise_vector_IndexError(); - return vec[key]; - } - - static - void - setitem(std::vector& vec, - std::size_t key, - const T &value) - { - if (key >= vec.size()) raise_vector_IndexError(); - vec[key] = value; - } - - static - void - delitem(std::vector& vec, - std::size_t key) - { - if (key >= vec.size()) raise_vector_IndexError(); - vec.erase(vec.begin() + key); - } - - // Convert vector to a regular Python tuple. - static - boost::python::tuple - as_tuple(const std::vector& vec) - { - // Create a python type of size vec.size(). - boost::python::tuple t(vec.size()); - for (std::size_t i = 0; i < vec.size(); i++) { - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python(vec[i]))); - } - return t; - } - }; - - // This function will build a vector and add it to the given - // module with the given name. - template - boost::python::class_builder, vector_wrapper > - wrap_vector(boost::python::module_builder& module, - const std::string& vector_name, - const T&) - { - // Add the vector to the module. - boost::python::class_builder, vector_wrapper > - py_vector(module, vector_name.c_str()); - - // Define constructors and methods for the vector. - py_vector.def(boost::python::constructor<>()); - py_vector.def(boost::python::constructor()); - py_vector.def(boost::python::constructor()); - py_vector.def(&std::vector::size, "__len__"); - py_vector.def(&vector_access::getitem, "__getitem__"); - py_vector.def(&vector_access::setitem, "__setitem__"); - py_vector.def(&vector_access::delitem, "__delitem__"); - py_vector.def(&vector_access::as_tuple, "as_tuple"); - - return py_vector; - } -} - -#endif // BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp deleted file mode 100644 index b95a31d5..00000000 --- a/include/boost/python/call.hpp +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_call.py - -#ifndef CALL_DWA20011214_HPP -# define CALL_DWA20011214_HPP - -# include - -namespace boost { namespace python { - -template -inline PyObject* call(R (*f)(), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -// Member functions -template -inline PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - - -}} // namespace boost::python - -#endif // CALL_DWA20011214_HPP - diff --git a/include/boost/python/callback.hpp b/include/boost/python/callback.hpp deleted file mode 100644 index 7240b5b7..00000000 --- a/include/boost/python/callback.hpp +++ /dev/null @@ -1,829 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for 10-argument python callbacks by gen_callback.python - -#ifndef CALLBACK_DWA_052100_H_ -# define CALLBACK_DWA_052100_H_ - -# include -# include - -namespace boost { namespace python { - -namespace detail { - template - inline void callback_adjust_refcount(PyObject*, type) {} - - inline void callback_adjust_refcount(PyObject* p, type) - { Py_INCREF(p); } -} - -// Calling Python from C++ -template -struct callback -{ - static R call_method(PyObject* self, const char* name) - { - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("()"))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - static R call(PyObject* self) - { - ref result(PyEval_CallFunction(self, const_cast("()"))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(O)"), - p1.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallFunction(self, const_cast("(O)"), - p1.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OO)"), - p1.get(), - p2.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallFunction(self, const_cast("(OO)"), - p1.get(), - p2.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallFunction(self, const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } -}; - -// This specialization wouldn't be needed, but MSVC6 doesn't correctly allow the following: -// void g(); -// void f() { return g(); } -template <> -struct callback -{ - - static void call_method(PyObject* self, const char* name) - { - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("()"))); - } - - static void call(PyObject* self) - { - ref result(PyEval_CallFunction(self, const_cast("()"))); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(O)"), - p1.get())); - } - - template - static void call(PyObject* self, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallFunction(self, const_cast("(O)"), - p1.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OO)"), - p1.get(), - p2.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallFunction(self, const_cast("(OO)"), - p1.get(), - p2.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallFunction(self, const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - } -}; - -// Make it a compile-time error to try to return a const char* from a virtual -// function. The standard conversion -// -// from_python(PyObject* string, boost::python::type) -// -// returns a pointer to the character array which is internal to string. The -// problem with trying to do this in a standard callback function is that the -// Python string would likely be destroyed upon return from the calling function -// (boost::python::callback::call[_method]) when its reference count is -// decremented. If you absolutely need to do this and you're sure it's safe (it -// usually isn't), you can use -// -// boost::python::string result(boost::python::callback::call[_method](...args...)); -// ...result.c_str()... // access the char* array -template <> -struct callback -{ - // Try hard to generate a readable error message - typedef struct unsafe_since_python_string_may_be_destroyed {} call, call_method; -}; - -}} // namespace boost::python - -#endif // CALLBACK_DWA_052100_H_ diff --git a/include/boost/python/caller.hpp b/include/boost/python/caller.hpp deleted file mode 100644 index 35b2d618..00000000 --- a/include/boost/python/caller.hpp +++ /dev/null @@ -1,1279 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file generated for 10-argument member functions and 11-argument free -// functions by gen_caller.python - -#ifndef CALLER_DWA05090_H_ -# define CALLER_DWA05090_H_ - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// Calling C++ from Python -template -struct caller -{ - template - static PyObject* call(R (T::*pmf)(), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)()); - } - - template - static PyObject* call(R (T::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()))); - } - - - template - static PyObject* call(R (T::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)()); - } - - template - static PyObject* call(R (T::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()))); - } - - // Free functions - static PyObject* call(R (*f)(), PyObject* args, PyObject* /* keywords */ ) { - if (!PyArg_ParseTuple(args, const_cast(""))) - return 0; - return to_python(f()); - } - - template - static PyObject* call(R (*f)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) - return 0; - return to_python(f(from_python(a1, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - PyObject* a11; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()), - from_python(a11, type()))); - } - -}; - -template <> -struct caller -{ - template - static PyObject* call(void (T::*pmf)(), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type())); - return detail::none(); - } - - - template - static PyObject* call(void (T::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type())); - return detail::none(); - } - - - // Free functions - static PyObject* call(void (*f)(), PyObject* args, PyObject* /* keywords */ ) { - if (!PyArg_ParseTuple(args, const_cast(""))) - return 0; - f(); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) - return 0; - f(from_python(a1, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) - return 0; - f(from_python(a1, type()), - from_python(a2, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - PyObject* a11; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()), - from_python(a11, type())); - return detail::none(); - } - -}; - -}} // namespace boost::python - -#endif diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp deleted file mode 100644 index 0f8d2a69..00000000 --- a/include/boost/python/class.hpp +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_DWA200216_HPP -# define CLASS_DWA200216_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace // put some convenience classes into the unnamed namespace for the user -{ - // A type list for specifying bases - template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) > - struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type - {}; - - // A type list for specifying arguments - template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) > - struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type - {}; -} - -namespace boost { namespace python { - -// Forward declarations -namespace objects -{ - struct value_holder_generator; -} - -namespace detail -{ - // This is an mpl BinaryMetaFunction object with a runtime behavior, - // which is to write the id of the type which is passed as its 2nd - // compile-time argument into the iterator pointed to by its runtime - // argument - struct write_type_id - { - // The first argument is Ignored because mpl::for_each is still - // currently an accumulate (reduce) implementation. - template struct apply - { - // also an artifact of accumulate-based for_each - typedef void type; - - // Here's the runtime behavior - static void execute(converter::undecorated_type_id_t** p) - { - *(*p)++ = converter::undecorated_type_id(); - } - }; - }; -} - -// -// class_ -// -// 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 = mpl::type_list<>::type - , class HolderGenerator = objects::value_holder_generator - > -class class_ : private objects::class_base -{ - typedef class_ 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 - self& def(char const* name, F f) - { - // Use function::add_to_namespace to achieve overloading if - // appropriate. - objects::function::add_to_namespace( - this->object(), name, ref(detail::wrap_function(f))); - return *this; - } - - // Define the constructor with the given Args, which should be an - // MPL sequence of types. - template - self& def_init(Args const& = Args()) - { - def("__init__", make_constructor()); - 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(); - - // Write the rest of the elements into succeeding positions. - class_id* p = ids + 1; - mpl::for_each::execute(&p); - } - - BOOST_STATIC_CONSTANT( - std::size_t, size = mpl::size::value + 1); - class_id ids[size]; - }; - - private: // helper functions - void initialize_converters(); -}; - - -// -// implementations -// -template -inline class_::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 converters(object()); -} - -template -inline class_::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 converters(object()); -} - -template -inline ref class_::object() const -{ - return this->class_base::object(); -} - -}} // namespace boost::python - -#endif // CLASS_DWA200216_HPP diff --git a/include/boost/python/class_builder.hpp b/include/boost/python/class_builder.hpp deleted file mode 100644 index fe2a7b74..00000000 --- a/include/boost/python/class_builder.hpp +++ /dev/null @@ -1,182 +0,0 @@ -// Revision History: -// Mar 03 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) - -#ifndef CLASS_WRAPPER_DWA101000_H_ -# define CLASS_WRAPPER_DWA101000_H_ - -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -// Syntactic sugar to make wrapping classes more convenient -template > -class class_builder - : python_extension_class_converters // Works around MSVC6.x/GCC2.95.2 bug described below -{ - public: - class_builder(module_builder& module, const char* name) - : m_class(new detail::extension_class(name)) - { - module.add(ref(as_object(m_class.get()), ref::increment_count), name); - } - - template - class_builder(class_builder& cls, const char* name) - : m_class(new detail::extension_class(name)) - { - cls.add(ref(as_object(m_class.get()), ref::increment_count), name); - } - - template - class_builder(detail::extension_class* cls, - const char* name) - : m_class(new detail::extension_class(name)) - { - cls->set_attribute(name, - ref(as_object(m_class.get()), ref::increment_count)); - } - - ~class_builder() - {} - - inline void dict_defines_state() { - add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__dict_defines_state__"); - } - inline void getstate_manages_dict() { - add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__getstate_manages_dict__"); - } - - // define constructors - template - void def(const signature& s) - { m_class->def(s); } - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::left_operand()); - template - void def(operators o1, left_operand o2) - { m_class->def(o1, o2); } - - // export heterogeneous operators (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::right_operand()); - template - void def(operators o1, right_operand o2) - { m_class->def(o1, o2); } - - // define a function that passes Python arguments and keywords - // to C++ verbatim (as a 'tuple const &' and 'dictionary const &' - // respectively). This is useful for manual argument passing. - // It's also the only possibility to pass keyword arguments to C++. - // Fn must have a signatur that is compatible to - // PyObject * (*)(PyObject * aTuple, PyObject * aDictionary) - template - void def_raw(Fn fn, const char* name) - { m_class->def_raw(fn, name); } - - // define member functions. In fact this works for free functions, too - - // they act like static member functions, or if they start with the - // appropriate self argument (as a pointer or reference), they can be used - // just like ordinary member functions -- just like Python! - template - void def(Fn fn, const char* name) - { m_class->def(fn, name); } - - // Define a virtual member function with a default implementation. - // default_fn should be a function which provides the default implementation. - // Be careful that default_fn does not in fact call fn virtually! - template - void def(Fn fn, const char* name, DefaultFn default_fn) - { m_class->def(fn, name, default_fn); } - - // Provide a function which implements x., reading from the given - // member (pm) of the T obj - template - void def_getter(MemberType T::*pm, const char* name) - { m_class->def_getter(pm, name); } - - // Provide a function which implements assignment to x., writing to - // the given member (pm) of the T obj - template - void def_setter(MemberType T::*pm, const char* name) - { m_class->def_getter(pm, name); } - - // Expose the given member (pm) of the T obj as a read-only attribute - template - void def_readonly(MemberType T::*pm, const char* name) - { m_class->def_readonly(pm, name); } - - // Expose the given member (pm) of the T obj as a read/write attribute - template - void def_read_write(MemberType T::*pm, const char* name) - { m_class->def_read_write(pm, name); } - - // define the standard coercion needed for operator overloading - void def_standard_coerce() - { m_class->def_standard_coerce(); } - - // declare the given class a base class of this one and register - // conversion functions - template - void declare_base(class_builder const & base) - { - m_class->declare_base(base.get_extension_class()); - } - - // declare the given class a base class of this one and register - // upcast conversion function - template - void declare_base(class_builder const & base, without_downcast_t) - { - m_class->declare_base(base.get_extension_class(), without_downcast); - } - - // get the embedded ExtensioClass object - detail::extension_class * get_extension_class() const - { - return m_class.get(); - } - - // set an arbitrary attribute. Useful for non-function class data members, - // e.g. enums - void add(PyObject* x, const char* name) - { m_class->set_attribute(name, x); } - void add(ref x, const char* name) - { m_class->set_attribute(name, x); } - private: - // declare the given class a base class of this one and register - // conversion functions - template - void declare_base(detail::extension_class * base) - { - m_class->declare_base(base); - } - - // declare the given class a base class of this one and register - // upcast conversion function - template - void declare_base(detail::extension_class * base, without_downcast_t) - { - m_class->declare_base(base, without_downcast); - } - - reference > m_class; -}; - -// The bug mentioned at the top of this file is that on certain compilers static -// global functions declared within the body of a class template will only be -// generated when the class template is constructed, and when (for some reason) -// the construction does not occur via a new-expression. Otherwise, we could -// rely on the initialization of the m_class data member to cause all of the -// to_/from_python functions to come into being. - -}} // namespace boost::python - -#endif // CLASS_WRAPPER_DWA101000_H_ diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp deleted file mode 100644 index 31af430f..00000000 --- a/include/boost/python/classes.hpp +++ /dev/null @@ -1,676 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef SUBCLASS_DWA051500_H_ -# define SUBCLASS_DWA051500_H_ - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// A simple type which acts something like a built-in Python class obj. -class BOOST_PYTHON_DECL instance - : public boost::python::detail::python_object -{ - public: - instance(PyTypeObject* class_); - ~instance(); - - // Standard Python functions. - PyObject* repr(); - int compare(PyObject*); - PyObject* str(); - long hash(); - PyObject* call(PyObject* args, PyObject* keywords); - PyObject* getattr(const char* name, bool use_special_function = true); - int setattr(const char* name, PyObject* value); - - // Mapping methods - int length(); - PyObject* get_subscript(PyObject* key); - void set_subscript(PyObject* key, PyObject* value); - - // Sequence methods - PyObject* get_slice(int start, int finish); - void set_slice(int start, int finish, PyObject* value); - - // Number methods - PyObject* add(PyObject* other); - PyObject* subtract(PyObject* other); - PyObject* multiply(PyObject* other); - PyObject* divide(PyObject* other); - PyObject* remainder(PyObject* other); - PyObject* divmod(PyObject* other); - PyObject* power(PyObject*, PyObject*); - PyObject* negative(); - PyObject* positive(); - PyObject* absolute(); - int nonzero(); - PyObject* invert(); - PyObject* lshift(PyObject* other); - PyObject* rshift(PyObject* other); - PyObject* do_and(PyObject* other); - PyObject* do_xor(PyObject* other); - PyObject* do_or(PyObject* other); - int coerce(PyObject**, PyObject**); - PyObject* as_int(); - PyObject* as_long(); - PyObject* as_float(); - PyObject* oct(); - PyObject* hex(); - - // Rich comparisons - PyObject* lt(PyObject* other); - PyObject* le(PyObject* other); - PyObject* eq(PyObject* other); - PyObject* ne(PyObject* other); - PyObject* gt(PyObject* other); - PyObject* ge(PyObject* other); - - // Inplace operations. - PyObject* inplace_add(PyObject* other); - PyObject* inplace_subtract(PyObject* other); - PyObject* inplace_multiply(PyObject* other); - PyObject* inplace_divide(PyObject* other); - PyObject* inplace_remainder(PyObject* other); - PyObject* inplace_power(PyObject* exponent, PyObject* modulus); - PyObject* inplace_lshift(PyObject* other); - PyObject* inplace_rshift(PyObject* other); - PyObject* inplace_and(PyObject* other); - PyObject* inplace_or(PyObject* other); - PyObject* inplace_xor(PyObject* other); - - private: // noncopyable, without the size bloat - instance(const instance&); - void operator=(const instance&); - - private: // helper functions - int setattr_dict(PyObject* value); - - private: - dictionary m_name_space; -}; - -template class meta_class; - -namespace detail { - class BOOST_PYTHON_DECL class_base : public type_object_base - { - public: - class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space); - tuple bases() const; - string name() const; - dictionary& dict(); - - // Standard Python functions. - PyObject* getattr(const char* name); - int setattr(const char* name, PyObject* value); - PyObject* repr() const; - void add_base(ref base); - - protected: - bool initialize_instance(instance* obj, PyObject* args, PyObject* keywords); - - private: // virtual functions - // Subclasses should override this to delete the particular obj type - virtual void delete_instance(PyObject*) const = 0; - - private: // boost::python::type_object_base required interface implementation - void instance_dealloc(PyObject*) const; // subclasses should not override this - - private: // noncopyable, without the size bloat - class_base(const class_base&); - void operator=(const class_base&); - - private: - string m_name; - tuple m_bases; - dictionary m_name_space; - }; - - void enable_named_method(class_base* type_obj, const char* name); -} - -// A type which acts a lot like a built-in Python class. T is the obj type, -// so class_t is a very simple "class-alike". -template -class BOOST_PYTHON_DECL_TEMPLATE class_t - : public boost::python::detail::class_base -{ - public: - class_t(meta_class* meta_class_obj, string name, tuple bases, const dictionary& name_space); - ~class_t(); - - // Standard Python functions. - PyObject* call(PyObject* args, PyObject* keywords); - - private: // Implement mapping methods on instances - PyObject* instance_repr(PyObject*) const; - int instance_compare(PyObject*, PyObject* other) const; - PyObject* instance_str(PyObject*) const; - long instance_hash(PyObject*) const; - int instance_mapping_length(PyObject*) const; - PyObject* instance_mapping_subscript(PyObject*, PyObject*) const; - int instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const; - - private: // Implement sequence methods on instances - int instance_sequence_length(PyObject*) const; - PyObject* instance_sequence_item(PyObject* obj, int n) const; - int instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const; - PyObject* instance_sequence_slice(PyObject*, int start, int finish) const; - int instance_sequence_ass_slice(PyObject*, int start, int finish, PyObject* value) const; - - private: // Implement number methods on instances - PyObject* instance_number_add(PyObject*, PyObject*) const; - PyObject* instance_number_subtract(PyObject*, PyObject*) const; - PyObject* instance_number_multiply(PyObject*, PyObject*) const; - PyObject* instance_number_divide(PyObject*, PyObject*) const; - PyObject* instance_number_remainder(PyObject*, PyObject*) const; - PyObject* instance_number_divmod(PyObject*, PyObject*) const; - PyObject* instance_number_power(PyObject*, PyObject*, PyObject*) const; - PyObject* instance_number_negative(PyObject*) const; - PyObject* instance_number_positive(PyObject*) const; - PyObject* instance_number_absolute(PyObject*) const; - int instance_number_nonzero(PyObject*) const; - PyObject* instance_number_invert(PyObject*) const; - PyObject* instance_number_lshift(PyObject*, PyObject*) const; - PyObject* instance_number_rshift(PyObject*, PyObject*) const; - PyObject* instance_number_and(PyObject*, PyObject*) const; - PyObject* instance_number_xor(PyObject*, PyObject*) const; - PyObject* instance_number_or(PyObject*, PyObject*) const; - int instance_number_coerce(PyObject*, PyObject**, PyObject**) const; - PyObject* instance_number_int(PyObject*) const; - PyObject* instance_number_long(PyObject*) const; - PyObject* instance_number_float(PyObject*) const; - PyObject* instance_number_oct(PyObject*) const; - PyObject* instance_number_hex(PyObject*) const; - - PyObject* instance_number_inplace_add(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const; - PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_and(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_or(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const; - - private: // Implement rich comparisons - PyObject* instance_lt(PyObject*, PyObject*) const; - PyObject* instance_le(PyObject*, PyObject*) const; - PyObject* instance_eq(PyObject*, PyObject*) const; - PyObject* instance_ne(PyObject*, PyObject*) const; - PyObject* instance_gt(PyObject*, PyObject*) const; - PyObject* instance_ge(PyObject*, PyObject*) const; - - private: // Miscellaneous "special" methods - PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const; - PyObject* instance_getattr(PyObject* obj, const char* name) const; - int instance_setattr(PyObject* obj, const char* name, PyObject* value) const; - - private: // Implementation of boost::python::detail::class_base required interface - void delete_instance(PyObject*) const; -}; - -// The type of a class_t object. -template -class BOOST_PYTHON_DECL_TEMPLATE meta_class - : public boost::python::detail::reprable< - boost::python::detail::callable< - boost::python::detail::getattrable< - boost::python::detail::setattrable< - boost::python::detail::type_object > > > > >, - boost::noncopyable -{ - public: - meta_class(); - - // Standard Python functions. - PyObject* call(PyObject* args, PyObject* keywords); - - struct type_object - : boost::python::detail::singleton > > - { - type_object() : singleton_base(&PyType_Type) {} - }; -}; - -// -// Member function implementations. -// -template -meta_class::meta_class() - : properties(type_object::instance()) -{ -} - -template -class_t::class_t(meta_class* meta_class_obj, string name, tuple bases, const dictionary& name_space) - : boost::python::detail::class_base(meta_class_obj, name, bases, name_space) -{ -} - -template -class_t::~class_t() -{ -} - -template -void class_t::delete_instance(PyObject* obj) const -{ - delete downcast(obj); -} - -template -PyObject* class_t::call(PyObject* args, PyObject* keywords) -{ - reference result(new T(this)); - if (!this->initialize_instance(result.get(), args, keywords)) - return 0; - else - return result.release(); -} - -template -PyObject* class_t::instance_repr(PyObject* obj) const -{ - return downcast(obj)->repr(); -} - -template -int class_t::instance_compare(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->compare(other); -} - -template -PyObject* class_t::instance_str(PyObject* obj) const -{ - return downcast(obj)->str(); -} - -template -long class_t::instance_hash(PyObject* obj) const -{ - return downcast(obj)->hash(); -} - -template -int class_t::instance_mapping_length(PyObject* obj) const -{ - return downcast(obj)->length(); -} - -template -int class_t::instance_sequence_length(PyObject* obj) const -{ - return downcast(obj)->length(); -} - -template -PyObject* class_t::instance_mapping_subscript(PyObject* obj, PyObject* key) const -{ - return downcast(obj)->get_subscript(key); -} - -template -PyObject* class_t::instance_sequence_item(PyObject* obj, int n) const -{ - ref key(to_python(n)); - return downcast(obj)->get_subscript(key.get()); -} - -template -int class_t::instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const -{ - ref key(to_python(n)); - downcast(obj)->set_subscript(key.get(), value); - return 0; -} - -template -int class_t::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyObject* value) const -{ - downcast(obj)->set_subscript(key, value); - return 0; -} - -void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish); - -template -PyObject* class_t::instance_sequence_slice(PyObject* obj, int start, int finish) const -{ - adjust_slice_indices(obj, start, finish); - return downcast(obj)->get_slice(start, finish); -} - -template -int class_t::instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const -{ - adjust_slice_indices(obj, start, finish); - downcast(obj)->set_slice(start, finish, value); - return 0; -} - -template -PyObject* class_t::instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const -{ - return downcast(obj)->call(args, keywords); -} - -template -PyObject* class_t::instance_getattr(PyObject* obj, const char* name) const -{ - return downcast(obj)->getattr(name); -} - - -template -int class_t::instance_setattr(PyObject* obj, const char* name, PyObject* value) const -{ - return downcast(obj)->setattr(name, value); -} - -template -PyObject* class_t::instance_number_add(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->add(other); -} - -template -PyObject* class_t::instance_number_subtract(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->subtract(other); -} - -template -PyObject* class_t::instance_number_multiply(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->multiply(other); -} - -template -PyObject* class_t::instance_number_divide(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->divide(other); -} - -template -PyObject* class_t::instance_number_remainder(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->remainder(other); -} - -template -PyObject* class_t::instance_number_divmod(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->divmod(other); -} - -template -PyObject* class_t::instance_number_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const -{ - return downcast(obj)->power(exponent, modulus); -} - -template -PyObject* class_t::instance_number_negative(PyObject* obj) const -{ - return downcast(obj)->negative(); -} - -template -PyObject* class_t::instance_number_positive(PyObject* obj) const -{ - return downcast(obj)->positive(); -} - -template -PyObject* class_t::instance_number_absolute(PyObject* obj) const -{ - return downcast(obj)->absolute(); -} - -template -int class_t::instance_number_nonzero(PyObject* obj) const -{ - return downcast(obj)->nonzero(); -} - -template -PyObject* class_t::instance_number_invert(PyObject* obj) const -{ - return downcast(obj)->invert(); -} - -template -PyObject* class_t::instance_number_lshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->lshift(other); -} - -template -PyObject* class_t::instance_number_rshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->rshift(other); -} - -template -PyObject* class_t::instance_number_and(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->do_and(other); -} - -template -PyObject* class_t::instance_number_xor(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->do_xor(other); -} - -template -PyObject* class_t::instance_number_or(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->do_or(other); -} - -template -int class_t::instance_number_coerce(PyObject* obj, PyObject** x, PyObject** y) const -{ - return downcast(obj)->coerce(x, y); -} - -template -PyObject* class_t::instance_number_int(PyObject* obj) const -{ - return downcast(obj)->as_int(); -} - -template -PyObject* class_t::instance_number_long(PyObject* obj) const -{ - return downcast(obj)->as_long(); -} - -template -PyObject* class_t::instance_number_float(PyObject* obj) const -{ - return downcast(obj)->as_float(); -} - -template -PyObject* class_t::instance_number_oct(PyObject* obj) const -{ - return downcast(obj)->oct(); -} - -template -PyObject* class_t::instance_number_hex(PyObject* obj) const -{ - return downcast(obj)->hex(); -} - -template -PyObject* class_t::instance_number_inplace_add(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_add(other); -} - -template -PyObject* class_t::instance_number_inplace_subtract(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_subtract(other); -} - -template -PyObject* class_t::instance_number_inplace_multiply(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_multiply(other); -} - -template -PyObject* class_t::instance_number_inplace_divide(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_divide(other); -} - -template -PyObject* class_t::instance_number_inplace_remainder(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_remainder(other); -} - -template -PyObject* class_t::instance_number_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const -{ - return downcast(obj)->inplace_power(exponent, modulus); -} - -template -PyObject* class_t::instance_number_inplace_lshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_lshift(other); -} - -template -PyObject* class_t::instance_number_inplace_rshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_rshift(other); -} - -template -PyObject* class_t::instance_number_inplace_and(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_and(other); -} - -template -PyObject* class_t::instance_number_inplace_or(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_or(other); -} - -template -PyObject* class_t::instance_number_inplace_xor(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_xor(other); -} - -template -PyObject* class_t::instance_lt(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->lt(other); -} - -template -PyObject* class_t::instance_le(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->le(other); -} - -template -PyObject* class_t::instance_eq(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->eq(other); -} - -template -PyObject* class_t::instance_ne(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->ne(other); -} - -template -PyObject* class_t::instance_gt(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->gt(other); -} - -template -PyObject* class_t::instance_ge(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->ge(other); -} - -namespace detail { - inline dictionary& class_base::dict() - { - return m_name_space; - } - - inline tuple class_base::bases() const - { - return m_bases; - } -} - -template -PyObject* meta_class::call(PyObject* args, PyObject* /*keywords*/) -{ - PyObject* name; - PyObject* bases; - PyObject* name_space; - - if (!PyArg_ParseTuple(args, const_cast("O!O!O!"), - &PyString_Type, &name, - &PyTuple_Type, &bases, - &PyDict_Type, &name_space)) - { - return 0; - } - - return as_object( - new class_t(this, string(ref(name, ref::increment_count)), - tuple(ref(bases, ref::increment_count)), - dictionary(ref(name_space, ref::increment_count))) - ); -} - -namespace detail { - const string& setattr_string(); - const string& getattr_string(); - const string& delattr_string(); - - inline string class_base::name() const - { - return m_name; - } -} - - -}} // namespace boost::python -#endif diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp deleted file mode 100644 index aa07547f..00000000 --- a/include/boost/python/conversions.hpp +++ /dev/null @@ -1,416 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 31 Jul 01 convert int/double to complex (Peter Bienstman) -// 04 Mar 01 Fixed std::complex<> stuff to work with MSVC (David Abrahams) -// 03 Mar 01 added: converters for [plain] char and std::complex -// (Ralf W. Grosse-Kunstleve) - -#ifndef METHOD_DWA122899_H_ -# define METHOD_DWA122899_H_ - -# include -# include -# include -# include -# include -# include -# include - -# ifdef BOOST_MSVC6_OR_EARLIER -# pragma warning(push) -# pragma warning(disable:4275) // disable a bogus warning caused by -# endif - -# include - -# ifdef BOOST_MSVC6_OR_EARLIER -# pragma warning(pop) -# endif - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround - -// This can be instantiated on an enum to provide the to_python/from_python -// conversions, provided the values can fit in a long. -template -class py_enum_as_int_converters -{ - friend EnumType from_python(PyObject* x, boost::python::type) - { - return static_cast( - from_python(x, boost::python::type())); - } - - friend EnumType from_python(PyObject* x, boost::python::type) - { - return static_cast( - from_python(x, boost::python::type())); - } - - friend PyObject* to_python(EnumType x) - { - return to_python(static_cast(x)); - } -}; -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { -template class enum_as_int_converters - : public BOOST_PYTHON_CONVERSION::py_enum_as_int_converters {}; - -template class wrapped_pointer; - -//#pragma warn_possunwant off -inline void decref_impl(PyObject* p) { Py_DECREF(p); } -inline void xdecref_impl(PyObject* p) { Py_XDECREF(p); } -//#pragma warn_possunwant reset - -template -inline void decref(T* p) -{ - char* const raw_p = reinterpret_cast(p); - char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); - decref_impl(reinterpret_cast(p_base)); -} - -template -inline void xdecref(T* p) -{ - char* const raw_p = reinterpret_cast(p); - char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); - xdecref_impl(reinterpret_cast(p_base)); -} - -namespace detail { - - void expect_complex(PyObject*); - - template - std::complex complex_from_python(PyObject* p, boost::python::type) - { - if (PyInt_Check(p)) return std::complex(PyInt_AS_LONG(p)); - if (PyLong_Check(p)) return std::complex(PyLong_AsDouble(p)); - if (PyFloat_Check(p)) return std::complex(PyFloat_AS_DOUBLE(p)); - - expect_complex(p); - - return std::complex( - static_cast(PyComplex_RealAsDouble(p)), - static_cast(PyComplex_ImagAsDouble(p))); - } - - template - PyObject* complex_to_python(const std::complex& sc) { - Py_complex pcc; - pcc.real = sc.real(); - pcc.imag = sc.imag(); - return PyComplex_FromCComplex(pcc); - } - -} - -}} // namespace boost::python - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -// -// Converters -// -PyObject* to_python(long); -BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type); -long from_python(PyObject* p, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned long); -BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type); -unsigned long from_python(PyObject* p, boost::python::type); - -PyObject* to_python(int); -BOOST_PYTHON_DECL int from_python(PyObject*, boost::python::type); -int from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned int); -BOOST_PYTHON_DECL unsigned int from_python(PyObject*, boost::python::type); -unsigned int from_python(PyObject*, boost::python::type); - -PyObject* to_python(short); -BOOST_PYTHON_DECL short from_python(PyObject*, boost::python::type); -short from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned short); -BOOST_PYTHON_DECL unsigned short from_python(PyObject*, boost::python::type); -unsigned short from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(char); -BOOST_PYTHON_DECL char from_python(PyObject*, boost::python::type); -char from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(signed char); -BOOST_PYTHON_DECL signed char from_python(PyObject*, boost::python::type); -signed char from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned char); -BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type); -unsigned char from_python(PyObject*, boost::python::type); - -# ifndef BOOST_MSVC6_OR_EARLIER -PyObject* to_python(float); -float from_python(PyObject*, boost::python::type); -PyObject* to_python(double); -double from_python(PyObject*, boost::python::type); -# else -BOOST_PYTHON_DECL PyObject* to_python(float); -BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type); -BOOST_PYTHON_DECL PyObject* to_python(double); -BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type); -# endif -float from_python(PyObject*, boost::python::type); - -double from_python(PyObject*, boost::python::type); - -PyObject* to_python(bool); -BOOST_PYTHON_DECL bool from_python(PyObject*, boost::python::type); -bool from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(void); -BOOST_PYTHON_DECL void from_python(PyObject*, boost::python::type); - -PyObject* to_python(const char* s); -BOOST_PYTHON_DECL const char* from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(const std::string& s); -BOOST_PYTHON_DECL std::string from_python(PyObject*, boost::python::type); -std::string from_python(PyObject*, boost::python::type); - -inline PyObject* to_python(const std::complex& x) -{ - return boost::python::detail::complex_to_python(x); -} - -inline PyObject* to_python(const std::complex& x) -{ - return boost::python::detail::complex_to_python(x); -} - -inline std::complex from_python(PyObject* p, - boost::python::type >) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -inline std::complex from_python(PyObject* p, - boost::python::type&>) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -inline std::complex from_python(PyObject* p, - boost::python::type >) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -inline std::complex from_python(PyObject* p, - boost::python::type&>) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -// For when your C++ function really wants to pass/return a PyObject* -PyObject* to_python(PyObject*); -PyObject* from_python(PyObject*, boost::python::type); - -// Some standard conversions to/from smart pointer types. You can add your own -// from these examples. These are not generated using the friend technique from -// wrapped_pointer because: -// -// 1. We want to be able to extend conversion to/from WrappedPointers using -// arbitrary smart pointer types. -// -// 2. It helps with compilation independence. This way, code which creates -// wrappers for functions accepting and returning smart_ptr does not -// have to have already seen the invocation of wrapped_type. -// - -// Unfortunately, MSVC6 is so incredibly lame that we have to rely on the friend -// technique to auto_generate standard pointer conversions for wrapped -// types. This means that you need to write a non-templated function for each -// specific smart_ptr which you want to convert from_python. For example, -// -// namespace boost { namespace python { -// #ifdef MUST_SUPPORT_MSVC -// -// MyPtr from_python(PyObject*p, type >) -// { return smart_ptr_from_python(p, type >(), type());} -// } -// -// MyPtr from_python(PyObject*p, type >) -// { return smart_ptr_from_python(p, type >(), type());} -// -// ... // definitions for MyPtr, MyPtr, etc. -// -// #else -// -// // Just once for all MyPtr -// template -// MyPtr from_python(PyObject*p, type >) -// { -// return smart_ptr_from_python(p, type >(), type()); -// } -// -// #endif -// }} // namespace boost::python - -#if !defined(BOOST_MSVC6_OR_EARLIER) -template -boost::shared_ptr from_python(PyObject*p, boost::python::type >) -{ - return smart_ptr_from_python(p, boost::python::type >(), boost::python::type()); -} -#endif - -#if 0 -template -PyObject* to_python(std::auto_ptr p) -{ - return new boost::python::wrapped_pointer, T>(p); -} - -template -PyObject* to_python(boost::shared_ptr p) -{ - return new boost::python::wrapped_pointer, T>(p); -} -#endif - -// -// inline implementations -// - -#ifndef BOOST_MSVC6_OR_EARLIER -inline PyObject* to_python(double d) -{ - return PyFloat_FromDouble(d); -} - -inline PyObject* to_python(float f) -{ - return PyFloat_FromDouble(f); -} -#endif // BOOST_MSVC6_OR_EARLIER - -inline PyObject* to_python(long l) -{ - return PyInt_FromLong(l); -} - -inline PyObject* to_python(int x) -{ - return PyInt_FromLong(x); -} - -inline PyObject* to_python(short x) -{ - return PyInt_FromLong(x); -} - -inline PyObject* to_python(bool b) -{ - return PyInt_FromLong(b); -} - -inline PyObject* to_python(void) -{ - return boost::python::detail::none(); -} - -inline PyObject* to_python(const char* s) -{ - return PyString_FromString(s); -} - -inline std::string from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline PyObject* to_python(PyObject* p) -{ - Py_INCREF(p); - return p; -} - -inline PyObject* from_python(PyObject* p, boost::python::type) -{ - return p; -} - -inline const char* from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline double from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline float from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline int from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline short from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline long from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline bool from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned int from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned short from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline char from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline signed char from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned char from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned long from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -#endif // METHOD_DWA122899_H_ diff --git a/include/boost/python/converter/body.hpp b/include/boost/python/converter/body.hpp deleted file mode 100644 index d9170839..00000000 --- a/include/boost/python/converter/body.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BODY_DWA2001127_HPP -# define BODY_DWA2001127_HPP -# include -# include - -namespace boost { namespace python { namespace converter { - -namespace registry -{ - class entry; -} - -struct BOOST_PYTHON_DECL body -{ - public: - body(type_id_t key); - virtual ~body() {} - - type_id_t key() const; - - protected: - // true iff the registry is still alive - bool can_unregister() const; - - private: - // called when the registry is destroyed, to prevent it from being - // unregistered. - void do_not_unregister(); - friend class registry::entry; - - private: - type_id_t m_key; - bool m_can_unregister; -}; - -// -// implementations -// -inline body::body(type_id_t key) - : m_key(key) - , m_can_unregister(true) -{ -} - -inline type_id_t body::key() const -{ - return m_key; -} - -inline bool body::can_unregister() const -{ - return m_can_unregister; -} - -}}} // namespace boost::python::converter - -#endif // BODY_DWA2001127_HPP diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp deleted file mode 100644 index 9c19cbc5..00000000 --- a/include/boost/python/converter/builtin_converters.hpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP -# define BUILTIN_CONVERTERS_DWA2002124_HPP - -namespace boost { namespace python { namespace converter { - -void initialize_builtin_converters(); - -}}} // namespace boost::python::converter - -#endif // BUILTIN_CONVERTERS_DWA2002124_HPP diff --git a/include/boost/python/converter/builtin_to_python_converters.hpp b/include/boost/python/converter/builtin_to_python_converters.hpp deleted file mode 100644 index 89ad7b86..00000000 --- a/include/boost/python/converter/builtin_to_python_converters.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP -# define BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP -# include -# include - -namespace boost { namespace python { - -// Provide specializations of to_python_value -template struct to_python_value; - -namespace detail -{ - struct builtin_to_python - { - static bool convertible() { return true; } - }; -} - -# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; - - -# define BOOST_PYTHON_TO_INT(T) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x)) - -BOOST_PYTHON_TO_INT(char) -BOOST_PYTHON_TO_INT(short) -BOOST_PYTHON_TO_INT(int) -BOOST_PYTHON_TO_INT(long) -# undef BOOST_TO_PYTHON_INT - -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x) - -}} // namespace boost::python::converter - -#endif // BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp deleted file mode 100644 index 67de6fad..00000000 --- a/include/boost/python/converter/class.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_DWA20011215_HPP -# define CLASS_DWA20011215_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -template -struct class_from_python_converter -{ - class_from_python_converter(); - - static void* convertible(PyObject*); - static T& convert_ref(PyObject*, from_python_data&); - static T const& convert_cref(PyObject*, from_python_data&); - static T* convert_ptr(PyObject*, from_python_data&); - static T const* convert_cptr(PyObject*, from_python_data&); - - from_python_converter to_ref; - from_python_converter to_cref; - from_python_converter to_ptr; - from_python_converter to_cptr; -}; - -// -// implementations -// -template -class_from_python_converter::class_from_python_converter() - : to_ref(convertible, convert_ref) - , to_cref(convertible, convert_cref) - , to_ptr(convertible, convert_ptr) - , to_cptr(convertible, convert_cptr) -{} - -template -T& class_from_python_converter::convert_ref(PyObject*, from_python_data& x) -{ - return *static_cast(x.stage1); -} - -template -T const& class_from_python_converter::convert_cref(PyObject*, from_python_data& x) -{ - return *static_cast(x.stage1); -} - - -template -T* class_from_python_converter::convert_ptr(PyObject*, from_python_data& x) -{ - return static_cast(x.stage1); -} - -template -T const* class_from_python_converter::convert_cptr(PyObject*, from_python_data& x) -{ - return static_cast(x.stage1); -} - -template -void* class_from_python_converter::convertible(PyObject* p) -{ - return objects::find_instance(p); -} - -}}} // namespace boost::python::converter - -#endif // CLASS_DWA20011215_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp deleted file mode 100644 index ee16a741..00000000 --- a/include/boost/python/converter/from_python.hpp +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_DWA2002127_HPP -# define FROM_PYTHON_DWA2002127_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// The type of convertibility checking functions -typedef void* (*from_python_check)(PyObject*); -typedef void (*from_python_destructor)(from_python_data&); - -// forward declaration -template struct from_python_lookup; - -// from_python -- -// A body class representing a conversion from python to C++. - -struct BOOST_PYTHON_DECL from_python_converter_base : body -{ - from_python_converter_base(type_id_t, from_python_check); // registers - - // Must return non-null iff the conversion will be successful. Any - // non-null pointer is acceptable, and will be passed on to the - // convert() function, so useful data can be stored there. - inline void* convertible(PyObject*) const; - - // Given the head of a from_python converter chain, find the - // converter which can convert p, leaving its intermediate data in - // data. - inline static from_python_converter_base const* - find(from_python_converter_base const*chain, PyObject* p, void*& data); - - private: - from_python_check m_convertible; - from_python_converter_base* m_next; -}; - - -template -struct from_python_converter : from_python_converter_base -{ - public: // types - typedef typename from_python_function::type conversion_function; - - public: // member functions - from_python_converter(from_python_check, conversion_function, from_python_destructor = 0); - T convert(PyObject*, from_python_data&) const; - void destroy(from_python_data&) const; - - // Find a converter for converting p to a T. - static from_python_converter const* find(PyObject* p, void*& data); - - private: // data members - conversion_function m_convert; - from_python_destructor m_destroy; - - // Keeps the chain of converters which convert from PyObject* to T - static from_python_converter_base*const& chain; -}; - -// Initialized to refer to a common place in the registry. -template -from_python_converter_base*const& -from_python_converter::chain = registry::from_python_chain(type_id()); - -// ------------------------------------------------------------------------- - -// A class which implements from_python with a registry lookup. -template -struct from_python_lookup // : from_python_base -{ - public: // types - - public: // member functions - from_python_lookup(PyObject* source); - ~from_python_lookup(); - - bool convertible() const; - T operator()(PyObject*); - - public: // functions for use by conversion implementations - // Get the converter object - from_python_converter const* converter() const; - - private: // data members - typedef typename from_python_intermediate_data::type intermediate_t; - mutable intermediate_t m_intermediate_data; - from_python_converter const* m_converter; -}; - -// -// implementations -// -inline void* from_python_converter_base::convertible(PyObject* o) const -{ - return m_convertible(o); -} - -inline from_python_converter_base const* -from_python_converter_base::find( - from_python_converter_base const* chain, PyObject* p, void*& data) -{ - for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next) - { - void* d = q->convertible(p); - if (d != 0) - { - data = d; - return q; - } - } - return 0; -} - -template -inline from_python_converter::from_python_converter( - from_python_check checker - , conversion_function converter - , from_python_destructor destructor // = 0 - ) - : from_python_converter_base(type_id(), checker) - , m_convert(converter) - , m_destroy(destructor) -{ - -} - -template -inline from_python_converter const* -from_python_converter::find(PyObject* p, void*& data) -{ - return static_cast const*>( - from_python_converter_base::find(chain, p, data)); -} - -template -inline T from_python_converter::convert(PyObject* src, from_python_data& data) const -{ - return this->m_convert(src, data); -} - -template -inline void from_python_converter::destroy(from_python_data& data) const -{ - if (this->m_destroy) - { - this->m_destroy(data); - } -} - -template -inline from_python_lookup::from_python_lookup(PyObject* src) - : m_converter( - from_python_converter::find( - src, m_intermediate_data.stage1)) -{ -} - -template -inline from_python_lookup::~from_python_lookup() -{ - if (m_converter != 0) - m_converter->destroy(m_intermediate_data); -} - -template -inline bool from_python_lookup::convertible() const -{ - return this->m_converter != 0; -} - -template -inline T from_python_lookup::operator()(PyObject* obj) -{ - return this->m_converter->convert(obj, m_intermediate_data); -} - -template -inline from_python_converter const* -from_python_lookup::converter() const -{ - return this->m_converter; -} - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp deleted file mode 100644 index 3edcbad7..00000000 --- a/include/boost/python/converter/from_python_data.hpp +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP -# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP - -# include -# include -# include -# include - -// Keep these for the metaprogram which EDG is choking on. -# if !defined(__EDG__) || (__EDG_VERSION__ > 245) -# include -# include -# include -# include -# endif - -namespace boost { namespace python { namespace converter { - -// A POD which is layout-compatible with the real intermediate data -// for all from_python conversions. There may be additional storage if -// we are converting a reference type. -struct from_python_data -{ - void* stage1; -}; - -namespace detail -{ - template struct referent_alignment; - template struct referent_size; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct referent_alignment - { - BOOST_STATIC_CONSTANT( - std::size_t, value = alignment_of::value); - }; - - template - struct referent_size - { - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(T)); - }; - -# else - - template - struct alignment_chars - { - BOOST_STATIC_CONSTANT( - std::size_T, n = alignment_of::value); - char elements[n + 1]; - }; - - template struct referent_alignment - { - template - static alignment_chars helper(U&); - - static T t; - - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(helper(t).elements) - 1); - }; - - - template struct referent_size - { - static T t; - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t)); - }; - -# endif - - struct unknown_alignment - { - void* p; - }; - -// EDG is too slow to handle this metaprogram :( -#if !defined(__EDG__) || (__EDG_VERSION__ > 245) - struct alignment_dummy; - - template - struct best_alignment_type - { - template - struct apply - { - BOOST_STATIC_CONSTANT( - std::size_t, align1 = alignment_of::value); - - BOOST_STATIC_CONSTANT( - std::size_t, align2 = alignment_of::value); - - BOOST_STATIC_CONSTANT( - bool, aligned2 = ( - (align2 >= target_alignment) - & (align2 % target_alignment == 0)) - ); - - BOOST_STATIC_CONSTANT( - bool, choose_t2 = ( - aligned2 && ( - is_same::value - | (align2 < alignment_of::value) - | (sizeof(T2) < sizeof(T1))) - )); - - typedef mpl::select_type::type type; - }; - }; - - typedef mpl::type_list< - char,short,int,long,float,double,long double - ,void* - ,void(*)() - ,void (alignment_dummy::*)() - , char (alignment_dummy::*) - > - align_types; -#endif // EDG is too slow - - template - struct aligned_storage - { - typedef Align align_t; - union - { - Align align; - char bytes[size - // this is just a STATIC_ASSERT. For some reason - // MSVC was barfing on the boost one. - - (is_same::value ? size : 0)]; - }; - }; - - template - 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::value> - > loop; - typedef typename loop::state align_t; -#else - // The Python source makes the assumption that double has - // maximal alignment anyway - typedef double align_t; -#endif - - typedef aligned_storage::value> type; - }; - - template - struct intermediate_data : from_python_data - { - typename referent_storage::type stage2; - }; - - template <> - struct intermediate_data : from_python_data - { - }; - -} - -// ------------------------------------------------------------------------- -// Auxiliary POD storage where the convertible and/or convert functions of a -// from_python object may place arbitrary data. -// -// Always starts with a void* -// -// For references, we produce additional aligned storage sufficient to -// store the referent - -template -struct from_python_intermediate_data -{ - typedef typename mpl::select_type< - is_reference::value, T, void>::type just_reference_t; - - typedef detail::intermediate_data type; -}; - -template -void* get_storage(from_python_data& x, boost::type* = 0) -{ - typedef typename from_python_intermediate_data::type layout; - return static_cast(&x)->stage2.bytes; -} - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/converter/from_python_function.hpp b/include/boost/python/converter/from_python_function.hpp deleted file mode 100644 index 0cf90459..00000000 --- a/include/boost/python/converter/from_python_function.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_FUNCTION_DWA2002128_HPP -# define FROM_PYTHON_FUNCTION_DWA2002128_HPP - -# include - -namespace boost { namespace python { namespace converter { - -struct from_python_data; - -template -struct from_python_function -{ - typedef T (*type)(PyObject*, from_python_data&); -}; - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_FUNCTION_DWA2002128_HPP diff --git a/include/boost/python/converter/handle.hpp b/include/boost/python/converter/handle.hpp deleted file mode 100644 index bc06be38..00000000 --- a/include/boost/python/converter/handle.hpp +++ /dev/null @@ -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 -# include -# include - -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 diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp deleted file mode 100644 index bdb64254..00000000 --- a/include/boost/python/converter/registry.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REGISTRY_DWA20011127_HPP -# define REGISTRY_DWA20011127_HPP -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct BOOST_PYTHON_DECL from_python_converter_base; - -// This namespace acts as a sort of singleton -namespace registry -{ - BOOST_PYTHON_DECL to_python_value_function const& - to_python_function(undecorated_type_id_t); - - BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t); - - BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t); - - BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key); -} - -}}} // namespace boost::python::converter - -#endif // REGISTRY_DWA20011127_HPP diff --git a/include/boost/python/converter/smart_ptr.hpp b/include/boost/python/converter/smart_ptr.hpp deleted file mode 100644 index bae4c2b8..00000000 --- a/include/boost/python/converter/smart_ptr.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SMART_PTR_DWA2002123_HPP -# define SMART_PTR_DWA2002123_HPP - -# include -# include -namespace boost { namespace python { namespace converter { - -template -class smart_ptr_wrapper - : wrapper -{ - smart_ptr_wrapper(ref const& type_) - : m_class_object(type_) - { - assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); - } - - PyObject* convert(Pointer x) const; - - private: - ref m_class_object; - - smart_ptr_converters(); -} - - -// -// implementations -// - -template -PyObject* smart_ptr_wrapper::convert(Pointer x) const -{ - if (x.operator->() == 0) - return detail::none(); - - // Don't call the type to do the construction, since that - // would require the registration of an __init__ copy - // constructor. Instead, just construct the object in place. - PyObject* raw_result = (PyObject*)PyObject_New( - instance, (PyTypeObject*)m_class_object.get()); - - if (raw_result == 0) - return 0; - - // Everything's OK; Bypass NULL checks but guard against - // exceptions. - ref result(raw_result, ref::allow_null()); - - // Build a value_holder to contain the object using the copy - // constructor - objects::pointer_holder* - p = new objects::pointer_holder(x); - - // Install it in the instance - p->install(raw_result); - - // Return the new result - return result.release(); -} - - -}}} // namespace boost::python::converter - -#endif // SMART_PTR_DWA2002123_HPP diff --git a/include/boost/python/converter/target.hpp b/include/boost/python/converter/target.hpp deleted file mode 100644 index f8f33171..00000000 --- a/include/boost/python/converter/target.hpp +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#ifndef TARGET_DWA20011119_HPP -# define TARGET_DWA20011119_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// target -- -// -// This type generator (see -// ../../../more/generic_programming.html#type_generator) is used -// to select the return type of the appropriate converter for -// unwrapping a given type. - -// Strategy: -// -// 1. reduce everything to a common, un-cv-qualified reference -// type where possible. This will save on registering many different -// converter types. -// -// 2. Treat built-in types specially: when unwrapping a value or -// constant reference to one of these, use a value for the target -// type. It will bind to a const reference if neccessary, and more -// importantly, avoids having to dynamically allocate room for -// an lvalue of types which can be cheaply copied. -// - -// Target Source -// int int -// int const& int -// int& int& -// int volatile& int volatile& -// int const volatile& int const volatile& - -// On compilers supporting partial specialization: -// -// Target Source -// T T const& -// T& T& -// T const& T const& -// T volatile T& -// T const volatile& T const& -// T* T* -// T const* T const* -// T volatile T* -// T const volatile* T const* -// T cv*const& same as T cv* -// T cv*& T*& <- should this be legal? -// T cv*volatile& T*& <- should this be legal? -// T cv*const volatile& T*& <- should this be legal? - -// On others: -// -// Target Source -// T T& -// T cv& T cv& -// T cv* T cv* -// T cv*cv& T cv*cv& - -// As you can see, in order to handle the same range of types without -// partial specialization, more converters need to be registered. - -template -struct target -{ - // Some pointer types are handled in a more sophisticated way on - // compilers supporting partial specialization. - BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_scalar::value)); - - typedef typename mpl::select_type< - use_identity - , T - , typename add_reference< - typename add_const< - typename remove_volatile::type - >::type - >::type - >::type type; -}; - -// When partial specialization is not present, we'll simply need to -// register many more converters. -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -template -struct target -{ - typedef typename remove_volatile::type& type; -}; - -template -struct target -{ - typedef typename boost::mpl::select_type< - is_scalar::value - , typename remove_cv::type - , typename remove_volatile::type const& - >::type type; -}; - -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -// Handle T*-cv for completeness. Function arguments in a signature -// are never actually cv-qualified, but who knows how these converters -// might be used, or whether compiler bugs lurk which make it seem -// otherwise? -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -// non-const references to pointers should be handled by the -// specialization for T&, above. -template -struct target -{ - typedef typename remove_volatile::type* type; -}; -# endif - -// Fortunately, we can handle T const& where T is an arithmetic type -// by explicit specialization. These specializations will cause value -// and const& arguments to be converted to values, rather than to -// references. -# define BOOST_PYTHON_UNWRAP_VALUE(T) \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -} - -BOOST_PYTHON_UNWRAP_VALUE(char); -BOOST_PYTHON_UNWRAP_VALUE(unsigned char); -BOOST_PYTHON_UNWRAP_VALUE(signed char); -BOOST_PYTHON_UNWRAP_VALUE(unsigned int); -BOOST_PYTHON_UNWRAP_VALUE(signed int); -BOOST_PYTHON_UNWRAP_VALUE(unsigned short); -BOOST_PYTHON_UNWRAP_VALUE(signed short); -BOOST_PYTHON_UNWRAP_VALUE(unsigned long); -BOOST_PYTHON_UNWRAP_VALUE(signed long); -BOOST_PYTHON_UNWRAP_VALUE(char const*); - -}}} // namespace boost::python::converter - -#endif // TARGET_DWA20011119_HPP diff --git a/include/boost/python/converter/to_python_function.hpp b/include/boost/python/converter/to_python_function.hpp deleted file mode 100644 index a438ce0c..00000000 --- a/include/boost/python/converter/to_python_function.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_FUNCTION_DWA2002128_HPP -# define TO_PYTHON_FUNCTION_DWA2002128_HPP - -# include -# include - -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 -struct as_to_python_value_function -{ - static PyObject* convert(void const* x) - { - return ToPython::convert(*(T const*)x); - } -}; - -}}} // namespace boost::python::converter - -#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp deleted file mode 100644 index 015e55e9..00000000 --- a/include/boost/python/converter/type_id.hpp +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TYPE_ID_DWA20011127_HPP -# define TYPE_ID_DWA20011127_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - - -namespace boost { namespace python { namespace converter { - -// for this compiler at least, cross-shared-library type_info -// comparisons don't work, so use typeid(x).name() instead. It's not -// yet clear what the best default strategy is. -# if defined(__GNUC__) && __GNUC__ >= 3 -# define BOOST_PYTHON_TYPE_ID_NAME -# endif - -// type ids which represent the same information as std::type_info -// (i.e. the top-level reference and cv-qualifiers are stripped), but -// which works across shared libraries. -struct undecorated_type_id_t : totally_ordered -{ - undecorated_type_id_t(std::type_info const&); - - // default constructor needed to build arrays, etc. - undecorated_type_id_t(); - - bool operator<(undecorated_type_id_t const& rhs) const; - bool operator==(undecorated_type_id_t const& rhs) const; - - char const* name() const; - friend BOOST_PYTHON_DECL std::ostream& operator<<( - std::ostream&, undecorated_type_id_t const&); - - private: // data members -# ifdef BOOST_PYTHON_TYPE_ID_NAME - typedef char const* base_id_t; -# else - typedef std::type_info const* base_id_t; -# endif - - base_id_t m_base_type; -}; - -struct type_id_t : totally_ordered -{ - enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; - - type_id_t(undecorated_type_id_t, decoration = decoration()); - - bool operator<(type_id_t const& rhs) const; - bool operator==(type_id_t const& rhs) const; - - friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); - - operator undecorated_type_id_t const&() const; - private: // type - typedef undecorated_type_id_t base_id_t; - - private: // data members - decoration m_decoration; - base_id_t m_base_type; -}; - -template -inline undecorated_type_id_t undecorated_type_id(boost::type* = 0) -{ - return undecorated_type_id_t( -# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) - typeid(T) -# else // strip the decoration which msvc and Intel mistakenly leave in - python::detail::msvc_typeid() -# endif - ); -} - -template -inline type_id_t type_id(boost::type* = 0) -{ - return type_id_t( - undecorated_type_id() - , type_id_t::decoration( - (is_const::value || python::detail::is_reference_to_const::value - ? type_id_t::const_ : 0) - | (is_volatile::value || python::detail::is_reference_to_volatile::value - ? type_id_t::volatile_ : 0) - | (is_reference::value ? type_id_t::reference : 0) - ) - ); -} - -inline undecorated_type_id_t::undecorated_type_id_t(std::type_info const& id) - : m_base_type( -# ifdef BOOST_PYTHON_TYPE_ID_NAME - id.name() -# else - &id -# endif - ) -{ -} - -inline undecorated_type_id_t::undecorated_type_id_t() - : m_base_type() -{ -} - -inline type_id_t::type_id_t(undecorated_type_id_t base_t, decoration decoration) - : m_decoration(decoration) - , m_base_type(base_t) -{ -} - -inline bool undecorated_type_id_t::operator<(undecorated_type_id_t const& rhs) const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return std::strcmp(m_base_type, rhs.m_base_type) < 0; -# else - return m_base_type->before(*rhs.m_base_type); -# endif -} - -inline bool type_id_t::operator<(type_id_t const& rhs) const -{ - return m_decoration < rhs.m_decoration - || m_decoration == rhs.m_decoration - && m_base_type < rhs.m_base_type; -} - -inline bool undecorated_type_id_t::operator==(undecorated_type_id_t const& rhs) const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return !std::strcmp(m_base_type, rhs.m_base_type); -# else - return *m_base_type == *rhs.m_base_type; -# endif -} - -inline bool type_id_t::operator==(type_id_t const& rhs) const -{ - return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; -} - -inline type_id_t::operator undecorated_type_id_t const&() const -{ - return m_base_type; -} - -inline char const* undecorated_type_id_t::name() const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return m_base_type; -# else - return m_base_type->name(); -# endif -} - - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, undecorated_type_id_t const&); -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); - -}}} // namespace boost::python::converter - -#endif // TYPE_ID_DWA20011127_HPP diff --git a/include/boost/python/converter/unwrapper_base.hpp b/include/boost/python/converter/unwrapper_base.hpp deleted file mode 100644 index ea437eb2..00000000 --- a/include/boost/python/converter/unwrapper_base.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef UNWRAPPER_BASE_DWA20011215_HPP -# define UNWRAPPER_BASE_DWA20011215_HPP -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct BOOST_PYTHON_DECL unwrapper_base : body -{ - public: - unwrapper_base(type_id_t); // registers - ~unwrapper_base(); // unregisters - - // Must return non-null iff the conversion will be successful. Any - // non-null pointer is acceptable, and will be passed on to the - // convert() function, so useful data can be stored there. - virtual void* can_convert(PyObject*) const = 0; - - protected: - // this is an arbitrary non-null pointer you can use to indicate success - static void* const non_null; - - private: // body required interface implementation - void destroy_handle(handle*) const {} -}; - -}}} // namespace boost::python::converter - -#endif // UNWRAPPER_BASE_DWA20011215_HPP diff --git a/include/boost/python/converter/unwrapper_select.hpp b/include/boost/python/converter/unwrapper_select.hpp deleted file mode 100644 index d60923af..00000000 --- a/include/boost/python/converter/unwrapper_select.hpp +++ /dev/null @@ -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 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 -struct unwrapper_select -{ - typedef unwrapper type; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct unwrapper_select -{ - typedef unwrapper type; -}; -# endif - -}}} // namespace boost::python::converter - -#endif // UNWRAPPER_SELECT_DWA20011229_HPP diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp deleted file mode 100644 index f5ca315d..00000000 --- a/include/boost/python/cross_module.hpp +++ /dev/null @@ -1,327 +0,0 @@ -/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, use, - modify, sell and distribute this software is granted provided this - copyright notice appears in all copies. This software is provided - "as is" without express or implied warranty, and with no claim as to - its suitability for any purpose. - - Revision History: - 17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve) -*/ - -/* Implementation of Boost.Python cross-module support. - See root/libs/python/doc/cross_module.html for details. -*/ - -#ifndef CROSS_MODULE_HPP -# define CROSS_MODULE_HPP - -# include - -namespace boost { namespace python { - struct BOOST_PYTHON_DECL import_error: error_already_set {}; - struct BOOST_PYTHON_DECL export_error : error_already_set {}; - -namespace detail -{ - -// Concept: throw exception if api_major is changed -// show warning on stderr if api_minor is changed - const int export_converters_api_major = 4; - const int export_converters_api_minor = 1; - extern BOOST_PYTHON_DECL const char* converters_attribute_name; - BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name); - BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor); - -} - -}} // namespace boost::python - -// forward declaration -namespace boost { namespace python { namespace detail { -template class import_extension_class; -}}} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -/* This class template is instantiated by import_converters. - This class is a look-alike of class python_extension_class_converters. - The converters in this class are wrappers that call converters - imported from another module. - To ensure that the dynamic loader resolves all symbols in the - intended way, the signature of all friend functions is changed with - respect to the original functions in class - python_extension_class_converters by adding an arbitrary additional - parameter with a default value, in this case "bool sig = false". - See also: comments for class export_converter_object_base below. - */ -template -class python_import_extension_class_converters -{ - public: - - friend python_import_extension_class_converters py_extension_class_converters(boost::python::type, bool sig = false) { - return python_import_extension_class_converters(); - } - - PyObject* to_python(const T& x) const { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_Ts(p, t); - } - friend const T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_cTs(p, t); - } - friend const T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_cTscr(p, t); - } - friend T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_Tscr(p, t); - } - friend T& from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_Tr(p, t); - } - friend const T& from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_cTr(p, t); - } - friend const T& from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_T(p, t); - } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_aTr(p, t); - } - friend std::auto_ptr from_python(PyObject* p, boost::python::type > t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_aT(p, t); - } - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_caTr(p, t); - } - friend PyObject* to_python(std::auto_ptr x, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_sTr(p, t); - } - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type > t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_sT(p, t); - } - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_csTr(p, t); - } - friend PyObject* to_python(boost::shared_ptr x, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } -}; - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); - -/* This class template is instantiated by export_converters(). - A pointer to this class is exported/imported via the Python API. - Using the Python API ensures maximum portability. - All member functions are virtual. This is, what we export/import - is essentially just a pointer to a vtbl. - To work around a deficiency of Visual C++ 6.0, the name of each - from_python() member functions is made unique by appending a few - characters (derived in a ad-hoc manner from the corresponding type). - */ -template -struct export_converter_object_base -{ - virtual int get_api_major() const { return detail::export_converters_api_major; } - virtual int get_api_minor() const { return detail::export_converters_api_minor; } - - virtual PyObject* to_python(const T& x) = 0; - - virtual T* from_python_Ts(PyObject* p, boost::python::type t) = 0; - virtual const T* from_python_cTs(PyObject* p, boost::python::type t) = 0; - virtual const T* from_python_cTscr(PyObject* p, boost::python::type t) = 0; - virtual T* from_python_Tscr(PyObject* p, boost::python::type t) = 0; - virtual T& from_python_Tr(PyObject* p, boost::python::type t) = 0; - virtual const T& from_python_cTr(PyObject* p, boost::python::type t) = 0; - virtual const T& from_python_T(PyObject* p, boost::python::type t) = 0; - - virtual std::auto_ptr& from_python_aTr(PyObject* p, boost::python::type&> t) = 0; - virtual std::auto_ptr from_python_aT(PyObject* p, boost::python::type > t) = 0; - virtual const std::auto_ptr& from_python_caTr(PyObject* p, boost::python::type&> t) = 0; - virtual PyObject* to_python(std::auto_ptr x) = 0; - - virtual boost::shared_ptr& from_python_sTr(PyObject* p, boost::python::type&> t) = 0; - virtual const boost::shared_ptr& from_python_sT(PyObject* p, boost::python::type > t) = 0; - virtual const boost::shared_ptr& from_python_csTr(PyObject* p, boost::python::type&> t) = 0; - virtual PyObject* to_python(boost::shared_ptr x) = 0; -}; - -// Converters to be used if T is not copyable. -template -struct export_converter_object_noncopyable : export_converter_object_base -{ - 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 - return 0; -#endif - } - - virtual T* from_python_Ts(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T* from_python_cTs(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T* from_python_cTscr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual T* from_python_Tscr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual T& from_python_Tr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T& from_python_cTr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T& from_python_T(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - - virtual std::auto_ptr& from_python_aTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual std::auto_ptr from_python_aT(PyObject* p, boost::python::type > t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const std::auto_ptr& from_python_caTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual PyObject* to_python(std::auto_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - - virtual boost::shared_ptr& from_python_sTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const boost::shared_ptr& from_python_sT(PyObject* p, boost::python::type > t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const boost::shared_ptr& from_python_csTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual PyObject* to_python(boost::shared_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } -}; - -// The addditional to_python() converter that can be used if T is copyable. -template -struct export_converter_object : export_converter_object_noncopyable -{ - virtual PyObject* to_python(const T& x) { - return BOOST_PYTHON_CONVERSION::py_extension_class_converters(boost::python::type()).to_python(x); - } -}; - -namespace detail -{ - -/* This class template is instantiated by import_converters. - Its purpose is to import the converter_object via the Python API. - The actual import is only done once. The pointer to the - imported converter object is kept in the static data member - imported_converters. -*/ - template - class import_extension_class - : public python_import_extension_class_converters - { - public: - inline import_extension_class(const char* module, const char* py_class) { - m_module = module; - m_py_class = py_class; - } - - static boost::python::export_converter_object_base* get_converters(); - - private: - static std::string m_module; - static std::string m_py_class; - static boost::python::export_converter_object_base* imported_converters; - }; - - template std::string import_extension_class::m_module; - template std::string import_extension_class::m_py_class; - template - boost::python::export_converter_object_base* - import_extension_class::imported_converters = 0; - - template - boost::python::export_converter_object_base* - import_extension_class::get_converters() { - if (imported_converters == 0) { - void* cobject - = import_converter_object(m_module, m_py_class, - converters_attribute_name); - imported_converters - = static_cast*>(cobject); - check_export_converters_api( - export_converters_api_major, - export_converters_api_minor, - imported_converters->get_api_major(), - imported_converters->get_api_minor()); - } - return imported_converters; - } -}}} // namespace boost::python::detail - -namespace boost { namespace python { - -// Implementation of export_converters(). -template -void export_converters(class_builder& cb) -{ - static export_converter_object export_cvts; - cb.add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - detail::converters_attribute_name); -} - -// Implementation of export_converters_noncopyable(). -template -void export_converters_noncopyable(class_builder& cb) -{ - static export_converter_object_noncopyable export_cvts; - cb.add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - detail::converters_attribute_name); -} - -// Implementation of import_converters. -template -class import_converters - : python_import_extension_class_converters // Works around MSVC6.x/GCC2.95.2 bug described - // at the bottom of class_builder.hpp. -{ - public: - import_converters(const char* module, const char* py_class) - : m_class(new detail::import_extension_class(module, py_class)) - { } - private: - boost::shared_ptr > m_class; -}; - -}} // namespace boost::python - -#endif // CROSS_MODULE_HPP diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp deleted file mode 100644 index 04bca0af..00000000 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ /dev/null @@ -1,341 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_arg_tuple_size.python - -#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP -# define ARG_TUPLE_SIZE_DWA20011201_HPP - -# include - -namespace boost { namespace python { namespace detail { - -// Computes (at compile-time) the number of elements that a Python -// argument tuple must have in order to be passed to a wrapped C++ -// (member) function of the given type. -template struct arg_tuple_size; - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__) - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 0); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -// Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -# endif // __MWERKS__ -# else - -// We will use the "sizeof() trick" to work around the lack of -// partial specialization in MSVC6 and its broken-ness in borland. -// See http://opensource.adobe.com or -// http://groups.yahoo.com/group/boost/message/5441 for -// more examples - -// The following helper functions are never actually called, since -// they are only used within a sizeof() expression, but the type of -// their return value is used to discriminate between various free -// and member function pointers at compile-time. - -template -char_array<0> arg_tuple_size_helper(R (*)()); - -template -char_array<1> arg_tuple_size_helper(R (*)(A1)); - -template -char_array<2> arg_tuple_size_helper(R (*)(A1, A2)); - -template -char_array<3> arg_tuple_size_helper(R (*)(A1, A2, A3)); - -template -char_array<4> arg_tuple_size_helper(R (*)(A1, A2, A3, A4)); - -template -char_array<5> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5)); - -template -char_array<6> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5, A6)); - -template -char_array<1> arg_tuple_size_helper(R (A0::*)()); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1)); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2)); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3)); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4)); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5)); - - -template -char_array<1> arg_tuple_size_helper(R (A0::*)() const); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const); - - -template -char_array<1> arg_tuple_size_helper(R (A0::*)() volatile); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1) volatile); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) volatile); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) volatile); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) volatile); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) volatile); - - -template -char_array<1> arg_tuple_size_helper(R (A0::*)() const volatile); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const volatile); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const volatile); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const volatile); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const volatile); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const volatile); - - -template -struct arg_tuple_size -{ - // The sizeof() magic happens here - BOOST_STATIC_CONSTANT(std::size_t, value - = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); -}; -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -}}} // namespace boost::python::detail - -#endif // ARG_TUPLE_SIZE_DWA20011201_HPP - diff --git a/include/boost/python/detail/base_object.hpp b/include/boost/python/detail/base_object.hpp deleted file mode 100644 index d92b3972..00000000 --- a/include/boost/python/detail/base_object.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) - -#ifndef BASE_OBJECT_DWA051600_H_ -# define BASE_OBJECT_DWA051600_H_ - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// base_object - adds a constructor and non-virtual destructor to a -// base Python type (e.g. PyObject, PyTypeObject). -template -struct base_object : PythonType -{ - typedef PythonType base_python_type; - - // Initializes type and reference count. All other fields of base_python_type are 0 - base_object(PyTypeObject* type_obj); - - // Decrements reference count on the type - ~base_object(); -}; - -// Easy typedefs for common usage -typedef base_object python_object; -typedef base_object python_type; - - -// -// base_object member function implementations -// -template -base_object::base_object(PyTypeObject* type_obj) -{ - base_python_type* bp = this; - BOOST_CSTD_::memset(bp, 0, sizeof(base_python_type)); - Py_INCREF(type_obj); - PyObject_INIT(bp, type_obj); -} - -template -inline base_object::~base_object() -{ - Py_DECREF(ob_type); -} - -}}} // namespace boost::python::detail - -#endif // BASE_OBJECT_DWA051600_H_ diff --git a/include/boost/python/detail/call_object.hpp b/include/boost/python/detail/call_object.hpp deleted file mode 100644 index 5595e5c0..00000000 --- a/include/boost/python/detail/call_object.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALL_OBJECT_DWA20011222_HPP -# define CALL_OBJECT_DWA20011222_HPP -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // A function object adaptor which turns a function returning R into - // an "equivalent" function returning void, but taking an R& in - // which the adapted function's result is stored. - template - struct return_by_reference - { - typedef void return_type; - - return_by_reference(R& result, F f) - : m_result(result) - , m_f(f) - { - } - - void operator()() const - { - m_result = m_f(); - } - - R& m_result; - F m_f; - }; - - // An object generator for the above adaptors - template - return_by_reference bind_return(R& result, F f) - { - return return_by_reference(result, f); - } - - // Given a function object f with signature - // - // R f(PyTypeObject*,PyObject*) - // - // calls f inside of handle_exception_impl, placing f's result in - // ret. Returns true iff an exception is thrown by f, leaving ret - // unmodified. - template - bool call_object(R& ret, PyObject* obj, F f) - { - return handle_exception( - detail::bind_return( - ret - , boost::bind( - f, static_cast(obj->ob_type), obj))); - } -} // namespace detail - -}} // namespace boost::python - -#endif // CALL_OBJECT_DWA20011222_HPP diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp deleted file mode 100644 index d0b01b6e..00000000 --- a/include/boost/python/detail/caller.hpp +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALLER_DWA20011214_HPP -# define CALLER_DWA20011214_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python -{ - template struct to_python; -}} - -namespace boost { namespace python { namespace detail { - -struct caller -{ - typedef PyObject* result_type; - - template - PyObject* operator()(R (*f)(), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - -// Member functions - template - PyObject* operator()(R (A0::*f)(), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)() const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)() volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } -}; - -}}} // namespace boost::python::detail - -#endif // CALLER_DWA20011214_HPP diff --git a/include/boost/python/detail/cast.hpp b/include/boost/python/detail/cast.hpp deleted file mode 100644 index 367f1f14..00000000 --- a/include/boost/python/detail/cast.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef CAST_DWA052500_H_ -# define CAST_DWA052500_H_ - -# ifndef BOOST_PYTHON_V2 -# include -# include - -namespace boost { namespace python { - -namespace detail { - inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p) - { - return reinterpret_cast(p); - } - - inline PyObject* as_base_object(const PyObject*, PyObject* p) - { - return p; - } - - inline const PyTypeObject* as_base_object(const PyTypeObject*, const PyObject* p) - { - return reinterpret_cast(p); - } - - inline const PyObject* as_base_object(const PyObject*, const PyObject* p) - { - return p; - } -} // namespace detail - -// Convert a pointer to any type derived from PyObject or PyTypeObject to a PyObject* -inline PyObject* as_object(PyObject* p) { return p; } -inline PyObject* as_object(PyTypeObject* p) { return reinterpret_cast(p); } - -// If I didn't have to support stupid MSVC6 we could just use a simple template function: -// template T* downcast(PyObject*). -template -struct downcast -{ - downcast(PyObject* p) - : m_p(static_cast(detail::as_base_object((T*)0, p))) - {} - - downcast(const PyObject* p) - : m_p(static_cast(detail::as_base_object((const T*)0, p))) - {} - - downcast(PyTypeObject* p) - : m_p(static_cast(p)) - {} - - downcast(const PyTypeObject* p) - : m_p(static_cast(p)) - {} - - operator T*() const { return m_p; } - - // MSVC doesn't like boost::dereferencable unless T has a default - // constructor, so operator-> must be defined by hand :( - T* operator->() const { return &**this; } - - T* get() const { return m_p; } - T& operator*() const { return *m_p; } - private: - T* m_p; -}; - -}} // namespace boost::python - -# endif // BOOST_PYTHON_V2 - -#endif // CAST_DWA052500_H_ diff --git a/include/boost/python/detail/char_array.hpp b/include/boost/python/detail/char_array.hpp deleted file mode 100644 index d68aea47..00000000 --- a/include/boost/python/detail/char_array.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CHAR_ARRAY_DWA2002129_HPP -# define CHAR_ARRAY_DWA2002129_HPP - -namespace boost { namespace python { namespace detail { - -// This little package is used to transmit the number of arguments -// from the helper functions below to the sizeof() expression below. -// Because we can never have an array of fewer than 1 element, we -// add 1 to n and then subtract 1 from the result of sizeof() below. -template -struct char_array -{ - char elements[n+1]; -}; - -}}} // namespace boost::python::detail - -#endif // CHAR_ARRAY_DWA2002129_HPP diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp deleted file mode 100644 index c488cb64..00000000 --- a/include/boost/python/detail/config.hpp +++ /dev/null @@ -1,169 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// Revision History: -// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams) - -#ifndef CONFIG_DWA052200_H_ -# define CONFIG_DWA052200_H_ - -# include -# include - -# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE - // A gcc bug forces some symbols into the global namespace -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE -# define BOOST_PYTHON_CONVERSION -# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x -# else -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python { -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python -# define BOOST_PYTHON_CONVERSION boost::python -# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';' -# endif - -# if defined(BOOST_MSVC) -# if _MSC_VER <= 1200 -# define BOOST_MSVC6_OR_EARLIER 1 -# endif - -# pragma warning (disable : 4786) - -# 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. -# if defined(__DECCXX_VER) && __DECCXX_VER <= 60290024 -# define BOOST_OFFSETOF(s_name, s_member) \ - ((size_t)__INTADDR__(&(((s_name *)0)->s_member))) -# else -# define BOOST_OFFSETOF(s_name, s_member) \ - offsetof(s_name, s_member) -# endif - -// The STLport puts all of the standard 'C' library names in std (as far as the -// user is concerned), but without it you need a fix if you're using MSVC or -// Intel C++ -# if defined(BOOST_MSVC_STD_ITERATOR) -# define BOOST_CSTD_ -# else -# define BOOST_CSTD_ std -# endif - -# ifndef BOOST_PYTHON_MODULE_INIT -# if defined(_WIN32) || defined(__CYGWIN__) -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() -# else -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() -# endif -# endif - -/***************************************************************************** - * - * Set up dll import/export options: - * - ****************************************************************************/ - -// backwards compatibility: -#ifdef BOOST_PYTHON_STATIC_LIB -# define BOOST_PYTHON_STATIC_LINK -#endif - -#if defined(__MWERKS__) \ - || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \ - || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) -# define BOOST_PYTHON_NO_TEMPLATE_EXPORT -#endif - -#if defined(__GNUC__) -# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern -# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern -#endif - -// Handle default cases -#ifndef BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD -# ifdef _WIN32 -# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern -# else -# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD -# endif -#endif - -#ifndef BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD -# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD -#endif - -#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) -# if defined(BOOST_PYTHON_SOURCE) -# define BOOST_PYTHON_DECL __declspec(dllexport) -# define BOOST_PYTHON_BUILD_DLL -# else -# define BOOST_PYTHON_DECL __declspec(dllimport) -# endif -#endif - -#ifndef BOOST_PYTHON_DECL -# define BOOST_PYTHON_DECL -#endif - -#ifndef BOOST_PYTHON_DECL_TEMPLATE -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -# define BOOST_PYTHON_DECL_TEMPLATE BOOST_PYTHON_DECL -# else -# define BOOST_PYTHON_DECL_TEMPLATE -# endif -#endif - -#if defined(BOOST_PYTHON_SOURCE) -# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD -#else -# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD -#endif - -# ifndef BOOST_PYTHON_EXPORT_TEMPLATE -# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template -# endif - -# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL - -// Borland C++ Fix/error check: -#if defined(__BORLANDC__) -# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551) - // problems with std::basic_string and dll RTL: -# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE) -# ifdef BOOST_PYTHON_BUILD_DLL -# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL -# else -# pragma warn defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!! -# endif -# endif -# ifndef _RTLDLL - // this is harmless for a static link: -# define _RWSTD_COMPILE_INSTANTIATE -# endif -# endif - // - // VCL support: - // if we're building a console app then there can't be any VCL (can there?) -# if !defined(__CONSOLE__) && !defined(_NO_VCL) -# define BOOST_PYTHON_USE_VCL -# endif -#endif - -#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 -// Work around a compiler bug. -// boost::python::detail::function has to be seen by the compiler before the -// boost::function class template. -namespace boost { namespace python { namespace detail { -class function; -}}} -#endif - -#endif // CONFIG_DWA052200_H_ diff --git a/include/boost/python/detail/eval.hpp b/include/boost/python/detail/eval.hpp deleted file mode 100644 index 3e799507..00000000 --- a/include/boost/python/detail/eval.hpp +++ /dev/null @@ -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 struct undefined; -template -struct eval -{ -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 - // based on the (non-conforming) MSVC trick from MPL - template - struct unarymetafunction_vc : UnaryMetaFunction {}; - - // illegal C++ which causes VC to admit that unarymetafunction_vc - // can have a nested template: - template<> - struct unarymetafunction_vc - { - template struct apply; - }; - - typedef typename unarymetafunction_vc< - ::boost::mpl::detail::msvc_never_true::value - >::template apply::type type; -# else - typedef typename UnaryMetaFunction::template apply::type type; -# endif -}; - -}}} // namespace boost::python::detail - -#endif // EVAL_DWA2002124_HPP diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp deleted file mode 100644 index 638217d1..00000000 --- a/include/boost/python/detail/extension_class.hpp +++ /dev/null @@ -1,1007 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated for 10-argument constructors by -// gen_extclass.python - -// Revision History: -// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve) -// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted -// to_python (Dave Abrahams) - -#ifndef EXTENSION_CLASS_DWA052000_H_ -# define EXTENSION_CLASS_DWA052000_H_ - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// forward declarations -template struct operators; -template struct left_operand; -template struct right_operand; - -enum without_downcast_t { without_downcast }; - -namespace detail -{ - -// forward declarations - class extension_instance; - class extension_class_base; - template class instance_holder; - template class instance_value_holder; - template class instance_ptr_holder; - template struct operand_select; - template struct choose_op; - template struct choose_rop; - template struct choose_unary_op; - template struct define_operator; - - class BOOST_PYTHON_DECL extension_instance : public instance - { - public: - extension_instance(PyTypeObject* class_); - ~extension_instance(); - - void add_implementation(std::auto_ptr holder); - - typedef std::vector held_objects; - const held_objects& wrapped_objects() const - { return m_wrapped_objects; } - private: - held_objects m_wrapped_objects; - }; - -} // namespace detail - -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t; -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class; -# endif - -namespace detail { - -BOOST_PYTHON_DECL meta_class* extension_meta_class(); -BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p); -BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&); -BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&); - -template -T* check_non_null(T* p) -{ - if (p == 0) - report_released_smart_pointer(typeid(T)); - return p; -} - -template class held_instance; - -typedef void* (*conversion_function_ptr)(void*); - -struct BOOST_PYTHON_DECL base_class_info -{ - base_class_info(extension_class_base* t, conversion_function_ptr f) - :class_object(t), convert(f) - {} - - extension_class_base* class_object; - conversion_function_ptr convert; -}; - -typedef base_class_info derived_class_info; - -struct add_operator_base; - -class BOOST_PYTHON_DECL extension_class_base : public class_t -{ - public: - extension_class_base(const char* name); - - public: - // the purpose of try_class_conversions() and its related functions - // is explained in extclass.cpp - void* try_class_conversions(instance_holder_base*) const; - void* try_base_class_conversions(instance_holder_base*) const; - void* try_derived_class_conversions(instance_holder_base*) const; - - void set_attribute(const char* name, PyObject* x); - void set_attribute(const char* name, ref x); - - private: - virtual void* extract_object_from_holder(instance_holder_base* v) const = 0; - virtual std::vector const& base_classes() const = 0; - virtual std::vector const& derived_classes() const = 0; - - protected: - friend struct add_operator_base; - void add_method(reference method, const char* name); - void add_method(function* method, const char* name); - - void add_constructor_object(function*); - void add_setter_method(function*, const char* name); - void add_getter_method(function*, const char* name); -}; - -template -class class_registry -{ - public: - static extension_class_base* class_object() - { return static_class_object; } - - // Register/unregister the Python class object corresponding to T - static void register_class(extension_class_base*); - static void unregister_class(extension_class_base*); - - // Establish C++ inheritance relationships - static void register_base_class(base_class_info const&); - static void register_derived_class(derived_class_info const&); - - // Query the C++ inheritance relationships - static std::vector const& base_classes(); - static std::vector const& derived_classes(); - private: - static extension_class_base* static_class_object; - static std::vector static_base_class_info; - static std::vector static_derived_class_info; -}; - -template -struct is_null_helper -{ - template - static bool test(Ptr x) { return x == 0; } -}; - -template <> -struct is_null_helper -{ - template - static bool test(const Ptr& x) { return x.get() == 0; } -}; - -template -bool is_null(const Ptr& x) -{ - return is_null_helper<(is_pointer::value)>::test(x); -} - -}}} // namespace boost::python::detail - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -// This class' only job is to define from_python and to_python converters for T -// and U. T is the class the user really intends to wrap. U is a class derived -// from T with some virtual function overriding boilerplate, or if there are no -// virtual functions, U = held_instance. -// -// A look-alike of this class in root/boost/python/cross_module.hpp -// is used for the implementation of the cross-module support -// (export_converters and import_converters). If from_python -// and to_python converters are added or removed from the class -// below, the class python_import_extension_class_converters has -// to be modified accordingly. -// -template > -class python_extension_class_converters -{ - public: - // Get an object which can be used to convert T to/from python. This is used - // as a kind of concept check by the global template - // - // PyObject* to_python(const T& x) - // - // below this class, to prevent the confusing messages that would otherwise - // pop up. Now, if T hasn't been wrapped as an extension class, the user - // will see an error message about the lack of an eligible - // py_extension_class_converters() function. - friend python_extension_class_converters py_extension_class_converters(boost::python::type) - { - return python_extension_class_converters(); - } - - // This is a member function because in a conforming implementation, friend - // funcitons defined inline in the class body are all instantiated as soon - // as the enclosing class is instantiated. If T is not copyable, that causes - // a compiler error. Instead, we access this function through the global - // template - // - // PyObject* to_python(const T& x) - // - // defined below this class. Since template functions are instantiated only - // on demand, errors will be avoided unless T is noncopyable and the user - // writes code which causes us to try to copy a T. - PyObject* to_python(const T& x) const - { - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_value_holder(result.get(), x))); - return result.release(); - } - - friend - T* non_null_from_python(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_holder* held = dynamic_cast*>(*p); - if (held != 0) - return held->target(); - - // see extclass.cpp for an explanation of try_class_conversions() - void* target = boost::python::detail::class_registry::class_object()->try_class_conversions(*p); - if(target) - return static_cast(target); - } - boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - throw boost::python::argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return 0; -#endif - } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - return 0; - else - return non_null_from_python(obj, boost::python::type()); - } - - // Extract from obj a mutable reference to the PtrType object which is holding a T. - template - static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_ptr_holder* held = - dynamic_cast*>(*p); - if (held != 0) - return held->ptr(); - } - boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - throw boost::python::argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return *(PtrType*)0; -#endif - } - - // Extract from obj a reference to the PtrType object which is holding a - // T. If it weren't for auto_ptr, it would be a constant reference. Do not - // modify the referent except by copying an auto_ptr! If obj is None, the - // reference denotes a default-constructed PtrType - template - static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - { - static PtrType null_ptr; - return null_ptr; - } - return smart_ptr_reference(obj, boost::python::type()); - } - - template - static PyObject* smart_ptr_to_python(PtrType x) - { - if (boost::python::detail::is_null(x)) - { - return boost::python::detail::none(); - } - - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_ptr_holder(x))); - return result.release(); - } - - static boost::python::reference create_instance() - { - PyTypeObject* class_object = boost::python::detail::class_registry::class_object(); - if (class_object == 0) - boost::python::detail::report_missing_class_object(typeid(T)); - - return boost::python::reference( - new boost::python::detail::extension_instance(class_object)); - } - - // Convert to const T* - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to const T* const& - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T* const& - friend T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T& - friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } - - // Convert to const T& - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend std::auto_ptr from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(std::auto_ptr x) - { return smart_ptr_to_python(x); } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(boost::shared_ptr x) - { return smart_ptr_to_python(x); } -}; - -// Convert T to_python, instantiated on demand and only if there isn't a -// non-template overload for this function. This version is the one invoked when -// T is a wrapped class. See the first 2 functions declared in -// python_extension_class_converters above for more info. -template -PyObject* to_python(const T& x) -{ - return py_extension_class_converters(boost::python::type()).to_python(x); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters); - -namespace detail { - -template class instance_holder; - -class BOOST_PYTHON_DECL read_only_setattr_function : public function -{ - public: - read_only_setattr_function(const char* name); - PyObject* do_call(PyObject* args, PyObject* keywords) const; - const char* description() const; - private: - string m_name; -}; - - template - struct define_conversion - { - static void* upcast_ptr(void* v) - { - return static_cast(static_cast(v)); - } - - static void* downcast_ptr(void* v) - { - return dynamic_cast(static_cast(v)); - } - }; - -// An easy way to make an extension base class which wraps T. Note that Python -// subclasses of this class will simply be class_t objects. -// -// U should be a class derived from T which overrides virtual functions with -// boilerplate code to call back into Python. See extclass_demo.h for examples. -// -// U is optional, but you won't be able to override any member functions in -// Python which are called from C++ if you don't supply it. If you just want to -// be able to use T in python without overriding member functions, you can omit -// U. -template > -class extension_class - : public python_extension_class_converters, // This generates the to_python/from_python functions - public extension_class_base -{ - public: - typedef T wrapped_type; - typedef U callback_type; - - // Construct with a name that comes from typeid(T).name(). The name only - // affects the objects of this class are represented through repr() - extension_class(); - - // Construct with the given name. The name only affects the objects of this - // class are represented through repr() - extension_class(const char* name); - - ~extension_class(); - - // define constructors - template - inline void def(constructor) - // The following incantation builds a signature1, signature2,... object. It - // should _all_ get optimized away. - { add_constructor( - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - signature0()))))))))))); - } - - - // export homogeneous operators (type of both lhs and rhs is 'operator') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>()); - - // export homogeneous operators (type of both lhs and rhs is 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>()); - template - inline void def(operators) - { - typedef typename operand_select::template wrapped::type true_operand; - def_operators(operators()); - } - - // export heterogeneous operators (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::right_operand()); - - // export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::right_operand()); - template - inline void def(operators, right_operand r) - { - typedef typename operand_select::template wrapped::type true_left; - def_operators(operators(), r); - } - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::left_operand()); - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::left_operand()); - template - inline void def(operators, left_operand l) - { - typedef typename operand_select::template wrapped::type true_right; - def_operators(operators(), l); - } - - // define a function that passes Python arguments and keywords - // to C++ verbatim (as a 'tuple const&' and 'dictionary const&' - // respectively). This is useful for manual argument passing. - // It's also the only possibility to pass keyword arguments to C++. - // Fn must have a signatur that is compatible to - // PyObject* (*)(PyObject* aTuple, PyObject* aDictionary) - template - inline void def_raw(Fn fn, const char* name) - { - this->add_method(new_raw_arguments_function(fn), name); - } - - // define member functions. In fact this works for free functions, too - - // they act like static member functions, or if they start with the - // appropriate self argument (as a pointer), they can be used just like - // ordinary member functions -- just like Python! - template - inline void def(Fn fn, const char* name) - { - this->add_method(new_wrapped_function(fn), name); - } - - // Define a virtual member function with a default implementation. - // default_fn should be a function which provides the default implementation. - // Be careful that default_fn does not in fact call fn virtually! - template - inline void def(Fn fn, const char* name, DefaultFn default_fn) - { - this->add_method(new_virtual_function(type(), fn, default_fn), name); - } - - // Provide a function which implements x., reading from the given - // member (pm) of the T obj - template - inline void def_getter(MemberType T::*pm, const char* name) - { - this->add_getter_method(new getter_function(pm), name); - } - - // Provide a function which implements assignment to x., writing to - // the given member (pm) of the T obj - template - inline void def_setter(MemberType T::*pm, const char* name) - { - this->add_setter_method(new setter_function(pm), name); - } - - // Expose the given member (pm) of the T obj as a read-only attribute - template - inline void def_readonly(MemberType T::*pm, const char* name) - { - this->add_setter_method(new read_only_setattr_function(name), name); - this->def_getter(pm, name); - } - - // Expose the given member (pm) of the T obj as a read/write attribute - template - inline void def_read_write(MemberType T::*pm, const char* name) - { - this->def_getter(pm, name); - this->def_setter(pm, name); - } - - // define the standard coercion needed for operator overloading - void def_standard_coerce(); - - // declare the given class a base class of this one and register - // up and down conversion functions - template - void declare_base(extension_class* base) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, - &define_conversion::downcast_ptr); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - // declare the given class a base class of this one and register - // only up conversion function - template - void declare_base(extension_class* base, without_downcast_t) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, 0); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - private: // types - typedef instance_value_holder holder; - - private: // extension_class_base virtual function implementations - std::vector const& base_classes() const; - std::vector const& derived_classes() const; - void* extract_object_from_holder(instance_holder_base* v) const; - - private: // Utility functions - template - inline void def_operators(operators) - { - def_standard_coerce(); - - // for some strange reason, this prevents MSVC from having an - // "unrecoverable block scoping error"! - typedef choose_op<(which & op_add)> choose_add; - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - choose_unary_op<(which & op_neg)>::template args::add(this); - choose_unary_op<(which & op_pos)>::template args::add(this); - choose_unary_op<(which & op_abs)>::template args::add(this); - choose_unary_op<(which & op_invert)>::template args::add(this); - choose_unary_op<(which & op_int)>::template args::add(this); - choose_unary_op<(which & op_long)>::template args::add(this); - choose_unary_op<(which & op_float)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_unary_op<(which & op_str)>::template args::add(this); - } - - template - inline void def_operators(operators, right_operand) - { - def_standard_coerce(); - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - } - - template - inline void def_operators(operators, left_operand) - { - def_standard_coerce(); - - choose_rop<(which & op_add)>::template args::add(this); - choose_rop<(which & op_sub)>::template args::add(this); - choose_rop<(which & op_mul)>::template args::add(this); - choose_rop<(which & op_div)>::template args::add(this); - choose_rop<(which & op_mod)>::template args::add(this); - choose_rop<(which & op_divmod)>::template args::add(this); - choose_rop<(which & op_pow)>::template args::add(this); - choose_rop<(which & op_lshift)>::template args::add(this); - choose_rop<(which & op_rshift)>::template args::add(this); - choose_rop<(which & op_and)>::template args::add(this); - choose_rop<(which & op_xor)>::template args::add(this); - choose_rop<(which & op_or)>::template args::add(this); - choose_rop<(which & op_cmp)>::template args::add(this); - } - - template - void add_constructor(signature sig) - { - this->add_constructor_object(init_function::create(sig)); - } -}; - -// A simple wrapper over a T which allows us to use extension_class with a -// single template parameter only. See extension_class, above. -template -class held_instance : public Held -{ - // There are no member functions: we want to avoid inadvertently overriding - // any virtual functions in Held. -public: - held_instance(PyObject*) : Held() {} - template - held_instance(PyObject*, A1 a1) : Held( - typename unwrap_parameter::type(a1)) {} - template - held_instance(PyObject*, A1 a1, A2 a2) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7) - , typename unwrap_parameter::type(a8)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7) - , typename unwrap_parameter::type(a8) - , typename unwrap_parameter::type(a9)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7) - , typename unwrap_parameter::type(a8) - , typename unwrap_parameter::type(a9) - , typename unwrap_parameter::type(a10)) {} -}; - -// Abstract base class for all obj holders. Base for template class -// instance_holder<>, below. -class BOOST_PYTHON_DECL instance_holder_base -{ -public: - virtual ~instance_holder_base() {} - virtual bool held_by_value() = 0; -}; - -// Abstract base class which holds a Held, somehow. Provides a uniform way to -// get a pointer to the held object -template -class instance_holder : public instance_holder_base -{ -public: - virtual Held*target() = 0; -}; - -// Concrete class which holds a Held by way of a wrapper class Wrapper. If Held -// can be constructed with arguments (A1...An), Wrapper must have a -// corresponding constructor for arguments (PyObject*, A1...An). Wrapper is -// neccessary to implement virtual function callbacks (there must be a -// back-pointer to the actual Python object so that we can call any -// overrides). held_instance (above) is used as a default Wrapper class when -// there are no virtual functions. -template -class instance_value_holder : public instance_holder -{ -public: - Held* target() { return &m_held; } - Wrapper* value_target() { return &m_held; } - - instance_value_holder(extension_instance* p) : - m_held(p) {} - template - instance_value_holder(extension_instance* p, A1 a1) : - m_held(p, a1) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2) : - m_held(p, a1, a2) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3) : - m_held(p, a1, a2, a3) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4) : - m_held(p, a1, a2, a3, a4) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : - m_held(p, a1, a2, a3, a4, a5) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : - m_held(p, a1, a2, a3, a4, a5, a6) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : - m_held(p, a1, a2, a3, a4, a5, a6, a7) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return true; } - - private: - Wrapper m_held; -}; - -// Concrete class which holds a HeldType by way of a (possibly smart) pointer -// PtrType. By default, these are only generated for PtrType == -// std::auto_ptr and PtrType == boost::shared_ptr. -template -class instance_ptr_holder : public instance_holder -{ - public: - HeldType* target() { return &*m_ptr; } - PtrType& ptr() { return m_ptr; } - - instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return false; } - private: - PtrType m_ptr; -}; - -// -// Template function implementations -// - -template -extension_class::extension_class() - : extension_class_base(typeid(T).name()) -{ - class_registry::register_class(this); -} - -template -extension_class::extension_class(const char* name) - : extension_class_base(name) -{ - class_registry::register_class(this); -} - -template -void extension_class::def_standard_coerce() -{ - ref coerce_fct = dict().get_item(string("__coerce__")); - - if(coerce_fct.get() == 0) // not yet defined - this->def(&standard_coerce, "__coerce__"); -} - -template -inline -std::vector const& -extension_class::base_classes() const -{ - return class_registry::base_classes(); -} - -template -inline -std::vector const& -extension_class::derived_classes() const -{ - return class_registry::derived_classes(); -} - -template -void* extension_class::extract_object_from_holder(instance_holder_base* v) const -{ - instance_holder* held = dynamic_cast*>(v); - if(held) - return held->target(); - return 0; -} - -template -extension_class::~extension_class() -{ - class_registry::unregister_class(this); -} - -template -inline void class_registry::register_class(extension_class_base* p) -{ - // You're not expected to create more than one of these! - assert(static_class_object == 0); - static_class_object = p; -} - -template -inline void class_registry::unregister_class(extension_class_base* p) -{ - // The user should be destroying the same object they created. - assert(static_class_object == p); - (void)p; // unused in shipping version - static_class_object = 0; -} - -template -void class_registry::register_base_class(base_class_info const& i) -{ - static_base_class_info.push_back(i); -} - -template -void class_registry::register_derived_class(derived_class_info const& i) -{ - static_derived_class_info.push_back(i); -} - -template -std::vector const& class_registry::base_classes() -{ - return static_base_class_info; -} - -template -std::vector const& class_registry::derived_classes() -{ - return static_derived_class_info; -} - -// -// Static data member declaration. -// -template -extension_class_base* class_registry::static_class_object; -template -std::vector class_registry::static_base_class_info; -template -std::vector class_registry::static_derived_class_info; - -}}} // namespace boost::python::detail - -#endif // EXTENSION_CLASS_DWA052000_H_ diff --git a/include/boost/python/detail/functions.hpp b/include/boost/python/detail/functions.hpp deleted file mode 100644 index 486d73f9..00000000 --- a/include/boost/python/detail/functions.hpp +++ /dev/null @@ -1,311 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef FUNCTIONS_DWA051400_H_ -# define FUNCTIONS_DWA051400_H_ - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// forward declaration -class extension_instance; - - -// function -- -// the common base class for all overloadable function and method objects -// supplied by the library. -class BOOST_PYTHON_DECL function : public python_object -{ - public: - function(); - // function objects are reasonably rare, so we guess we can afford a virtual table. - // This cuts down on the number of distinct type objects which need to be defined. - virtual ~function() {} - - PyObject* call(PyObject* args, PyObject* keywords) const; - static void add_to_namespace(reference f, const char* name, PyObject* dict); - - private: - virtual PyObject* do_call(PyObject* args, PyObject* keywords) const = 0; - virtual const char* description() const = 0; - private: - struct type_object; - private: - reference m_overloads; // A linked list of the function overloads -}; - -// wrapped_function_pointer<> -- -// A single function or member function pointer wrapped and presented to -// Python as a callable object. -// -// Template parameters: -// R - the return type of the function pointer -// F - the complete type of the wrapped function pointer -template -struct wrapped_function_pointer : function -{ - typedef F ptr_fun; // pointer-to--function or pointer-to-member-function - - wrapped_function_pointer(ptr_fun pf) - : m_pf(pf) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const - { - // This is where the boundary between the uniform Python function - // interface and the statically-checked C++ function interface is - // crossed. - return caller::call(m_pf, args, keywords); - } - - const char* description() const - { return typeid(F).name(); } - - private: - const ptr_fun m_pf; -}; - -// raw_arguments_function -// A function that passes the Python argument tuple and keyword dictionary -// verbatim to C++ (useful for customized argument parsing and variable -// argument lists) -template -struct raw_arguments_function : function -{ - typedef Ret (*ptr_fun)(Args, Keywords); - - raw_arguments_function(ptr_fun pf) - : m_pf(pf) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const - { - ref dict(keywords ? - ref(keywords, ref::increment_count) : - ref(PyDict_New())); - - return to_python( - (*m_pf)(from_python(args, boost::python::type()), - from_python(dict.get(), boost::python::type()))); - } - - const char* description() const - { return typeid(ptr_fun).name(); } - - private: - const ptr_fun m_pf; -}; - -// virtual_function<> -- -// A virtual function with a default implementation wrapped and presented -// to Python as a callable object. -// -// Template parameters: -// T - the type of the target class -// R - the return type of the function pointer -// V - the virtual function pointer being wrapped -// (should be of the form R(T::*)(), or R (*)(T, )) -// D - a function which takes a T&, const T&, T*, or const T* first -// parameter and calls T::f on it /non-virtually/, where V -// approximates &T::f. -template -class virtual_function : public function -{ - public: - virtual_function(V virtual_function_ptr, D default_implementation) - : m_virtual_function_ptr(virtual_function_ptr), - m_default_implementation(default_implementation) - {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const; - - const char* description() const - { return typeid(V).name(); } - - private: - const V m_virtual_function_ptr; - const D m_default_implementation; -}; - -// A helper function for new_member_function(), below. Implements the core -// functionality once the return type has already been deduced. R is expected to -// be type, where X is the actual return type of pmf. -template -function* new_wrapped_function_aux(R, F pmf) -{ - // We can't just use "typename R::Type" below because MSVC (incorrectly) pukes. - typedef typename R::type return_type; - return new wrapped_function_pointer(pmf); -} - -// Create and return a new member function object wrapping the given -// pointer-to-member function -template -inline function* new_wrapped_function(F pmf) -{ - // Deduce the return type and pass it off to the helper function above - return new_wrapped_function_aux(return_value(pmf), pmf); -} - -template -function* new_raw_arguments_function(R (*pmf)(Args, keywords)) -{ - return new raw_arguments_function(pmf); -} - - -// A helper function for new_virtual_function(), below. Implements the core -// functionality once the return type has already been deduced. R is expected to -// be type, where X is the actual return type of V. -template -inline function* new_virtual_function_aux( - type, R, V virtual_function_ptr, D default_implementation - ) -{ - // We can't just use "typename R::Type" below because MSVC (incorrectly) pukes. - typedef typename R::type return_type; - return new virtual_function( - virtual_function_ptr, default_implementation); -} - -// Create and return a new virtual_function object wrapping the given -// virtual_function_ptr and default_implementation -template -inline function* new_virtual_function( - type, V virtual_function_ptr, D default_implementation - ) -{ - // Deduce the return type and pass it off to the helper function above - return new_virtual_function_aux( - type(), return_value(virtual_function_ptr), - virtual_function_ptr, default_implementation); -} - -// A function with a bundled "bound target" object. This is what is produced by -// the expression a.b where a is an instance or extension_instance object and b -// is a callable object not found in the obj namespace but on its class or -// a base class. -class BOOST_PYTHON_DECL bound_function : public python_object -{ - public: - static bound_function* create(const ref& target, const ref& fn); - - bound_function(const ref& target, const ref& fn); - PyObject* call(PyObject*args, PyObject* keywords) const; - PyObject* getattr(const char* name) const; - - private: - struct type_object; - friend struct type_object; - - ref m_target; - ref m_unbound_function; - - private: // data members for allocation/deallocation optimization - bound_function* m_free_list_link; - - static bound_function* free_list; -}; - -// Special functions designed to access data members of a wrapped C++ object. -template -class getter_function : public function -{ - public: - typedef MemberType ClassType::* pointer_to_member; - - getter_function(pointer_to_member pm) - : m_pm(pm) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const; - - const char* description() const - { return typeid(MemberType (*)(const ClassType&)).name(); } - private: - pointer_to_member m_pm; -}; - -template -class setter_function : public function -{ - public: - typedef MemberType ClassType::* pointer_to_member; - - setter_function(pointer_to_member pm) - : m_pm(pm) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const; - - const char* description() const - { return typeid(void (*)(const ClassType&, const MemberType&)).name(); } - private: - pointer_to_member m_pm; -}; - -template -PyObject* getter_function::do_call( - PyObject* args, PyObject* /* keywords */) const -{ - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - - return to_python( - from_python(self, type())->*m_pm); -} - -template -PyObject* setter_function::do_call( - PyObject* args, PyObject* /* keywords */) const -{ - PyObject* self; - PyObject* value; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &value)) - return 0; - - typedef typename boost::call_traits::const_reference extract_type; - from_python(self, type())->*m_pm - = from_python(value, type()); - - return none(); -} - -template -PyObject* virtual_function::do_call(PyObject* args, PyObject* keywords) const -{ - // If the target object is held by pointer, we must call through the virtual - // function pointer to the most-derived override. - PyObject* target = PyTuple_GetItem(args, 0); - if (target != 0) - { - extension_instance* self = get_extension_instance(target); - if (self->wrapped_objects().size() == 1 - && !self->wrapped_objects()[0]->held_by_value()) - { - return caller::call(m_virtual_function_ptr, args, keywords); - } - } - return caller::call(m_default_implementation, args, keywords); -} - -}}} // namespace boost::python::detail - -#endif // FUNCTIONS_DWA051400_H_ diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp deleted file mode 100644 index c76ffbc0..00000000 --- a/include/boost/python/detail/indirect_traits.hpp +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef INDIRECT_TRAITS_DWA2002131_HPP -# define INDIRECT_TRAITS_DWA2002131_HPP -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_reference_to_const -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -struct is_reference_to_const -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_reference_to_non_const -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -struct is_reference_to_non_const -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_reference_to_volatile -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -struct is_reference_to_volatile -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; -# else - -typedef char (&inner_yes_type)[3]; -typedef char (&inner_no_type)[2]; -typedef char (&outer_no_type)[1]; - -template -struct is_const_help -{ - typedef typename mpl::select_type< - is_const::value - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_volatile_help -{ - typedef typename mpl::select_type< - is_volatile::value - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -typename is_const_help::type reference_to_const_helper(V&); - -outer_no_type -reference_to_const_helper(...); - -template -struct is_reference_to_const -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); -}; - -template -struct is_reference_to_non_const -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); -}; - -template -typename is_volatile_help::type reference_to_volatile_helper(V&); -outer_no_type reference_to_volatile_helper(...); - -template -struct is_reference_to_volatile -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); -}; -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}}} // namespace boost::python::detail - -#endif // INDIRECT_TRAITS_DWA2002131_HPP diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp deleted file mode 100644 index ed34f9be..00000000 --- a/include/boost/python/detail/init_function.hpp +++ /dev/null @@ -1,556 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for %d-argument constructors by gen_init_function.python - -#ifndef INIT_FUNCTION_DWA052000_H_ -# define INIT_FUNCTION_DWA052000_H_ - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail { - - // parameter_traits - so far, this is a way to pass a const T& when we can be - // sure T is not a reference type, and a raw T otherwise. This should be - // rolled into boost::call_traits. Ordinarily, parameter_traits would be - // written: - // - // template struct parameter_traits - // { - // typedef const T& const_reference; - // }; - // - // template struct parameter_traits - // { - // typedef T& const_reference; - // }; - // - // template <> struct parameter_traits - // { - // typedef void const_reference; - // }; - // - // ...but since we can't partially specialize on reference types, we need this - // long-winded but equivalent incantation. - - // const_ref_selector -- an implementation detail of parameter_traits (below). This uses - // the usual "poor man's partial specialization" hack for MSVC. - template - struct const_ref_selector - { - template - struct const_ref - { - typedef const T& type; - }; - }; - - template <> - struct const_ref_selector - { - template - struct const_ref - { - typedef T type; - }; - }; - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable: 4181) -# endif // BOOST_MSVC - template - struct parameter_traits - { - private: - enum { is_ref = boost::is_reference::value }; - typedef const_ref_selector selector; - public: - typedef typename selector::template const_ref::type const_reference; - }; -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif // BOOST_MSVC - - // Full spcialization for void - template <> - struct parameter_traits - { - typedef void const_reference; - }; - - struct reference_parameter_base {}; - - template - class reference_parameter - : public reference_parameter_base - { - public: - typedef typename parameter_traits::const_reference const_reference; - reference_parameter(const_reference value) - : value(value) {} - operator const_reference() { return value; } - private: - const_reference value; - }; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct unwrap_parameter - { - typedef typename boost::add_reference::type type; - }; - - template - struct unwrap_parameter > - { - typedef typename reference_parameter::const_reference type; - }; -# else - template - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename T::const_reference type; - }; - }; - - template <> - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename add_reference::type type; - }; - }; - - template - struct unwrap_parameter - { - BOOST_STATIC_CONSTANT( - bool, is_wrapped = (is_base_and_derived::value)); - - typedef typename unwrap_parameter_helper< - is_wrapped - >::template apply::type type; - }; -# endif - -class extension_instance; -class instance_holder_base; - -class init; -template struct init0; -template struct init1; -template struct init2; -template struct init3; -template struct init4; -template struct init5; -template struct init6; -template struct init7; -template struct init8; -template struct init9; -template struct init10; - -template -struct init_function -{ - static init* create(signature0) { - return new init0; - } - - template - static init* create(signature1) { - return new init1::const_reference>; - } - - template - static init* create(signature2) { - return new init2::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature3) { - return new init3::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature4) { - return new init4::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature5) { - return new init5::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature6) { - return new init6::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature7) { - return new init7::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature8) { - return new init8::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature9) { - return new init9::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } - - template - static init* create(signature10) { - return new init10::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; - } -}; - -class BOOST_PYTHON_DECL init : public function -{ -private: // override function hook - PyObject* do_call(PyObject* args, PyObject* keywords) const; -private: - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0; -}; - - -template -struct init0 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - if (!PyArg_ParseTuple(args, const_cast(""))) - throw argument_error(); - return new T(self - ); - } - const char* description() const - { return typeid(void (*)(T&)).name(); } -}; - -template -struct init1 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1)).name(); } -}; - -template -struct init2 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2)).name(); } -}; - -template -struct init3 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3)).name(); } -}; - -template -struct init4 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4)).name(); } -}; - -template -struct init5 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5)).name(); } -}; - -template -struct init6 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6)).name(); } -}; - -template -struct init7 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7)).name(); } -}; - -template -struct init8 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())), - boost::python::detail::reference_parameter(from_python(a8, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8)).name(); } -}; - -template -struct init9 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())), - boost::python::detail::reference_parameter(from_python(a8, type())), - boost::python::detail::reference_parameter(from_python(a9, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9)).name(); } -}; - -template -struct init10 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - throw argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())), - boost::python::detail::reference_parameter(from_python(a8, type())), - boost::python::detail::reference_parameter(from_python(a9, type())), - boost::python::detail::reference_parameter(from_python(a10, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)).name(); } -}; - -}}} // namespace boost::python::detail - -#endif // INIT_FUNCTION_DWA052000_H_ diff --git a/include/boost/python/detail/map_entry.hpp b/include/boost/python/detail/map_entry.hpp deleted file mode 100644 index 9249523a..00000000 --- a/include/boost/python/detail/map_entry.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MAP_ENTRY_DWA2002118_HPP -# define MAP_ENTRY_DWA2002118_HPP - -namespace boost { namespace python { namespace detail { - -// A trivial type that works well as the value_type of associative -// vector maps -template -struct map_entry -{ - map_entry() {} - map_entry(Key k) : key(k), value() {} - map_entry(Key k, Value v) : key(k), value(v) {} - - bool operator<(map_entry const& rhs) const - { - return this->key < rhs.key; - } - - Key key; - Value value; -}; - -template -bool operator<(map_entry const& e, Key const& k) -{ - return e.key < k; -} - -template -bool operator<(Key const& k, map_entry const& e) -{ - return k < e.key; -} - - -}}} // namespace boost::python::detail - -#endif // MAP_ENTRY_DWA2002118_HPP diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp deleted file mode 100644 index 2473023a..00000000 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MSVC_TYPEINFO_DWA200222_HPP -# define MSVC_TYPEINFO_DWA200222_HPP - -#include -#include - -// -// Fix for MSVC's broken typeid() implementation which doesn't strip -// decoration. This fix doesn't handle cv-qualified array types. It -// could probably be done, but I haven't figured it out yet. -// - -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600 - -namespace boost { namespace python { namespace detail { - -typedef std::type_info const& typeinfo; - -templatestruct value_id_accessor; - -template<> -struct value_id_accessor<0> -{ - template - static typeinfo get(T*) { return typeid(T); } -}; - -template<> -struct value_id_accessor<1> -{ - template - static typeinfo get(T const*) { return typeid(T); } -}; - -template<> -struct value_id_accessor<2> -{ - template - static typeinfo get(T volatile*) { return typeid(T); } -}; - -template<> -struct value_id_accessor<3> -{ - template - static typeinfo get(T const volatile*) { return typeid(T); } -}; - -template struct bool_t{}; - -template -inline typeinfo typeid_nonref(boost::type* = 0) -{ - BOOST_STATIC_CONSTANT(bool, c = is_const::value); - BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); - return value_id_accessor<(2 * v + c)>::get((T*)0); -} - -template -inline typeinfo typeid_ref(boost::type*, ...) -{ - return typeid_nonref(); -} - -template -inline typeinfo typeid_ref(boost::type*, T& (*)()) -{ - return typeid_nonref(); -} - -template -inline typeinfo typeid_array(bool_t, boost::type* = 0) -{ - typedef T (*x)(); - return typeid_ref((boost::type*)0, x(0)); -} - -template -inline typeinfo typeid_array(bool_t, boost::type* = 0) -{ - return typeid_nonref(); -} - -template -inline typeinfo msvc_typeid(boost::type* = 0) -{ - typedef bool_t::value> tag; - return typeid_array(tag(), (boost::type*)0); -} - -}}} // namespace boost::python::detail - -# endif // BOOST_MSVC -#endif // MSVC_TYPEINFO_DWA200222_HPP diff --git a/include/boost/python/detail/none.hpp b/include/boost/python/detail/none.hpp deleted file mode 100644 index 8cb21004..00000000 --- a/include/boost/python/detail/none.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef NONE_DWA_052000_H_ -# define NONE_DWA_052000_H_ - -# include -# include - -namespace boost { namespace python { namespace detail { - -inline PyObject* none() { Py_INCREF(Py_None); return Py_None; } - -}}} // namespace boost::python::detail - -#endif // NONE_DWA_052000_H_ diff --git a/include/boost/python/detail/python_library_include.hpp b/include/boost/python/detail/python_library_include.hpp deleted file mode 100644 index d2b78c6e..00000000 --- a/include/boost/python/detail/python_library_include.hpp +++ /dev/null @@ -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 - * 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 - - - - diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp deleted file mode 100644 index 99bbc572..00000000 --- a/include/boost/python/detail/returning.hpp +++ /dev/null @@ -1,1338 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_returning.py - -#ifndef RETURNING_DWA20011201_HPP -# define RETURNING_DWA20011201_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// Calling C++ from Python -template -struct returning -{ - template - static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - - template - static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - - template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - - -// missing const volatile type traits -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - - template - static PyObject* call(R (*pf)(), PyObject* args, PyObject*, P const& policies) - { - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type c0; - if (!c0.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = c0( (*pf)() ); - - if (!result) return 0; - return policies.postcall(args, result); - } - - template - static PyObject* call(R (*pf)(A0), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type c1; - if (!c1.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = c1( (*pf)(c0(PyTuple_GET_ITEM(args, 0))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type c2; - if (!c2.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = c2( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type c3; - if (!c3.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = c3( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type c4; - if (!c4.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = c4( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type c5; - if (!c5.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = c5( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type c6; - if (!c6.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - PyObject* result = c6( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); - } -}; - -template <> -struct returning -{ - typedef void R; - template - static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); - } - - template - static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); - } - - template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); - } - - -// missing const volatile type traits -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); - } - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - static PyObject* call(R (*pf)(), PyObject*, PyObject*, P const& policies) - { - (*pf)(); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (*pf)(A0), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); - } -}; - -}}} // namespace boost::python::detail - -#endif // RETURNING_DWA20011201_HPP - diff --git a/include/boost/python/detail/signature.hpp b/include/boost/python/detail/signature.hpp deleted file mode 100644 index db8b39a4..00000000 --- a/include/boost/python/detail/signature.hpp +++ /dev/null @@ -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 - -namespace boost { namespace python { namespace detail { - -template -mpl::type_list -signature(R (*)()) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2, A3)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2, A3, A4)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2, A3, A4, A5)) -{ - return mpl::type_list(); -} -template -mpl::type_list signature(R (A0::*)()) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5)) -{ - return mpl::type_list(); -} - - -template -mpl::type_list signature(R (A0::*)() const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) const) -{ - return mpl::type_list(); -} - - -template -mpl::type_list signature(R (A0::*)() volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) volatile) -{ - return mpl::type_list(); -} - - -template -mpl::type_list signature(R (A0::*)() const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) const volatile) -{ - return mpl::type_list(); -} - -}}} // namespace boost::python::detail - -#endif // SIGNATURE_DWA2002128_HPP - diff --git a/include/boost/python/detail/signatures.hpp b/include/boost/python/detail/signatures.hpp deleted file mode 100644 index e216f688..00000000 --- a/include/boost/python/detail/signatures.hpp +++ /dev/null @@ -1,251 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated by gen_signatures.python for 10 arguments. -#ifndef SIGNATURES_DWA050900_H_ -# define SIGNATURES_DWA050900_H_ - -# include - -namespace boost { namespace python { - -namespace detail { -// A stand-in for the built-in void. This one can be passed to functions and -// (under MSVC, which has a bug, be used as a default template type parameter). -struct BOOST_PYTHON_DECL void_t {}; -} - -// An envelope in which type information can be delivered for the purposes -// of selecting an overloaded from_python() function. This is needed to work -// around MSVC's lack of partial specialiation/ordering. Where normally we'd -// want to form a function call like void f(), We instead pass -// type as one of the function parameters to select a particular -// overload. -// -// The id typedef helps us deal with the lack of partial ordering by generating -// unique types for constructor signatures. In general, type::id is type, -// but type::id is just void_t. -template -struct type -{ - typedef type id; -}; - -template <> -struct type -{ - typedef boost::python::detail::void_t id; -}; - -namespace detail { -// These basically encapsulate a chain of types, , used to make the syntax of -// add(constructor()) work. We need to produce a unique type for each number -// of non-default parameters to constructor<>. Q: why not use a recursive -// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs -// that involve recursive template nesting. -// -// signature chaining -template -struct signature10 {}; - -template -struct signature9 {}; - -template -inline signature10 prepend(type, signature9) - { return signature10(); } - -template -struct signature8 {}; - -template -inline signature9 prepend(type, signature8) - { return signature9(); } - -template -struct signature7 {}; - -template -inline signature8 prepend(type, signature7) - { return signature8(); } - -template -struct signature6 {}; - -template -inline signature7 prepend(type, signature6) - { return signature7(); } - -template -struct signature5 {}; - -template -inline signature6 prepend(type, signature5) - { return signature6(); } - -template -struct signature4 {}; - -template -inline signature5 prepend(type, signature4) - { return signature5(); } - -template -struct signature3 {}; - -template -inline signature4 prepend(type, signature3) - { return signature4(); } - -template -struct signature2 {}; - -template -inline signature3 prepend(type, signature2) - { return signature3(); } - -template -struct signature1 {}; - -template -inline signature2 prepend(type, signature1) - { return signature2(); } - -struct signature0 {}; - -template -inline signature1 prepend(type, signature0) - { return signature1(); } - - -// This one terminates the chain. Prepending void_t to the head of a void_t -// signature results in a void_t signature again. -inline signature0 prepend(void_t, signature0) { return signature0(); } - -} // namespace detail - -template -struct constructor -{ -}; - -namespace detail { -// Return value extraction: - -// This is just another little envelope for carrying a typedef (see type, -// above). I could have re-used type, but that has a very specific purpose. I -// thought this would be clearer. -template -struct return_value_select { typedef T type; }; - -// free functions -template -return_value_select return_value(R (*)()) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return return_value_select(); } - -// TODO(?): handle 'const void' - -// member functions -template -return_value_select return_value(R (T::*)()) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)() const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { return return_value_select(); } - -}}} // namespace boost::python::detail - -#endif diff --git a/include/boost/python/detail/singleton.hpp b/include/boost/python/detail/singleton.hpp deleted file mode 100644 index 3e7d91af..00000000 --- a/include/boost/python/detail/singleton.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef SINGLETON_DWA051900_H_ -# define SINGLETON_DWA051900_H_ - -# include - -namespace boost { namespace python { namespace detail { - -struct BOOST_PYTHON_DECL empty {}; -template -struct singleton : Base -{ - typedef singleton singleton_base; // Convenience type for derived class constructors - - static Derived* instance(); - - // Pass-through constructors - singleton() : Base() {} - - template - singleton(const A1& a1) : Base(a1) {} - - template - singleton(const A1& a1, const A2& a2) : Base(a1, a2) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3) : Base(a1, a2, a3) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4) : Base(a1, a2, a3, a4) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) : Base(a1, a2, a3, a4, a5) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) : Base(a1, a2, a3, a4, a5, a6) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) : Base(a1, a2, a3, a4, a5, a6, a7) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) : Base(a1, a2, a3, a4, a5, a6, a7, a8) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} - -}; - -template -Derived* singleton::instance() -{ - static Derived x; - return &x; -} - -}}} // namespace boost::python::detail - -#endif diff --git a/include/boost/python/detail/types.hpp b/include/boost/python/detail/types.hpp deleted file mode 100644 index 2e69d24e..00000000 --- a/include/boost/python/detail/types.hpp +++ /dev/null @@ -1,413 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef TYPES_DWA051800_H_ -# define TYPES_DWA051800_H_ - -// Usage: -// class X : public -// boost::python::callable< -// boost::python::getattrable < -// boost::python::setattrable > > -// { -// public: -// ref call(args, kw); -// ref getattr(args, kw); -// ref setattr(args, kw); -// }; - -# include -# include // really just for type<> -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail { - -class BOOST_PYTHON_DECL type_object_base : public python_type -{ - public: - explicit type_object_base(PyTypeObject* type_type); - virtual ~type_object_base(); - - public: - enum capability { - hash, call, str, getattr, setattr, compare, repr, richcompare, - - mapping_length, mapping_subscript, mapping_ass_subscript, - - sequence_length, sequence_item, sequence_ass_item, - sequence_concat, sequence_repeat, sequence_slice, sequence_ass_slice, - - number_add, number_subtract, number_multiply, number_divide, - number_remainder, number_divmod, number_power, number_negative, - number_positive, number_absolute, number_nonzero, number_invert, - number_lshift, number_rshift, number_and, number_xor, number_or, - number_coerce, number_int, number_long, number_float, number_oct, - number_hex, number_inplace_add, number_inplace_subtract, - number_inplace_multiply, number_inplace_divide, - number_inplace_remainder, number_inplace_power, - number_inplace_lshift, number_inplace_rshift, - number_inplace_and, number_inplace_or, number_inplace_xor - }; - - void enable(capability); - - // - // type behaviors - // - public: // Callbacks for basic type functionality. - virtual PyObject* instance_repr(PyObject*) const; - virtual int instance_compare(PyObject*, PyObject* other) const; - virtual PyObject* instance_str(PyObject*) const; - virtual long instance_hash(PyObject*) const; - virtual PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* kw) const; - virtual PyObject* instance_getattr(PyObject* obj, const char* name) const; - virtual int instance_setattr(PyObject* obj, const char* name, PyObject* value) const; - - // Dealloc is a special case, since every type needs a nonzero tp_dealloc slot. - virtual void instance_dealloc(PyObject*) const = 0; - - public: // Callbacks for mapping methods - virtual int instance_mapping_length(PyObject*) const; - virtual PyObject* instance_mapping_subscript(PyObject*, PyObject*) const ; - virtual int instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const; - - public: // Callbacks for sequence methods - virtual int instance_sequence_length(PyObject* obj) const; - virtual PyObject* instance_sequence_concat(PyObject* obj, PyObject* other) const; - virtual PyObject* instance_sequence_repeat(PyObject* obj, int n) const; - virtual PyObject* instance_sequence_item(PyObject* obj, int n) const; - virtual PyObject* instance_sequence_slice(PyObject* obj, int start, int finish) const; - virtual int instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const; - virtual int instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const; - - public: // Callbacks for number methods - virtual PyObject* instance_number_add(PyObject*, PyObject*) const; - virtual PyObject* instance_number_subtract(PyObject*, PyObject*) const; - virtual PyObject* instance_number_multiply(PyObject*, PyObject*) const; - virtual PyObject* instance_number_divide(PyObject*, PyObject*) const; - virtual PyObject* instance_number_remainder(PyObject*, PyObject*) const; - virtual PyObject* instance_number_divmod(PyObject*, PyObject*) const; - virtual PyObject* instance_number_power(PyObject*, PyObject*, PyObject*) const; - virtual PyObject* instance_number_negative(PyObject*) const; - virtual PyObject* instance_number_positive(PyObject*) const; - virtual PyObject* instance_number_absolute(PyObject*) const; - virtual int instance_number_nonzero(PyObject*) const; - virtual PyObject* instance_number_invert(PyObject*) const; - virtual PyObject* instance_number_lshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_rshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_and(PyObject*, PyObject*) const; - virtual PyObject* instance_number_xor(PyObject*, PyObject*) const; - virtual PyObject* instance_number_or(PyObject*, PyObject*) const; - virtual int instance_number_coerce(PyObject*, PyObject**, PyObject**) const; - virtual PyObject* instance_number_int(PyObject*) const; - virtual PyObject* instance_number_long(PyObject*) const; - virtual PyObject* instance_number_float(PyObject*) const; - virtual PyObject* instance_number_oct(PyObject*) const; - virtual PyObject* instance_number_hex(PyObject*) const; - - virtual PyObject* instance_number_inplace_add(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_and(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_or(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const; - - public: // Callbacks for rich comparisons - virtual PyObject* instance_lt(PyObject*, PyObject*) const; - virtual PyObject* instance_le(PyObject*, PyObject*) const; - virtual PyObject* instance_eq(PyObject*, PyObject*) const; - virtual PyObject* instance_ne(PyObject*, PyObject*) const; - virtual PyObject* instance_gt(PyObject*, PyObject*) const; - virtual PyObject* instance_ge(PyObject*, PyObject*) const; -}; - -template -class type_object : public type_object_base -{ - public: - typedef T instance; - - type_object(PyTypeObject* type_type, const char* name) - : type_object_base(type_type) - { - assert(name != 0); - this->tp_name = const_cast(name); - } - - type_object(PyTypeObject* type_type) - : type_object_base(type_type) - { - this->tp_name = const_cast(typeid(instance).name()); - } - - private: // Overridable behaviors. - // Called when the reference count goes to zero. The default implementation - // is "delete p". If you have not allocated your object with operator new or - // you have other constraints, you'll need to override this - virtual void dealloc(T* p) const; - - private: // Implementation of type_object_base hooks. Do not reimplement in derived classes. - void instance_dealloc(PyObject*) const; -}; - -// -// type objects -// -template -class callable : public Base -{ - public: - typedef callable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - callable(PyTypeObject* type_type, const char* name); - callable(PyTypeObject* type_type); - private: - PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* kw) const; -}; - -template -class getattrable : public Base -{ - public: - typedef getattrable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - getattrable(PyTypeObject* type_type, const char* name); - getattrable(PyTypeObject* type_type); - private: - PyObject* instance_getattr(PyObject* obj, const char* name) const; -}; - -template -class setattrable : public Base -{ - public: - typedef setattrable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - setattrable(PyTypeObject* type_type, const char* name); - setattrable(PyTypeObject* type_type); - private: - int instance_setattr(PyObject* obj, const char* name, PyObject* value) const; -}; - -template -class reprable : public Base -{ - public: - typedef reprable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - reprable(PyTypeObject* type_type, const char* name); - reprable(PyTypeObject* type_type); - private: - PyObject* instance_repr(PyObject* obj) const; -}; - -// -// Member function definitions -// - -// type_object<> -template -void type_object::instance_dealloc(PyObject* obj) const -{ - this->dealloc(downcast(obj).get()); -} - -template -void type_object::dealloc(T* obj) const -{ - delete obj; -} - -// callable -template -callable::callable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(call); -} - -template -callable::callable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(call); -} - -template -PyObject* callable::instance_call(PyObject* obj, PyObject* args, PyObject* kw) const -{ - return downcast(obj)->call(args, kw); -} - -// getattrable -template -getattrable::getattrable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(getattr); -} - -template -getattrable::getattrable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(getattr); -} - -template -PyObject* getattrable::instance_getattr(PyObject* obj, const char* name) const -{ - return downcast(obj)->getattr(name); -} - -// setattrable -template -setattrable::setattrable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(setattr); -} - -template -setattrable::setattrable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(setattr); -} - -template -int setattrable::instance_setattr(PyObject* obj, const char* name, PyObject* value) const -{ - return downcast(obj)->setattr(name, value); -} - -// reprable -template -reprable::reprable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(repr); -} - -template -reprable::reprable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(repr); -} - -template -PyObject* reprable::instance_repr(PyObject* obj) const -{ - return downcast(obj)->repr(); -} - - // Helper class for optimized allocation of PODs: If two PODs - // happen to contain identical byte patterns, they may share their - // memory. Reference counting is used to free unused memory. - // This is useful because method tables of related extension classes tend - // to be identical, so less memory is needed for them. - class BOOST_PYTHON_DECL shared_pod_manager - { - typedef std::pair holder; - typedef std::vector storage; - - public: - static shared_pod_manager& obj(); - ~shared_pod_manager(); - - // Allocate memory for POD T and fill it with zeros. - // This memory is initially not shared. - template - static void create(T*& t) - { - t = reinterpret_cast(obj().create(sizeof(T))); - } - - // Decrement the refcount for the memory t points to. If the count - // goes to zero, the memory is freed. - template - static void dispose(T* t) - { - obj().dec_ref(t, sizeof(T)); - } - - // Attempt to share the memory t points to. If memory with the same - // contents already exists, t is replaced by a pointer to this memory, - // and t's old memory is disposed. Otherwise, t will be registered for - // potential future sharing. - template - static void replace_if_equal(T*& t) - { - t = reinterpret_cast(obj().replace_if_equal(t, sizeof(T))); - } - - // Create a copy of t's memory that is guaranteed to be private to t. - // Afterwards t points to the new memory, unless it was already private, in - // which case there is no change (except that t's memory will no longer - // be considered for future sharing - see raplade_if_equal()) - // This function *must* be called before the contents of (*t) can - // be overwritten. Otherwise, inconsistencies and crashes may result. - template - static void make_unique_copy(T*& t) - { - t = reinterpret_cast(obj().make_unique_copy(t, sizeof(T))); - } - - private: - void* replace_if_equal(void* pod, std::size_t size); - void* make_unique_copy(void* pod, std::size_t size); - void* create(std::size_t size); - void dec_ref(void* pod, std::size_t size); - void erase_from_list(void* pod); - - struct compare; - struct identical; - - private: - shared_pod_manager() {} // instance - -#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - public: -#endif - storage m_storage; - }; - - - BOOST_PYTHON_DECL void add_capability(type_object_base::capability capability, - PyTypeObject* dest); - -// This macro gets the length of an array as a compile-time constant, and will -// fail to compile if the parameter is a pointer. -#ifdef __BORLANDC__ // smart implementation doesn't work for borland; maybe someone knows a workaround? -# define PY_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) -#else -# define PY_ARRAY_LENGTH(a) \ - (sizeof(::boost::python::detail::countof_validate(a, &(a))) ? sizeof(a) / sizeof((a)[0]) : 0) -#endif - - template - inline void countof_validate(T* const, T* const*); - - template - inline int countof_validate(const void*, T); - -}}} // namespace boost::python::detail - -#endif // TYPES_DWA051800_H_ diff --git a/include/boost/python/detail/void_adaptor.hpp b/include/boost/python/detail/void_adaptor.hpp deleted file mode 100644 index 3b4b2124..00000000 --- a/include/boost/python/detail/void_adaptor.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. - -#ifndef VOID_ADAPTOR_DWA20011112_HPP -# define VOID_ADAPTOR_DWA20011112_HPP - -namespace boost { namespace python { namespace detail { - - extern BOOST_PYTHON_DECL PyObject arbitrary_object; - - template - struct void_adaptor - { - typedef PyObject* result_type; - - void_adaptor(T const& f) - : m_f(f) - {} - - PyObject* operator()() const - { - m_f(); - return &arbitrary_object; - } - private: - T m_f; - }; - - template - void_adaptor make_void_adaptor(T const& f) - { - return void_adaptor(f); - } -}}} // namespace boost::python::detail - -#endif // VOID_ADAPTOR_DWA20011112_HPP - diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp deleted file mode 100644 index 0424183d..00000000 --- a/include/boost/python/detail/wrap_function.hpp +++ /dev/null @@ -1,56 +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 WRAP_FUNCTION_DWA2002118_HPP -# define WRAP_FUNCTION_DWA2002118_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// A function which converts its argument into a Python callable -// object. Not very general yet! - -// This should eventually be replaced with a mechanism for specialized -// wrap/unwrap objects. In other words, to_python(f), where f is a -// function pointer or function type, should produce a callable Python -// object. - -template -struct wrap_function_select -{ - template - static objects::function* execute(F f) - { - return make_function(f); - } -}; - -template<> -struct wrap_function_select -{ - template - static F execute(F f) - { - return f; - } -}; - -template -PyObject* wrap_function(F f) -{ - return wrap_function_select< - type_traits::ice_or< - is_function::value - , is_member_function_pointer::value - >::value >::execute(f); -} - -}}} // namespace boost::python::detail - -#endif // WRAP_FUNCTION_DWA2002118_HPP diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp deleted file mode 100644 index 3807eae1..00000000 --- a/include/boost/python/detail/wrap_python.hpp +++ /dev/null @@ -1,120 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// This file serves as a wrapper around which allows it to be -// compiled with GCC 2.95.2 under Win32 and which disables the default MSVC -// behavior so that a program may be compiled in debug mode without requiring a -// special debugging build of the Python library. - - -// To use the Python debugging library, #define BOOST_DEBUG_PYTHON on the -// compiler command-line. - -// Revision History: -// 05 Mar 01 Suppress warnings under Cygwin with Python 2.0 (Dave Abrahams) -// 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) -// 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) - - -#include - -#ifdef _DEBUG -# ifndef BOOST_DEBUG_PYTHON -# undef _DEBUG // Don't let Python force the debug library just because we're debugging. -# define DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H -# endif -#endif - -// -// Some things we need in order to get Python.h to work with compilers other -// than MSVC on Win32 -// -#if defined(_WIN32) || defined(__CYGWIN__) -# if defined(__GNUC__) && defined(__CYGWIN__) -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 -typedef int pid_t; -# define WORD_BIT 32 -# define hypot _hypot -# include -# if PY_MAJOR_VERSION < 2 -# define HAVE_CLOCK -# define HAVE_STRFTIME -# define HAVE_STRERROR -# endif -# define NT_THREADS -# if __GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3 -# define WITH_THREAD -# endif -# ifndef NETSCAPE_PI -# define USE_SOCKET -# endif - -# ifdef USE_DL_IMPORT -# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE -# endif - -# ifdef USE_DL_EXPORT -# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE -# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE -# endif - -# define HAVE_LONG_LONG 1 -# define LONG_LONG long long -# endif - -# elif defined(__MWERKS__) - -# ifndef _MSC_VER -# define PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H 1 -# define _MSC_VER 900 -# endif - -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2 -# include -# else -# include -# endif -# undef hypot // undo the evil #define left by Python. - -# elif defined(__BORLANDC__) -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2 -# include -# else -# include -# endif -# undef HAVE_HYPOT -# define HAVE_HYPOT 1 -# elif defined(_MSC_VER) -# ifdef __cplusplus -# include // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX -# endif -# endif - -#endif // _WIN32 - -#include - -#ifdef PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H -# undef _MSC_VER -#endif - -#ifdef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H -# undef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H -# define _DEBUG -#endif - -#if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 -# define PyObject_INIT(op, typeobj) \ - ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) -#endif - -#ifdef __MWERKS__ -# pragma warn_possunwant off -#elif _MSC_VER -# pragma warning(disable:4786) -#endif diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp deleted file mode 100644 index b9eb4363..00000000 --- a/include/boost/python/errors.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef ERRORS_DWA052500_H_ -# define ERRORS_DWA052500_H_ - -# include -# include -# include - -namespace boost { namespace python { - -struct error_already_set {}; -struct argument_error : error_already_set {}; - -// Handles exceptions caught just before returning to Python code. -// Returns true iff an exception was caught. -BOOST_PYTHON_DECL bool handle_exception_impl(function0); - -template -bool handle_exception(T f) -{ - return handle_exception_impl(function0(boost::ref(f))); -} - -BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x); - -template -T* expect_non_null(T* x) -{ - return (T*)expect_non_null((PyObject*)x); -} - -}} // namespace boost::python - -#endif // ERRORS_DWA052500_H_ diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp deleted file mode 100644 index 995f7877..00000000 --- a/include/boost/python/from_python.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_DWA2002128_HPP -# define FROM_PYTHON_DWA2002128_HPP - -# include -# include - -namespace boost { namespace python { - -template -struct from_python - : converter::from_python_lookup::type> -{ - typedef converter::from_python_lookup::type> base; - from_python(PyObject*); -}; - -// specialization for PyObject* -template <> -struct from_python -{ - from_python(PyObject*) {} - bool convertible() const { return true; } - PyObject* operator()(PyObject* source) const { return source; } -}; - -// -// implementations -// -template -from_python::from_python(PyObject* source) - : base(source) -{ -} - -}} // namespace boost::python - -#endif // FROM_PYTHON_DWA2002128_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp deleted file mode 100644 index 2943d96c..00000000 --- a/include/boost/python/make_function.hpp +++ /dev/null @@ -1,54 +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 MAKE_FUNCTION_DWA20011221_HPP -# define MAKE_FUNCTION_DWA20011221_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template -objects::function* make_function(F f) -{ - return new objects::function( - objects::py_function( - ::boost::bind(detail::caller(), f, _1, _2, default_call_policies())) - , detail::arg_tuple_size::value); -} - -template -objects::function* make_function(F f, Policies const& policies) -{ - return new objects::function( - objects::py_function( - ::boost::bind(detail::caller(), f, _1, _2, policies)) - , detail::arg_tuple_size::value); -} - -template -objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) -{ - enum { nargs = mpl::size::value }; - - return new objects::function( - objects::py_function( - ::boost::bind(detail::caller(), - objects::make_holder - ::template apply::execute - , _1, _2, default_call_policies())) - , nargs + 1); -} - -}} // namespace boost::python - -#endif // MAKE_FUNCTION_DWA20011221_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp deleted file mode 100644 index 3a243b06..00000000 --- a/include/boost/python/module.hpp +++ /dev/null @@ -1,111 +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 MODULE_DWA2001128_HPP -# define MODULE_DWA2001128_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template class class_; - -class BOOST_PYTHON_DECL module_base -{ - public: - // Create a module. REQUIRES: only one module is created per module. - module_base(const char* name); - ~module_base(); - - // Add elements to the module - void setattr(const char* name, PyObject*); - void setattr(const char* name, ref const&); - void add(PyTypeObject* x); // just use the type's name - void add_type(ref); - - // Return a reference to the Python module object being built - ref module() const; - - private: - ref m_module; - static PyMethodDef initial_methods[1]; -}; - -class module : public module_base -{ - public: - module(const char* name) - : module_base(name) {} - - // Add elements to the module - module& setattr(const char* name, PyObject*); - module& setattr(const char* name, PyTypeObject*); - module& setattr(const char* name, ref const&); - module& add(PyTypeObject* x); // just use the type's name - - template - module& add(class_ const& c) - { - Py_INCREF(c.object()); - this->add_type(c.object()); - return *this; - } - - template - module& def(char const* name, Fn fn) - { - this->setattr(name, boost::python::make_function(fn)); - return *this; - } - - - template - module& def(char const* name, Fn fn, ResultHandler handler) - { - this->setattr(name, boost::python::make_function(fn, handler)); - return *this; - } -}; - -// -// inline implementations -// -inline ref module_base::module() const -{ - return m_module; -} - -inline module& module::setattr(const char* name, PyObject* x) -{ - this->module_base::setattr(name, x); - return *this; -} - -inline module& module::setattr(const char* name, PyTypeObject* x) -{ - this->module_base::setattr(name, (PyObject*)x); - return *this; -} - -inline module& module::setattr(const char* name, ref const& x) -{ - this->module_base::setattr(name, x); - return *this; -} - -inline module& module::add(PyTypeObject* x) -{ - this->module_base::add(x); - return *this; -} - -}} // namespace boost::python - -#endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/module_builder.hpp b/include/boost/python/module_builder.hpp deleted file mode 100644 index 180a6200..00000000 --- a/include/boost/python/module_builder.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef MODULE_DWA051000_H_ -# define MODULE_DWA051000_H_ - -# include -# include -# include -# include - -namespace boost { namespace python { - -class BOOST_PYTHON_DECL module_builder_base -{ - public: - // Create a module. REQUIRES: only one module_builder is created per module. - module_builder_base(const char* name); - ~module_builder_base(); - - // Add elements to the module - void add(detail::function* x, const char* name); - void add(PyTypeObject* x, const char* name = 0); - void add(ref x, const char*name); - - // Return true iff a module is currently being built. - static bool initializing(); - - // Return the name of the module currently being built. - // REQUIRES: initializing() == true - static string name(); - - // Return a pointer to the Python module object being built - PyObject* module() const; - - private: - PyObject* m_module; - static PyMethodDef initial_methods[1]; -}; - -class module_builder : public module_builder_base -{ - public: - module_builder(const char* name) - : module_builder_base(name) {} - - template - void def_raw(Fn fn, const char* name) - { - add(detail::new_raw_arguments_function(fn), name); - } - - template - void def(Fn fn, const char* name) - { - add(detail::new_wrapped_function(fn), name); - } -}; - -// -// inline implementations -// -inline PyObject* module_builder_base::module() const -{ - return m_module; -} - -}} // namespace boost::python - -#endif diff --git a/include/boost/python/object/auto_ptr_generator.hpp b/include/boost/python/object/auto_ptr_generator.hpp deleted file mode 100644 index 9c13e436..00000000 --- a/include/boost/python/object/auto_ptr_generator.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef AUTO_PTR_GENERATOR_DWA2002123_HPP -# define AUTO_PTR_GENERATOR_DWA2002123_HPP -# include - -namespace boost { namespace python { namespace object { - -struct auto_ptr_generator -{ - template - struct apply - { - typedef std::auto_ptr type; - }; -}; - -}}} // namespace boost::python::object - -#endif // AUTO_PTR_GENERATOR_DWA2002123_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp deleted file mode 100644 index 53d886fa..00000000 --- a/include/boost/python/object/class.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_DWA20011214_HPP -# define CLASS_DWA20011214_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -class module; - -namespace objects { - -template struct holder; - -// To identify a class, we don't need cv/reference decorations -typedef converter::undecorated_type_id_t class_id; - -struct BOOST_PYTHON_DECL class_base : noncopyable -{ - // constructor - class_base( - char const* name // The name of the class - - , std::size_t num_types // A list of class_ids. The first is the type - , class_id const*const types // this is wrapping. The rest are the types of - // any bases. - ); - - // Retrieve the underlying object - ref object() const { return m_object; } - private: - ref m_object; -}; - -// Base class for all holders -struct BOOST_PYTHON_DECL instance_holder : noncopyable -{ - public: - instance_holder(); - virtual ~instance_holder(); - - // return the next holder in a chain - instance_holder* next() const; - - virtual void* holds(converter::type_id_t) = 0; - - void install(PyObject* inst) throw(); - - struct iterator_policies : default_iterator_policies - { - template - void increment(Iterator& p) - { - p.base() = p.base()->next(); - } - }; - - typedef iterator_adaptor< - instance_holder* - , iterator_policies - , value_type_is - , reference_is - , pointer_is - , iterator_category_is > iterator; - - private: - instance_holder* m_next; -}; - -// Each extension instance will be one of these -struct instance -{ - PyObject_HEAD - instance_holder* objects; -}; - -// Given a type_id, find the instance data which corresponds to it, or -// return 0 in case no such type is held. -BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t); - -template -T* find_instance(PyObject* p, T* = 0) -{ - return static_cast(find_instance_impl(p, converter::type_id())); -} - -BOOST_PYTHON_DECL ref class_metatype(); -BOOST_PYTHON_DECL ref class_type(); - -// -// implementation -// -inline instance_holder* instance_holder::next() const -{ - return m_next; -} - -}}} // namespace boost::python::objects - -#endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp deleted file mode 100644 index d5978af7..00000000 --- a/include/boost/python/object/class_converters.hpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_CONVERTERS_DWA2002119_HPP -# define CLASS_CONVERTERS_DWA2002119_HPP - -# include -# include -# include -# include - -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 -struct class_converters -{ - public: // member functions - // Constructor takes the python class object associated with T - class_converters(ref const& python_class); - - private: // data members - converter::class_from_python_converter m_unwrapper; - class_wrapper m_wrapper; -}; - -// -// Implementation details -// - -////////////////////////////////////////////////////////////////////// -// -// register_base_of - -// A BinaryMetaFunction object which registers a single base -// class of T, and the corresponding cast(s) -// - - -// register_downcast/do_nothing - -// Helpers for register_base_of<> which take care of registering -// down-casts -template -struct register_downcast -{ - static void execute() - { - register_conversion(true); - } -}; - -struct do_nothing -{ - static void execute() { } -}; - -// Here's where the real work gets done: -template -struct register_base_of -{ - // Ignored is needed because mpl::for_each is still actually - // accumulate. We're not using any state so it just sits there. - template - struct apply - { - typedef void type; // 'type' needs to be defined for the same reasons - - // Here's the runtime part: - static void execute() - { - // Register the Base class - register_dynamic_id(); - // Register the up-cast - register_conversion(false); - - // Register the down-cast, if appropriate. - mpl::select_type< - is_polymorphic::value - , register_downcast - , do_nothing - >::type::execute(); - } - }; -}; - -template -class_converters::class_converters(ref const& type_object) - : m_wrapper(type_object) -{ - // register all up/downcasts here - register_dynamic_id(); - - // register each base in the sequence - mpl::for_each >::execute(); -} - -}}} // namespace boost::python::object - -#endif // CLASS_CONVERTERS_DWA2002119_HPP diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp deleted file mode 100644 index 4a52f290..00000000 --- a/include/boost/python/object/class_wrapper.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_WRAPPER_DWA20011221_HPP -# define CLASS_WRAPPER_DWA20011221_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct class_wrapper - : to_python_converter > -{ - class_wrapper(ref const& type_) - : m_class_object_keeper(type_) - { - assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); - m_class_object = (PyTypeObject*)type_.get(); - } - - static PyObject* convert(T const& x) - { - // Don't call the type to do the construction, since that - // would require the registration of an __init__ copy - // constructor. Instead, just construct the object in place. - PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0); - - if (raw_result == 0) - return 0; - - // Everything's OK; Bypass NULL checks but guard against - // exceptions. - ref result(raw_result, ref::allow_null()); - - ((instance*)raw_result)->objects = 0; - - // Build a value_holder to contain the object using the copy - // constructor - value_holder* p = new value_holder(raw_result, cref(x)); - - // Install it in the instance - p->install(raw_result); - - // Return the new result - return result.release(); - } - - private: - ref m_class_object_keeper; - static PyTypeObject* m_class_object; -}; - -template -PyTypeObject* class_wrapper::m_class_object; - -}}} // namespace boost::python::objects - -#endif // CLASS_WRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/construct.hpp b/include/boost/python/object/construct.hpp deleted file mode 100644 index 1eb73e4a..00000000 --- a/include/boost/python/object/construct.hpp +++ /dev/null @@ -1,24 +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 CONSTRUCT_DWA20011215_HPP -# define CONSTRUCT_DWA20011215_HPP - -namespace boost { namespace python { namespace objects { - -template -struct construct -{ - static - template -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -// A little metaprogram which selects the type to pass through an -// intermediate forwarding function when the destination argument type -// is T. -template -struct forward -{ - BOOST_STATIC_CONSTANT( - bool, by_value = (is_scalar::value | is_reference::value) - ); - - typedef typename mpl::select_type< - by_value - , T - , reference_wrapper< - typename add_const::type - > - >::type type; -}; - -}}} // namespace boost::python::objects - -#endif // FORWARD_DWA20011215_HPP diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp deleted file mode 100644 index 2a05a946..00000000 --- a/include/boost/python/object/function.hpp +++ /dev/null @@ -1,51 +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 FUNCTION_DWA20011214_HPP -# define FUNCTION_DWA20011214_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -// We use boost::function to avoid generating lots of virtual tables -typedef boost::function2 py_function; - -struct BOOST_PYTHON_DECL function : PyObject -{ - function(py_function, unsigned min_args, unsigned max_args = 0); - ~function(); - - PyObject* call(PyObject*, PyObject*) const; - - // Add an attributeto the name_space with the given name. If it is - // a function object (this class), and an existing function is - // already there, add it as an overload. - static void add_to_namespace( - ref const& name_space, char const* name, ref const& attribute); - - private: // helper functions - void argument_error(PyObject* args, PyObject* keywords) const; - void add_overload(function*); - - private: // data members - py_function m_fn; - unsigned m_min_args; - unsigned m_max_args; - function* m_overloads; -}; - -extern BOOST_PYTHON_DECL PyTypeObject function_type; - -// -// implementations -// - -}}} // namespace boost::python::objects - -#endif // FUNCTION_DWA20011214_HPP diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp deleted file mode 100644 index 60aeda58..00000000 --- a/include/boost/python/object/inheritance.hpp +++ /dev/null @@ -1,165 +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 INHERITANCE_DWA200216_HPP -# define INHERITANCE_DWA200216_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -typedef converter::undecorated_type_id_t class_id; -using converter::undecorated_type_id; - -// Types used to get address and id of most derived type -typedef std::pair dynamic_id_t; -typedef dynamic_id_t (*dynamic_id_function)(void*); - -BOOST_PYTHON_DECL void register_dynamic_id_aux( - class_id static_id, dynamic_id_function get_dynamic_id); - -BOOST_PYTHON_DECL void add_cast( - class_id src_t, class_id dst_t, void* (*cast)(void*), bool polymorphic); - -BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst); - -BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst); - -// is_polymorphic test from John Maddock -template -struct is_polymorphic -{ - struct d1 : public T - { - d1(); - char padding[256]; - }; - struct d2 : public T - { - d2(); - virtual ~d2(); - virtual void foo(); - char padding[256]; - }; - BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1))); -}; - -// -// a generator with an execute() function which, given a source type -// and a pointer to an object of that type, returns its most-derived -// /reachable/ type identifier and object pointer. -// - -// first, the case where T has virtual functions -template -struct polymorphic_id_generator -{ - static dynamic_id_t execute(void* p_) - { - T* p = static_cast(p_); - return std::make_pair(dynamic_cast(p), class_id(typeid(*p))); - } -}; - -// now, the non-polymorphic case. -template -struct non_polymorphic_id_generator -{ - static dynamic_id_t execute(void* p_) - { - return std::make_pair(p_, converter::undecorated_type_id()); - } -}; - -// Now the generalized selector -template -struct dynamic_id_generator -{ - typedef typename mpl::select_type< - is_polymorphic::value - , polymorphic_id_generator - , non_polymorphic_id_generator >::type type; -}; - -// Register the dynamic id function for T with the type-conversion -// system. -template -void register_dynamic_id(T* = 0) -{ - typedef typename dynamic_id_generator::type generator; - register_dynamic_id_aux( - converter::undecorated_type_id(), &generator::execute); -} - -// -// a generator with an execute() function which, given a void* -// pointing to an object of type Source will attempt to convert it to -// an object of type Target. -// - -template -struct dynamic_cast_generator -{ - static void* execute(void* source) - { - return dynamic_cast( - static_cast(source)); - } - -}; - -template -struct implicit_cast_generator -{ - static void* execute(void* source) - { - Target* result = static_cast(source); - return result; - } -}; - -template -struct cast_generator -{ - // CWPro7 will return false sometimes, but that's OK since we can - // always cast up with dynamic_cast<> - BOOST_STATIC_CONSTANT( - bool, is_upcast = ( - is_base_and_derived::value - )); - - typedef typename mpl::select_type< - is_upcast -# if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - // grab a few more implicit_cast cases for CodeWarrior - || !is_polymorphic::value - || !is_polymorphic::value -# endif - , implicit_cast_generator - , dynamic_cast_generator - >::type type; -}; - -template -inline void register_conversion( - // We need this parameter because CWPro7 can't determine - // which is the base reliably. - bool is_downcast = !cast_generator::is_upcast - - // These parameters shouldn't be used, they're an MSVC bug workaround - , Source* = 0, Target* = 0) -{ - typedef typename cast_generator::type generator; - - add_cast(converter::undecorated_type_id() - , converter::undecorated_type_id() - , &generator::execute - , is_downcast); -} - -}}} // namespace boost::python::object - -#endif // INHERITANCE_DWA200216_HPP diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp deleted file mode 100644 index 8a72a880..00000000 --- a/include/boost/python/object/make_holder.hpp +++ /dev/null @@ -1,98 +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 MAKE_HOLDER_DWA20011215_HPP -# define MAKE_HOLDER_DWA20011215_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template struct make_holder; - -template <> -struct make_holder<0> -{ - template - struct apply - { - typedef typename detail::eval::type holder; - static void execute( - PyObject* p) - { - (new holder(p))->install(p); - } - }; -}; - - -template <> -struct make_holder<1> -{ - template - struct apply - { - typedef typename detail::eval::type holder; - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - - static void execute( - PyObject* p - , t0 a0) - { - (new holder(p, f0(a0)))->install(p); - } - }; -}; - -template <> -struct make_holder<2> -{ - template - struct apply - { - typedef typename detail::eval::type holder; - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - - static void execute( - PyObject* p, t0 a0, t1 a1) - { - (new holder(p, f0(a0), f1(a1)))->install(p); - } - }; -}; - -template <> -struct make_holder<3> -{ - template - struct apply - { - typedef typename detail::eval::type holder; - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - - static void execute( - PyObject* p, t0 a0, t1 a1, t2 a2) - { - (new holder(p, f0(a0), f1(a1), f2(a2)))->install(p); - } - }; -}; - -}}} // namespace boost::python::objects - -#endif // MAKE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp deleted file mode 100644 index 81fcac0c..00000000 --- a/include/boost/python/object/pointer_holder.hpp +++ /dev/null @@ -1,201 +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 POINTER_HOLDER_DWA20011215_HPP -# define POINTER_HOLDER_DWA20011215_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct pointer_holder : instance_holder -{ - pointer_holder(Pointer); - - // Forward construction to the held object - pointer_holder(PyObject*) - : m_p(new Value) {} - - - template - pointer_holder(PyObject*, A1 a1) - : m_p(new Value( - (unwrap_reference::type&)(a1) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - )) {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - )) {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) - , (unwrap_reference::type&)(a10) - )) - {} - - private: // required holder implementation - void* holds(converter::type_id_t); - - private: // data members - Pointer m_p; -}; - -}}} - -// back to namespace boost for this forward declaration -namespace boost -{ - template class shared_ptr; -} - -namespace boost { namespace python { namespace objects { - -struct shared_ptr_generator -{ - template - struct apply - { - typedef boost::shared_ptr type; - }; -}; - -// A generator metafunction which can be passed to make_holder -// PointerGenerator should be another generator metafunction which -// makes the appropriate (smart) pointer type to hold the argument to -// pointer_holder_generator. -template -struct pointer_holder_generator -{ - template - struct apply - { - typedef typename detail::eval::type pointer; - typedef pointer_holder type; - }; -}; - -template -pointer_holder::pointer_holder(Pointer p) - : m_p(p) -{ -} - -template -void* pointer_holder::holds(converter::type_id_t dst_t) -{ - if (dst_t == converter::type_id()) - return &this->m_p; - - converter::type_id_t src_t = converter::type_id(); - return src_t == dst_t ? &*this->m_p - : find_dynamic_type(&*this->m_p, src_t, dst_t); -} - -}}} // namespace boost::python::objects - -#endif // POINTER_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp deleted file mode 100644 index 85e3797f..00000000 --- a/include/boost/python/object/value_holder.hpp +++ /dev/null @@ -1,163 +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 VALUE_HOLDER_DWA20011215_HPP -# define VALUE_HOLDER_DWA20011215_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct value_holder : instance_holder -{ - // Forward construction to the held object - value_holder(PyObject*) - : m_held() {} - - template - value_holder(PyObject*, A1 a1) - : m_held( - (unwrap_reference::type&)(a1) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - ) {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - ) {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) - , (unwrap_reference::type&)(a10) - ) - {} - - private: // required holder implementation - void* holds(converter::type_id_t); - - private: // data members - Held m_held; -}; - -// A generator metafunction which can be passed to make_holder -struct value_holder_generator -{ - template - struct apply - { - typedef value_holder type; - }; -}; - -template -void* value_holder::holds(converter::type_id_t dst_t) -{ - converter::type_id_t src_t = converter::type_id(); - return src_t == dst_t ? &m_held - : find_static_type(&m_held, src_t, dst_t); -} - -}}} // namespace boost::python::objects - -#endif // VALUE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp deleted file mode 100644 index 8b230478..00000000 --- a/include/boost/python/objects.hpp +++ /dev/null @@ -1,395 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef OBJECTS_DWA051100_H_ -# define OBJECTS_DWA051100_H_ - -# include -# include -# include -# include "boost/operators.hpp" -# include - -namespace boost { namespace python { - -class BOOST_PYTHON_DECL object -{ - public: - explicit object(ref p); - - // Return a reference to the held object - ref reference() const; - - // Return a raw pointer to the held object - PyObject* get() const; - - private: - ref m_p; -}; - -class tuple; - -class BOOST_PYTHON_DECL tuple_base : public object -{ - public: - explicit tuple_base(std::size_t n = 0); - explicit tuple_base(ref p); - - static PyTypeObject* type_obj(); - static bool accepts(ref p); - std::size_t size() const; - ref operator[](std::size_t pos) const; - - void set_item(std::size_t pos, const ref& rhs); - - tuple slice(int low, int high) const; - - friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&); - friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&); -}; - -class tuple : public tuple_base -{ - public: - explicit tuple(std::size_t n = 0) : tuple_base(n) {} - explicit tuple(ref p) : tuple_base(p) {} - - template - tuple(const std::pair& x) - : tuple_base(ref(PyTuple_New(2))) - { - set_item(0, x.first); - set_item(1, x.second); - } - - template - tuple(const First& first, const Second& second) - : tuple_base(ref(PyTuple_New(2))) - { - set_item(0, first); - set_item(1, second); - } - - template - tuple(const First& first, const Second& second, const Third& third) - : tuple_base(ref(PyTuple_New(3))) - { - set_item(0, first); - set_item(1, second); - set_item(2, third); - } - - template - tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth) - : tuple_base(ref(PyTuple_New(4))) - { - set_item(0, first); - set_item(1, second); - set_item(2, third); - set_item(3, fourth); - } - - template - void set_item(std::size_t pos, const T& rhs) - { - this->set_item(pos, make_ref(rhs)); - } - - void set_item(std::size_t pos, const ref& rhs) - { - tuple_base::set_item(pos, rhs); - } -}; - -class list; - -struct BOOST_PYTHON_DECL list_proxy; -struct BOOST_PYTHON_DECL list_slice_proxy; - -class BOOST_PYTHON_DECL list_base : public object -{ - protected: - typedef list_proxy proxy; - typedef list_slice_proxy slice_proxy; - public: - explicit list_base(ref p); - explicit list_base(std::size_t sz = 0); - static PyTypeObject* type_obj(); - static bool accepts(ref p); - std::size_t size() const; - ref operator[](std::size_t pos) const; - proxy operator[](std::size_t pos); - ref get_item(std::size_t pos) const; - - void set_item(std::size_t pos, const ref& ); - -// void set_item(std::size_t pos, const object& ); - - void insert(std::size_t index, const ref& item); - - void push_back(const ref& item); - - void append(const ref& item); - - list slice(int low, int high) const; - slice_proxy slice(int low, int high); - void sort(); - void reverse(); - tuple as_tuple() const; -}; - -class list : public list_base -{ - public: - explicit list(ref p) : list_base(p) {} - explicit list(std::size_t sz = 0) : list_base(sz) {} - template - void set_item(std::size_t pos, const T& x) - { this->set_item(pos, make_ref(x)); } - template - void insert(std::size_t index, const T& x) - { this->insert(index, make_ref(x)); } - template - void push_back(const T& item) - { this->push_back(make_ref(item)); } - template - void append(const T& item) - { this->append(make_ref(item)); } - - void set_item(std::size_t pos, const ref& x) { list_base::set_item(pos, x); } - void insert(std::size_t index, const ref& item) { list_base::insert(index, item); } - void push_back(const ref& item) { list_base::push_back(item); } - void append(const ref& item) { list_base::append(item); } -}; - -class BOOST_PYTHON_DECL string - : public object, public boost::multipliable2 -{ - public: - // Construct from an owned PyObject*. - // Precondition: p must point to a python string. - explicit string(ref p); - explicit string(const char* s); - string(const char* s, std::size_t length); - string(const string& rhs); - - enum interned_t { interned }; - string(const char* s, interned_t); - - // Get the type object for Strings - static PyTypeObject* type_obj(); - - // Return true if the given object is a python string - static bool accepts(ref o); - - // Return the length of the string. - std::size_t size() const; - - // Returns a null-terminated representation of the contents of string. - // The pointer refers to the internal buffer of string, not a copy. - // The data must not be modified in any way. It must not be de-allocated. - const char* c_str() const; - - string& operator*=(unsigned int repeat_count); - string& operator+=(const string& rhs); - friend string operator+(string x, string y); - string& operator+=(const char* rhs); - friend string operator+(string x, const char* y); - friend string operator+(const char* x, string y); - - void intern(); - - friend string operator%(const string& format, const tuple& args); -}; - -class dictionary; - -struct BOOST_PYTHON_DECL dictionary_proxy; - -class BOOST_PYTHON_DECL dictionary_base : public object -{ - protected: - typedef dictionary_proxy proxy; - - public: - explicit dictionary_base(ref p); - dictionary_base(); - void clear(); - - static PyTypeObject* type_obj(); - static bool accepts(ref p); - - public: - proxy operator[](ref key); - ref operator[](ref key) const; - ref get_item(const ref& key) const; - ref get_item(const ref& key, const ref& default_) const; - - void set_item(const ref& key, const ref& value); - - void erase(ref key); - -// proxy operator[](const object& key); -// ref operator[](const object& key) const; - -// ref get_item(const object& key, ref default_ = ref()) const; -// void set_item(const object& key, const ref& value); - -// void erase(const object& key); - - list items() const; - list keys() const; - list values() const; - - std::size_t size() const; - // TODO: iterator support -}; - -struct BOOST_PYTHON_DECL dictionary_proxy -{ - template - const ref& operator=(const T& rhs) - { return (*this) = make_ref(rhs); } - const ref& operator=(const ref& rhs); - - operator ref() const; - private: - friend class dictionary_base; - dictionary_proxy(const ref& dict, const ref& key); - - // This is needed to work around the very strange MSVC error report that the - // return type of the built-in operator= differs from that of the ones - // defined above. Couldn't hurt to make these un-assignable anyway, though. - const ref& operator=(const dictionary_proxy&); // Not actually implemented - private: - ref m_dict; - ref m_key; -}; - -class dictionary : public dictionary_base -{ - typedef dictionary_proxy proxy; - public: - explicit dictionary(ref p) : dictionary_base(p) {} - dictionary() : dictionary_base() {} - - template - proxy operator[](const Key& key) - { return this->operator[](make_ref(key)); } - proxy operator[](ref key) - { return dictionary_base::operator[](key); } - - template - ref operator[](const Key& key) const - { return this->operator[](make_ref(key)); } - ref operator[](ref key) const - { return dictionary_base::operator[](key); } - - template - ref get_item(const Key& key) const - { return this->get_item(make_ref(key)); } - ref get_item(const ref& key) const - { return dictionary_base::get_item(key); } - - template - ref get_item(const Key& key, const Default& default_) const - { return this->get_item(make_ref(key), make_ref(default_)); } - ref get_item(const ref& key, const ref& default_) const - { return dictionary_base::get_item(key, default_); } - - template - void set_item(const Key& key, const Value& value) - { this->set_item(make_ref(key), make_ref(value)); } - void set_item(const ref& key, const ref& value) - { dictionary_base::set_item(key, value); } - - template - void erase(const Key& key) - { this->erase(make_ref(key)); } - void erase(ref key) - { dictionary_base::erase(key); } -}; - -struct BOOST_PYTHON_DECL list_proxy -{ - template - const ref& operator=(const T& rhs) - { return (*this) = make_ref(rhs); } - const ref& operator=(const ref& rhs); - - operator ref() const; - - private: - friend class list_base; - list_proxy(const ref& list, std::size_t index); - - // This is needed to work around the very strange MSVC error report that the - // return type of the built-in operator= differs from that of the ones - // defined above. Couldn't hurt to make these un-assignable anyway, though. - const ref& operator=(const list_proxy&); // Not actually implemented - private: - list m_list; - std::size_t m_index; -}; - -struct BOOST_PYTHON_DECL list_slice_proxy -{ - const list& operator=(const list& rhs); - operator ref() const; - operator list() const; - std::size_t size() const; - ref operator[](std::size_t pos) const; - private: - friend class list_base; - list_slice_proxy(const ref& list, int low, int high); - private: - ref m_list; - int m_low, m_high; -}; - -}} // namespace boost::python - -# ifndef BOOST_PYTHON_V2 - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple&); -BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type); - -inline boost::python::tuple from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list&); -BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type); - -inline boost::python::list from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string&); -BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type); - -inline boost::python::string from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary&); -BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type); - -inline boost::python::dictionary from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE -# endif -#endif // OBJECTS_DWA051100_H_ diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp deleted file mode 100644 index c766c8b6..00000000 --- a/include/boost/python/operators.hpp +++ /dev/null @@ -1,549 +0,0 @@ -// (C) Copyright Ullrich Koethe and David Abrahams 2000-2001. Permission to -// copy, use, modify, sell and distribute this software is granted provided -// this copyright notice appears in all copies. This software is provided "as -// is" without express or implied warranty, and with no claim as to its -// suitability for any purpose. -// -// The authors gratefully acknowlege the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 23 Jan 2001 - Another stupid typo fix by Ralf W. Grosse-Kunstleve (David Abrahams) -// 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams) -#ifndef OPERATORS_UK112000_H_ -#define OPERATORS_UK112000_H_ - -# include -# include - -// When STLport is used with native streams, _STL::ostringstream().str() is not -// _STL::string, but std::string. This confuses to_python(), so we'll use -// strstream instead. Also, GCC 2.95.2 doesn't have sstream. -# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) -# define BOOST_PYTHON_USE_SSTREAM -# endif - -#if defined(BOOST_PYTHON_USE_SSTREAM) -# include -# else -# include -# endif - -namespace boost { namespace python { - -BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r); - -namespace detail { - - // helper class for automatic operand type detection - // during operator wrapping. - struct auto_operand {}; -} - -// Define operator ids that can be or'ed together -// (boost::python::op_add | boost::python::op_sub | boost::python::op_mul). -// This allows to wrap several operators in one line. -enum operator_id -{ - op_add = 0x1, - op_sub = 0x2, - op_mul = 0x4, - op_div = 0x8, - op_mod = 0x10, - op_divmod =0x20, - op_pow = 0x40, - op_lshift = 0x80, - op_rshift = 0x100, - op_and = 0x200, - op_xor = 0x400, - op_or = 0x800, - op_neg = 0x1000, - op_pos = 0x2000, - op_abs = 0x4000, - op_invert = 0x8000, - op_int = 0x10000, - op_long = 0x20000, - op_float = 0x40000, - op_str = 0x80000, - op_cmp = 0x100000, - op_gt = 0x200000, - op_ge = 0x400000, - op_lt = 0x800000, - op_le = 0x1000000, - op_eq = 0x2000000, - op_ne = 0x4000000 -}; - -// Wrap the operators given by "which". Usage: -// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>()); -template -struct operators {}; - -// Wrap heterogeneous operators with given left operand type. Usage: -// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), -// boost::python::left_operand()); -template -struct left_operand {}; - -// Wrap heterogeneous operators with given right operand type. Usage: -// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), -// boost::python::right_operand()); -template -struct right_operand {}; - -namespace detail -{ - template - struct operand_select - { - template - struct wrapped - { - typedef Specified type; - }; - }; - - template <> - struct operand_select - { - template - struct wrapped - { - typedef const wrapped_type& type; - }; - }; - - template struct define_operator; - - // Base class which grants access to extension_class_base::add_method() to its derived classes - struct add_operator_base - { - protected: - static inline void add_method(extension_class_base* target, function* method, const char* name) - { target->add_method(method, name); } - }; - -// -// choose_op, choose_unary_op, and choose_rop -// -// These templates use "poor man's partial specialization" to generate the -// appropriate add_method() call (if any) for a given operator and argument set. -// -// Usage: -// choose_op<(which & op_add)>::template args::add(ext_class); -// -// (see extension_class<>::def_operators() for more examples). -// - template - struct choose_op - { - template - struct args : add_operator_base - { - static inline void add(extension_class_base* target) - { - typedef define_operator def_op; - add_method(target, - new typename def_op::template operator_function(), - def_op::name()); - } - - }; - }; - - // specialization for 0 has no effect - template <> - struct choose_op<0> - { - template - struct args - { - static inline void add(extension_class_base*) - { - } - - }; - }; - - template - struct choose_unary_op - { - template - struct args : add_operator_base - { - static inline void add(extension_class_base* target) - { - typedef define_operator def_op; - add_method(target, - new typename def_op::template operator_function(), - def_op::name()); - } - - }; - }; - - // specialization for 0 has no effect - template <> - struct choose_unary_op<0> - { - template - struct args - { - static inline void add(extension_class_base*) - { - } - - }; - }; - - template - struct choose_rop - { - template - struct args : add_operator_base - { - static inline void add(extension_class_base* target) - { - typedef define_operator def_op; - add_method(target, - new typename def_op::template roperator_function(), - def_op::rname()); - } - - }; - }; - - // specialization for 0 has no effect - template <> - struct choose_rop<0> - { - template - struct args - { - static inline void add(extension_class_base*) - { - } - - }; - }; - - -// Fully specialize define_operator for all operators defined in operator_id above. -// Every specialization defines one function object for normal operator calls and one -// for operator calls with operands reversed ("__r*__" function variants). -// Specializations for most operators follow a standard pattern: execute the expression -// that uses the operator in question. This standard pattern is realized by the following -// macros so that the actual specialization can be done by just calling a macro. -#define PY_DEFINE_BINARY_OPERATORS(id, oper) \ - template <> \ - struct define_operator \ - { \ - template \ - struct operator_function : function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - tuple args(ref(arguments, ref::increment_count)); \ - \ - return BOOST_PYTHON_CONVERSION::to_python( \ - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) oper \ - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type())); \ - } \ - \ - const char* description() const \ - { return "__" #id "__"; } \ - }; \ - \ - template \ - struct roperator_function : function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - tuple args(ref(arguments, ref::increment_count)); \ - \ - return BOOST_PYTHON_CONVERSION::to_python( \ - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) oper \ - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type())); \ - } \ - \ - const char* description() const \ - { return "__r" #id "__"; } \ - \ - }; \ - \ - static const char * name() { return "__" #id "__"; } \ - static const char * rname() { return "__r" #id "__"; } \ - } - -#define PY_DEFINE_UNARY_OPERATORS(id, oper) \ - template <> \ - struct define_operator \ - { \ - template \ - struct operator_function : function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - tuple args(ref(arguments, ref::increment_count)); \ - \ - return BOOST_PYTHON_CONVERSION::to_python( \ - oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); \ - } \ - \ - const char* description() const \ - { return "__" #id "__"; } \ - }; \ - \ - static const char * name() { return "__" #id "__"; } \ - } - - PY_DEFINE_BINARY_OPERATORS(add, +); - PY_DEFINE_BINARY_OPERATORS(sub, -); - PY_DEFINE_BINARY_OPERATORS(mul, *); - PY_DEFINE_BINARY_OPERATORS(div, /); - PY_DEFINE_BINARY_OPERATORS(mod, %); - PY_DEFINE_BINARY_OPERATORS(lshift, <<); - PY_DEFINE_BINARY_OPERATORS(rshift, >>); - PY_DEFINE_BINARY_OPERATORS(and, &); - PY_DEFINE_BINARY_OPERATORS(xor, ^); - PY_DEFINE_BINARY_OPERATORS(or, |); - PY_DEFINE_BINARY_OPERATORS(gt, >); - PY_DEFINE_BINARY_OPERATORS(ge, >=); - PY_DEFINE_BINARY_OPERATORS(lt, <); - PY_DEFINE_BINARY_OPERATORS(le, <=); - PY_DEFINE_BINARY_OPERATORS(eq, ==); - PY_DEFINE_BINARY_OPERATORS(ne, !=); - - PY_DEFINE_UNARY_OPERATORS(neg, -); - PY_DEFINE_UNARY_OPERATORS(pos, +); - PY_DEFINE_UNARY_OPERATORS(abs, abs); - PY_DEFINE_UNARY_OPERATORS(invert, ~); - PY_DEFINE_UNARY_OPERATORS(int, long); - PY_DEFINE_UNARY_OPERATORS(long, PyLong_FromLong); - PY_DEFINE_UNARY_OPERATORS(float, double); - -#undef PY_DEFINE_BINARY_OPERATORS -#undef PY_DEFINE_UNARY_OPERATORS - -// Some operators need special treatment, e.g. because there is no corresponding -// expression in C++. These are specialized manually. - -// pow(): Manual specialization needed because an error message is required if this -// function is called with three arguments. The "power modulo" operator is not -// supported by define_operator, but can be wrapped manually (see special.html). - template <> - struct define_operator - { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type) - { - PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3"); - throw argument_error(); - } - - return BOOST_PYTHON_CONVERSION::to_python( - pow(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()), - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()))); - } - - const char* description() const - { return "__pow__"; } - - }; - - template - struct roperator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type) - { - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()"); - throw argument_error(); - } - - return BOOST_PYTHON_CONVERSION::to_python( - pow(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()), - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); - } - - const char* description() const - { return "__rpow__"; } - - }; - - static const char * name() { return "__pow__"; } - static const char * rname() { return "__rpow__"; } - }; - -// divmod(): Manual specialization needed because we must actually call two operators and -// return a tuple containing both results - template <> - struct define_operator - { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - PyObject * res = PyTuple_New(2); - - PyTuple_SET_ITEM(res, 0, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) / - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()))); - PyTuple_SET_ITEM(res, 1, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) % - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()))); - - return res; - } - - const char* description() const - { return "__divmod__"; } - - }; - - template - struct roperator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - PyObject * res = PyTuple_New(2); - - PyTuple_SET_ITEM(res, 0, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) / - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); - PyTuple_SET_ITEM(res, 1, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) % - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); - - return res; - } - - const char* description() const - { return "__rdivmod__"; } - - }; - - static const char * name() { return "__divmod__"; } - static const char * rname() { return "__rdivmod__"; } - }; - -// cmp(): Manual specialization needed because there is no three-way compare in C++. -// It is implemented by two one-way comparisons with operators reversed in the second. - template <> - struct define_operator - { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - return BOOST_PYTHON_CONVERSION::to_python( - (BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type())) ? - - 1 : - (BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type())) ? - 1 : - 0) ; - } - - const char* description() const - { return "__cmp__"; } - - }; - - template - struct roperator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - return BOOST_PYTHON_CONVERSION::to_python( - (BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type())) ? - - 1 : - (BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type())) ? - 1 : - 0) ; - } - - const char* description() const - { return "__rcmp__"; } - - }; - - static const char * name() { return "__cmp__"; } - static const char * rname() { return "__rcmp__"; } - }; - -# ifndef BOOST_PYTHON_USE_SSTREAM - class unfreezer { - public: - unfreezer(std::ostrstream& s) : m_stream(s) {} - ~unfreezer() { m_stream.freeze(false); } - private: - std::ostrstream& m_stream; - }; -# endif - -// str(): Manual specialization needed because the string conversion does not follow -// the standard pattern relized by the macros. - template <> - struct define_operator - { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject*) const - { - tuple args(ref(arguments, ref::increment_count)); - -// When STLport is used with native streams, _STL::ostringstream().str() is not -// _STL::string, but std::string. -# ifdef BOOST_PYTHON_USE_SSTREAM - std::ostringstream s; - s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()); - return BOOST_PYTHON_CONVERSION::to_python(s.str()); -# else - std::ostrstream s; - s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) << char(); - auto unfreezer unfreeze(s); - return BOOST_PYTHON_CONVERSION::to_python(const_cast(s.str())); -# endif - } - - const char* description() const - { return "__str__"; } - - }; - - static const char * name() { return "__str__"; } - }; - - -} // namespace detail - -}} // namespace boost::python - -# undef BOOST_PYTHON_USE_SSTREAM -#endif /* OPERATORS_UK112000_H_ */ diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp deleted file mode 100644 index 97edef99..00000000 --- a/include/boost/python/reference.hpp +++ /dev/null @@ -1,241 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef PYPTR_DWA050400_H_ -# define PYPTR_DWA050400_H_ - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# ifndef BOOST_PYTHON_V2 -# include - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -template -struct py_ptr_conversions : Base -{ - inline friend T from_python(PyObject* x, boost::python::type) - { return T(boost::python::downcast(x).get(), T::increment_count); } - - inline friend T from_python(PyObject* x, boost::python::type) - { return T(boost::python::downcast(x).get(), T::increment_count); } - - inline friend PyObject* to_python(T x) - { return boost::python::as_object(x.release()); } - -}; - -BOOST_PYTHON_END_CONVERSION_NAMESPACE -# endif - -namespace boost { namespace python { - -# ifndef BOOST_PYTHON_V2 -BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions); -# endif - -template -class reference -# ifndef BOOST_PYTHON_V2 - : public py_ptr_conversions, T> -# endif -{ -public: - typedef T value_type; - - reference(const reference& rhs) - : m_p(rhs.m_p) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); - } - - reference() : m_p(0) {} - - // These are two ways of spelling the same thing, that we need to increment - // the reference count on the pointer when we're initialized. - enum increment_count_t { increment_count }; - - enum allow_null { null_ok }; - - template - explicit reference(T2* x) - : m_p(expect_non_null(x)) - { - assert(m_p->ob_refcnt > 0); - } - - template - reference(T2* x, increment_count_t) - : m_p(expect_non_null(x)) - { - assert(m_p->ob_refcnt > 0); - Py_INCREF(m_p); - } - - template - reference(T2* x, allow_null) - : m_p(x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - reference(T2* x, allow_null, increment_count_t) - : m_p(x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); - } - - template - reference(T2* x, increment_count_t, allow_null) - : m_p(x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); - } - - reference& operator=(const reference& rhs) - { - assert(rhs.m_p == 0 || rhs.m_p->ob_refcnt > 0); - Py_XINCREF(static_cast(rhs.m_p)); - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = rhs.m_p; - return *this; - } - - ~reference() - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - } - - T& operator*() const - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - return *m_p; - } - - // MSVC doesn't like boost::dereferencable unless T has a default - // constructor, so operator-> must be defined by hand :( - T* operator->() const - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - return &**this; - } - - T* get() const - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - return m_p; - } - - T* release() - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - T* p = m_p; - m_p = 0; - return p; - } - - void reset() - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = 0; - } - - template - void reset(T2* x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = expect_non_null(x); - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, increment_count_t) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(x); - Py_XDECREF(m_p); - m_p = expect_non_null(x); - assert(m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, allow_null) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = x; - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, allow_null, increment_count_t) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(x); - Py_XDECREF(m_p); - m_p = x; - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, increment_count_t, allow_null) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(x); - Py_XDECREF(m_p); - m_p = x; - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) -private: - template friend class shared_ptr; -#endif - - inline PyObject* object() const - { -#ifdef BOOST_PYTHON_V2 - return (PyObject*)( - (char*)&m_p->ob_type - offsetof(PyObject,ob_type)); -#else - return as_object(m_p); -#endif - } - - T* m_p; -}; - -typedef reference ref; - -#ifndef BOOST_PYTHON_V2 -template -ref make_ref(const T& x) -{ - return ref(to_python(x)); -} -#endif - -}} // namespace boost::python - -#endif // PYPTR_DWA050400_H_ diff --git a/include/boost/python/reference_from_python.hpp b/include/boost/python/reference_from_python.hpp deleted file mode 100644 index a9631dc5..00000000 --- a/include/boost/python/reference_from_python.hpp +++ /dev/null @@ -1,62 +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 REFERENCE_FROM_PYTHON_DWA2002130_HPP -# define REFERENCE_FROM_PYTHON_DWA2002130_HPP - -# include -# include - -namespace boost { namespace python { - -// Utility which produces a member extractor function on platforms -// other than VC6. -template -struct get_member -{ - static Member& execute(Class* c) - { - return c->*mp; - } -}; - -template < - PyTypeObject const* python_type - , class Value - , class PythonObject - , class Extract - > -struct reference_from_python -{ - typedef type_from_python convertible_t; - - reference_from_python() - : m_mutable_converter( - &convertible_t::convertible, convert_mutable) - - , m_const_converter( - &convertible_t::convertible, convert_const) - {} - - static Value& convert_mutable(PyObject* op, converter::from_python_data&) - { - return Extract::execute(*(PythonObject*)op); - } - - static Value const& convert_const(PyObject* op, converter::from_python_data&) - { - return Extract::execute(*(PythonObject*)op); - } - - private: - typedef converter::from_python_converter mutable_converter; - typedef converter::from_python_converter const_converter; - mutable_converter m_mutable_converter; - const_converter m_const_converter; -}; - -}} // namespace boost::python - -#endif // REFERENCE_FROM_PYTHON_DWA2002130_HPP diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp deleted file mode 100644 index ac7f3fbf..00000000 --- a/include/boost/python/return_internal_reference.hpp +++ /dev/null @@ -1,45 +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 RETURN_INTERNAL_REFERENCE_DWA2002131_HPP -# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct return_internal_reference_requires_a_pointer_or_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -}; - -struct internal_reference_to_python_generator -{ - template - struct apply - { - typedef typename mpl::select_type< - !is_object::value - , internal_reference_to_python - , detail::return_internal_reference_requires_a_pointer_or_reference_return_type - >::type type; - }; -}; - -template -struct return_internal_reference : Base -{ - typedef wrap_internal_reference result_converter; -}; - -}} // namespace boost::python - -#endif // RETURN_INTERNAL_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/return_value_policy.hpp b/include/boost/python/return_value_policy.hpp deleted file mode 100644 index 0beec47b..00000000 --- a/include/boost/python/return_value_policy.hpp +++ /dev/null @@ -1,20 +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 RETURN_VALUE_POLICY_DWA2002131_HPP -# define RETURN_VALUE_POLICY_DWA2002131_HPP -# include - -namespace boost { namespace python { - -template -struct return_value_policy : Base -{ - typedef Handler result_converter; -}; - -}} // namespace boost::python - -#endif // RETURN_VALUE_POLICY_DWA2002131_HPP diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp deleted file mode 100644 index 6bea9822..00000000 --- a/include/boost/python/to_python_converter.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_CONVERTER_DWA200221_HPP -# define TO_PYTHON_CONVERTER_DWA200221_HPP - -# include -# include -# include - -namespace boost { namespace python { - -template -struct to_python_converter -{ - to_python_converter(); -}; - -// -// implementation -// - -template -to_python_converter::to_python_converter() -{ - typedef converter::as_to_python_value_function< - T, Derived - > normalized; - - converter::registry::insert( - &normalized::convert - , converter::undecorated_type_id()); -} - -}} // namespace boost::python - -#endif // TO_PYTHON_CONVERTER_DWA200221_HPP diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp deleted file mode 100644 index a222e9a9..00000000 --- a/include/boost/python/to_python_value.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_VALUE_DWA200221_HPP -# define TO_PYTHON_VALUE_DWA200221_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template -struct to_python_value -{ - typedef typename add_reference< - typename add_const::type - >::type argument_type; - - static bool convertible(); - PyObject* operator()(argument_type) const; - - private: - // Note that this is a pointer to a function pointer - static converter::to_python_value_function const* fconvert; -}; - - -template -converter::to_python_value_function const* -to_python_value::fconvert - = &converter::registry::to_python_function(converter::undecorated_type_id()); - - -template -bool to_python_value::convertible() -{ - // if this assert fires, our static variable hasn't been set up yet. - assert(fconvert != 0); - return *fconvert != 0; -} - -template -PyObject* to_python_value::operator()(argument_type x) const -{ - // This might be further optimized on platforms which dynamically - // link without specific imports/exports - converter::to_python_value_function f = *fconvert; - return f(&x); -} - -}} // namespace boost::python - -#endif // TO_PYTHON_VALUE_DWA200221_HPP diff --git a/include/boost/python/type_from_python.hpp b/include/boost/python/type_from_python.hpp deleted file mode 100644 index 46d59d13..00000000 --- a/include/boost/python/type_from_python.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TYPE_FROM_PYTHON_DWA2002130_HPP -# define TYPE_FROM_PYTHON_DWA2002130_HPP - -namespace boost { namespace python { - -template -struct type_from_python -{ - static void* convertible(PyObject* op) - { - return PyObject_TypeCheck( - op, const_cast(python_type)) ? op : 0; - } -}; - -}} // namespace boost::python - -#endif // TYPE_FROM_PYTHON_DWA2002130_HPP diff --git a/include/boost/python/value_from_python.hpp b/include/boost/python/value_from_python.hpp deleted file mode 100644 index 0ff80323..00000000 --- a/include/boost/python/value_from_python.hpp +++ /dev/null @@ -1,72 +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 VALUE_FROM_PYTHON_DWA2002130_HPP -# define VALUE_FROM_PYTHON_DWA2002130_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -template -struct value_from_python -{ - typedef converter::from_python_check from_python_check; - - value_from_python(from_python_check convertible) - : m_converter( - convertible - , &Derived::convert - - // Change this to a compile-time check later to avoid - // generating destroy function - , has_trivial_destructor::value ? 0 : &Derived::destroy - ) - { - } - - value_from_python() - : m_converter( - &Derived::convertible - , &Derived::convert - - // Change this to a compile-time check later to avoid - // generating destroy function - , has_trivial_destructor::value ? 0 : &Derived::destroy - ) - { - } - - static void* get_storage(converter::from_python_data& data) - { - return converter::get_storage(data); - } - - // Mark successful construction - static void constructed(converter::from_python_data& data) - { - data.stage1 = get_storage(data); - } - - inline static void destroy(converter::from_python_data& data) - { - // Get the location of the storage for - void* storage = get_storage(data); - - // Check for successful construction - if (data.stage1 == storage) - static_cast(storage)->~T(); - } - - private: - converter::from_python_converter m_converter; -}; - -}} // namespace boost::python - -#endif // VALUE_FROM_PYTHON_DWA2002130_HPP diff --git a/release_notes.txt b/release_notes.txt deleted file mode 100644 index 8932a0aa..00000000 --- a/release_notes.txt +++ /dev/null @@ -1,217 +0,0 @@ -2000-11-22 10:00 - Ullrich fixed bug in operator_dispatcher. - -2000-11-21 10:00 - Changed all class and function names into lower_case. - - Ullrich updated documentation for operator wrapping. - -2000-11-20 10:00 - Ullrich renamed ExtensionClass:register_coerce() into - ExtensionClass:def_standard_coerce() and made it public - - Ullrich improved shared_pod_manager. - -2000-11-17 15:04 - Changed allocation strategy of shared_pod_manager to make it portable. - - Added pickling support + tests thanks to "Ralf W. Grosse-Kunstleve" - - - Added a specialization of Callback to prevent unsafe usage. - - Fixed Ullrich's operator_dispatcher refcount bug - - Removed const char* return values from virtual functions in tests; that - usage was unsafe. - - Ullrich changed Module::add() so that it steals a reference (fix of refcount bug) - - Ullrich added operator_dispatcher::create() optimization - - Ullrich changed design and implementation of TypeObjectBase::enable() (to eliminate low-level - code) and added shared_pod_manager optimization. - - -2000-11-15 12:01 - Fixed refcount bugs in operator calls. - - Added callback_adjust_refcount(PyObject*, Type) to account for different ownership - semantics of Callback's return types and Caller's arguments (which both use from_python()) - This bug caused refcount errors during operator calls. - - Moved operator_dispatcher into extclass.cpp - Gave it shared ownership of the objects it wraps - - Introduced sequence points in extension_class_coerce for exception-safety - - UPPER_CASE_MACRO_NAMES - - MixedCase template type argument names - - Changed internal error reporting to use Python exceptions so we don't force the - user to link in iostreams code - - Changed error return value of call_cmp to -1 - - Moved unwrap_* functions out of operator_dispatcher. This was transitional: when - I realized they didn't need to be declared in extclass.h I moved them out, but - now that operator_dispatcher itself is in extclass.cpp they could go back in. - - Numerous formatting tweaks - - Updated the BoundFunction::create() optimization and enabled it so it could actually be used! - -2000-11-15 00:26 - - Made Ullrich's operators support work with MSVC - - Cleaned up operators.h such that invalid define_operator<0> is no longer needed. - - Ullrich created operators.h to support wrapping of C++ operators (including the "__r*__" forms). - He added several auxiliary classes to extclass.h and extclass.cpp (most importantly, - py::detail::operator_dispatcher and py::operators) - -2000-11-13 22:29 - - removed obsolete ExtensionClassFromPython for good. - - removed unused class ExtensionType forward declaration - -2000-11-12 13:08 - - Added enum_as_int_converters for easier enum wrapping - - Introduced new conversion namespace macros: - PY_BEGIN_CONVERSION_NAMESPACE, - PY_END_CONVERSION_NAMESPACE, - PY_CONVERSION - - callback.h, gen_callback.py: - Added call() function so that a regular python function (as opposed to - method or other function-as-attribute) can be called. - - Added newlines for readability. - - class_wrapper.h: - Fixed a bug in add(), which allows non-method class attributes - - Ullrich has added def_raw for simple varargs and keyword support. - - Fixed version number check for __MWERKS__ - - Added tests for enums and non-method class attributes - - objects.h/objects.cpp: - Added py::String operator*= and operator* for repetition - - Change Dict::items(), keys(), and values() to return a List - - Added template versions of set_item, etc., methods so that users can optionally - use C++ types that have to_python() functions as parameters. - - Changed various Ptr by-value parameters to const Ptr& - - -======= Release ======= -2000-11-06 0:22 - Lots of documentation updates - - added 4-argument template constructor to py::Tuple - - added "add" member function to ClassWrapper<> to allow arbitrary Python - objects to be added to an extension class. - - gen_all.py now generates support for n argument member functions and n+1 - argument member functions at the suggestion of "Ralf W. Grosse-Kunstleve" - - - Added regression tests and re-ordered declare_base calls to verify that the - phantom base class issue is resolved. - -2000-11-04 17:35 - - Integrated Ullrich Koethe's brilliant from_python_experiment for better - error-reporting in many cases. - - extclass.h, gen_extclass.py: - removed special-case MSVC code - added much commentary - removed unused py_copy_to_new_value_holder - - init_function.h, gen_init_function.py: - added missing 'template' keyword on type-dependent template member usage - removed special-case MSVC code - added much commentary - -2000-11-04 0:36 - - Removed the need for the phantom base class that screwed up inheritance - hierarchies, introduced error-prone ordering dependencies, and complexified - logic in many places! - - extclass.h: Added some explanatory comments, removed wasteful m_self member - of HeldInstance - - extclass_demo.cpp: Added #pragmas which allow compilation in ansi strict - mode under Metrowerks - - functions.h: Added virtual_function as part of phantom base class removal; - expanded commentary - - pyptr.h: Added some missing 'typename's and a GCC workaround fix - - subclass.cpp: Added missing string literal const_cast<>s. - -2000-11-03 10:58 - - Fix friend function instantiation bug caught by Metrowerks (thanks - Metrowerks!) - - Add proof-of-concept for one technique of wrapping function that return a - pointer - - Worked around MSVC optimizer bug by writing to_python(double) and - to_python(float) out-of-line - -2000-11-02 23:25 - - Add /Zm200 option to vc6_prj to deal with MSVC resource limitations - - Remove conflicting /Ot option from vc6_prj release build - -======= Release ======= -2000-11-02 17:42 - - Added a fix for interactions between default virtual function - implementations and declare_base(). You still need to write your - declare_base() /after/ all member functions have been def()d for the two - classes concerned. Many, many thanks to Ullrich Koethe - for all his work on this. - - Added missing conversions: - to_python(float) - from_python(const char* const&) - from_python(const double&) - from_python(const float&) - - Added a Regression test for a reference-counting bug thanks to Mark Evans - () - - const-ify ClassBase::getattr() - - Add repr() function to Class - - Add to_python/from_python conversions for PyPtr - - Standardize set_item/get_item interfaces (instead of proxies) for Dict and List - - Add Reprable<> template to newtypes.h - - Fix a bug wherein the __module__ attribute would be lost for classes that have a - default virtual function implementation. - - Remove extra ';' in module.cpp thanks to "Ralf W. Grosse-Kunstleve" - - - Fix a bug in the code of example1.html diff --git a/src/classes.cpp b/src/classes.cpp deleted file mode 100644 index b018c0ce..00000000 --- a/src/classes.cpp +++ /dev/null @@ -1,1039 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 04 Mar 01 Rolled in const_cast from Dragon fork (Dave Abrahams) -// 03 Mar 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) -// 03 Mar 01 bug fix: use bound_function::create() (instead of new bound_function) - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace detail { - void enable_named_method(boost::python::detail::class_base* type_obj, const char* name); -} - -namespace { - // Add the name of the module currently being loaded to the name_space with the - // key "__module__". If no module is being loaded, or if name_space already has - // a key "__module", has no effect. This is not really a useful public - // interface; it's just used for class_t<>::class_t() below. - void add_current_module_name(dictionary&); - - bool is_prefix(const char* s1, const char* s2); - bool is_special_name(const char* name); - void enable_special_methods(boost::python::detail::class_base* derived, const tuple& bases, const dictionary& name_space); - - void report_ignored_exception(PyObject* source) - { - // This bit of code copied wholesale from classobject.c in the Python source. - PyObject *f, *t, *v, *tb; - PyErr_Fetch(&t, &v, &tb); - f = PySys_GetObject(const_cast("stderr")); - if (f != NULL) - { - PyFile_WriteString(const_cast("Exception "), f); - if (t) { - PyFile_WriteObject(t, f, Py_PRINT_RAW); - if (v && v != Py_None) { - PyFile_WriteString(const_cast(": "), f); - PyFile_WriteObject(v, f, 0); - } - } - PyFile_WriteString(const_cast(" in "), f); - PyFile_WriteObject(source, f, 0); - PyFile_WriteString(const_cast(" ignored\n"), f); - PyErr_Clear(); /* Just in case */ - } - Py_XDECREF(t); - Py_XDECREF(v); - Py_XDECREF(tb); - } - - // - // pickle support courtesy of "Ralf W. Grosse-Kunstleve" - // - PyObject* class_reduce(PyObject* klass) - { - return PyObject_GetAttrString(klass, const_cast("__name__")); - } - - ref global_class_reduce() - { - return ref(detail::new_wrapped_function(class_reduce)); - } - - - tuple instance_reduce(PyObject* obj) - { - ref instance_class(PyObject_GetAttrString(obj, const_cast("__class__"))); - - ref getinitargs(PyObject_GetAttrString(obj, const_cast("__getinitargs__")), - ref::null_ok); - PyErr_Clear(); - ref initargs; - if (getinitargs.get() != 0) - { - initargs = ref(PyEval_CallObject(getinitargs.get(), NULL)); - initargs = ref(PySequence_Tuple(initargs.get())); - } - else - { - initargs = ref(PyTuple_New(0)); - } - - ref getstate(PyObject_GetAttrString(obj, const_cast("__getstate__")), - ref::null_ok); - PyErr_Clear(); - - ref dict(PyObject_GetAttrString(obj, const_cast("__dict__")), ref::null_ok); - PyErr_Clear(); - - if (getstate.get() != 0) - { - if (dict.get() != 0 && dictionary(dict).size() > 0) - { - ref getstate_manages_dict(PyObject_GetAttrString(instance_class.get(), const_cast("__getstate_manages_dict__")), ref::null_ok); - PyErr_Clear(); - if (getstate_manages_dict.get() == 0) - { - PyErr_SetString(PyExc_RuntimeError, "Incomplete pickle support (__getstate_manages_dict__ not set)"); - throw error_already_set(); - } - } - - ref state = ref(PyEval_CallObject(getstate.get(), NULL)); - return tuple(instance_class, initargs, state); - } - - if (getinitargs.get() == 0) - { - ref dict_defines_state(PyObject_GetAttrString(instance_class.get(), const_cast("__dict_defines_state__")), ref::null_ok); - PyErr_Clear(); - if (dict_defines_state.get() == 0) - { - PyErr_SetString(PyExc_RuntimeError, "Incomplete pickle support (__dict_defines_state__ not set)"); - throw error_already_set(); - } - } - - if (dict.get() != 0 && dictionary(dict).size() > 0) - { - return tuple(instance_class, initargs, dict); - } - - return tuple(instance_class, initargs); - } - - ref global_instance_reduce() - { - return ref(detail::new_wrapped_function(instance_reduce)); - } -} - - -namespace detail { - - class_base::class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space) - : type_object_base(meta_class_obj), - m_name(name), - m_bases(bases), - m_name_space(name_space) - { - this->tp_name = const_cast(name.c_str()); - enable(type_object_base::getattr); - enable(type_object_base::setattr); - add_current_module_name(m_name_space); - static const boost::python::string docstr("__doc__", boost::python::string::interned); - if (PyDict_GetItem(m_name_space.get(), docstr.get())== 0) - { - PyDict_SetItem(m_name_space.get(), docstr.get(), Py_None); - } - enable_special_methods(this, bases, name_space); - } - - void class_base::add_base(ref base) - { - tuple new_bases(m_bases.size() + 1); - for (std::size_t i = 0; i < m_bases.size(); ++i) - new_bases.set_item(i, m_bases[i]); - new_bases.set_item(m_bases.size(), base); - m_bases = new_bases; - } - - PyObject* class_base::getattr(const char* name) - { - if (!BOOST_CSTD_::strcmp(name, "__dict__")) - { - PyObject* result = m_name_space.get(); - Py_INCREF(result); - return result; - } - - if (!BOOST_CSTD_::strcmp(name, "__bases__")) - { - PyObject* result = m_bases.get(); - Py_INCREF(result); - return result; - } - - if (!BOOST_CSTD_::strcmp(name, "__name__")) - { - PyObject* result = m_name.get(); - Py_INCREF(result); - return result; - } - - // pickle support courtesy of "Ralf W. Grosse-Kunstleve" - if (!BOOST_CSTD_::strcmp(name, "__safe_for_unpickling__")) - { - return PyInt_FromLong(1); - } - if (!BOOST_CSTD_::strcmp(name, "__reduce__")) - { - PyObject* self = as_object(this); - ref target(self, ref::increment_count); - return bound_function::create(target, global_class_reduce()); - } - - ref local_attribute = m_name_space.get_item(string(name).reference()); - - if (local_attribute.get()) - return local_attribute.release(); - - // In case there are no bases... - PyErr_SetString(PyExc_AttributeError, name); - - // Check bases - for (std::size_t i = 0; i < m_bases.size(); ++i) - { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) - PyErr_Clear(); // we're going to try a base class - else if (PyErr_Occurred()) - break; // Other errors count, though! - - PyObject* base_attribute = PyObject_GetAttrString(m_bases[i].get(), const_cast(name)); - - if (base_attribute != 0) - { - // Unwind the actual underlying function from unbound Python class - // methods in case of multiple inheritance from real Python - // classes. Python stubbornly insists that the first argument to a - // method must be a true Python instance object otherwise. Do not - // unwrap bound methods; that would interfere with intended semantics. - if (PyMethod_Check(base_attribute) - && reinterpret_cast(base_attribute)->im_self == 0) - { - PyObject* function - = reinterpret_cast(base_attribute)->im_func; - Py_INCREF(function); - Py_DECREF(base_attribute); - return function; - } - else - { - return base_attribute; - } - } - } - return 0; - } - - // Mostly copied wholesale from Python's classobject.c - PyObject* class_base::repr() const - { - PyObject *mod = PyDict_GetItemString( - m_name_space.get(), const_cast("__module__")); - unsigned long address = reinterpret_cast(this); - string result = (mod == NULL || !PyString_Check(mod)) - ? string("") % tuple(m_name, address) - : string("") % tuple(ref(mod, ref::increment_count), m_name, address); - return result.reference().release(); - } - - - int class_base::setattr(const char* name, PyObject* value) - { - if (is_special_name(name) - && BOOST_CSTD_::strcmp(name, "__doc__") != 0 - && BOOST_CSTD_::strcmp(name, "__name__") != 0) - { - boost::python::string message("Special attribute names other than '__doc__' and '__name__' are read-only, in particular: "); - PyErr_SetObject(PyExc_TypeError, (message + name).get()); - throw error_already_set(); - } - - if (PyCallable_Check(value)) - detail::enable_named_method(this, name); - - return PyDict_SetItemString( - m_name_space.reference().get(), const_cast(name), value); - } - - bool class_base::initialize_instance(instance* obj, PyObject* args, PyObject* keywords) - { - // Getting the init function off the obj should result in a - // bound method. - PyObject* const init_function = obj->getattr("__init__", false); - - if (init_function == 0) - { - if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); // no __init__? That's legal. - } - else { - return false; // Something else? Keep the error - } - } - else - { - // Manage the reference to the bound function - ref init_function_holder(init_function); - - // Declare a ref to manage the result of calling __init__ (which should be None). - ref init_result( - PyEval_CallObjectWithKeywords(init_function, args, keywords)); - } - return true; - } - - void class_base::instance_dealloc(PyObject* obj) const - { - Py_INCREF(obj); // This allows a __del__ function to revive the obj - - PyObject* exc_type; - PyObject* exc_value; - PyObject* exc_traceback; - PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); - - // This scope ensures that the reference held by del_function doesn't release - // the last reference and delete the object recursively (infinitely). - { - ref del_function; - try { - instance* const target = boost::python::downcast(obj); - del_function = ref(target->getattr("__del__", false), ref::null_ok); - } - catch(...) { - } - - if (del_function.get() != 0) - { - ref result(PyEval_CallObject(del_function.get(), (PyObject *)NULL), ref::null_ok); - - if (result.get() == NULL) - report_ignored_exception(del_function.get()); - } - } - PyErr_Restore(exc_type, exc_value, exc_traceback); - - if (--obj->ob_refcnt <= 0) - delete_instance(obj); - } - - -} - -instance::instance(PyTypeObject* class_) - : boost::python::detail::base_object(class_) -{ -} - -instance::~instance() -{ -} - -PyObject* instance::getattr(const char* name, bool use_special_function) -{ - if (!BOOST_CSTD_::strcmp(name, "__dict__")) - { - if (PyEval_GetRestricted()) { - PyErr_SetString(PyExc_RuntimeError, - "instance.__dict__ not accessible in restricted mode"); - return 0; - } - Py_INCREF(m_name_space.get()); - return m_name_space.get(); - } - - if (!BOOST_CSTD_::strcmp(name, "__class__")) - { - Py_INCREF(this->ob_type); - return as_object(this->ob_type); - } - - if (!BOOST_CSTD_::strcmp(name, "__reduce__")) - { - return detail::bound_function::create(ref(this, ref::increment_count), global_instance_reduce()); - } - - ref local_attribute = m_name_space.get_item(string(name).reference()); - - if (local_attribute.get()) - return local_attribute.release(); - - // Check its class. - PyObject* function = - PyObject_GetAttrString(as_object(this->ob_type), const_cast(name)); - - if (function == 0 && !use_special_function) - { - return 0; - } - - ref class_attribute; - if (function != 0) - { - // This will throw if the attribute wasn't found - class_attribute = ref(function); - } - else - { - // Clear the error while we try special methods method (if any). - PyErr_Clear(); - - // First we try the special method that comes from concatenating - // "__getattr__" and and 2 trailing underscores. This is an - // extension to regular Python class functionality. - const string specific_getattr_name(detail::getattr_string() + name + "__"); - PyObject* getattr_method = PyObject_GetAttr( - as_object(this->ob_type), specific_getattr_name.get()); - - // Use just the first arg to PyEval_CallFunction if found - char* arg_format = const_cast("(O)"); - - // Try for the regular __getattr__ method if not found - if (getattr_method == 0) - { - PyErr_Clear(); - getattr_method = PyObject_GetAttrString( - as_object(this->ob_type), const_cast("__getattr__")); - - // Use both args to PyEval_CallFunction - arg_format = const_cast("(Os)"); - } - - // If there is no such method, throw now. - if (PyErr_Occurred()) - { - PyErr_SetString(PyExc_AttributeError, name); - return 0; - } - - // Take ownership of the method - ref owner(getattr_method); - - // Call it to get the attribute. - return PyEval_CallFunction(getattr_method, arg_format, this, name); - } - - if (!PyCallable_Check(class_attribute.get())) - { - PyErr_Clear(); - return class_attribute.release(); - } - else - { - return detail::bound_function::create(ref(this, ref::increment_count), class_attribute); - } -} - -// instance::setattr_dict -// -// Implements setattr() functionality for the "__dict__" attribute -// -int instance::setattr_dict(PyObject* value) -{ - if (PyEval_GetRestricted()) - { - PyErr_SetString(PyExc_RuntimeError, - "__dict__ not accessible in restricted mode"); - return -1; - } - - if (value == 0 || !PyDict_Check(value)) - { - PyErr_SetString(PyExc_TypeError, - "__dict__ must be set to a dictionary"); - return -1; - } - m_name_space = dictionary(ref(value, ref::increment_count)); - return 0; -} - -// instance::setattr - -// -// Implements the setattr() and delattr() functionality for our own instance -// objects, using the standard Python interface: if value == 0, we are deleting -// the attribute, and returns 0 unless an error occurred. -int instance::setattr(const char* name, PyObject* value) -{ - if (BOOST_CSTD_::strcmp(name, "__class__") == 0) - { - PyErr_SetString(PyExc_TypeError, "__class__ attribute is read-only"); - throw error_already_set(); - } - - if (BOOST_CSTD_::strcmp(name, "__dict__") == 0) - return setattr_dict(value); - - // Try to find an appropriate "specific" setter or getter method, either - // __setattr____(value) or __delattr____(). This is an extension - // to regular Python class functionality. - const string& base_name = value ? detail::setattr_string() : detail::delattr_string(); - const string specific_method_name(base_name + name + "__"); - - ref special_method( - PyObject_GetAttr(as_object(this->ob_type), specific_method_name.get()), - ref::null_ok); - - PyObject* result_object = 0; - if (special_method.get() != 0) - { - // The specific function was found; call it now. Note that if value is - // not included in the format string, it is ignored. - char* format_string = const_cast(value ? "(OO)" : "(O)"); - result_object = PyEval_CallFunction(special_method.get(), format_string, this, value); - } - else - { - // If not found, try the usual __setattr__(name, value) or - // __delattr__(name) functions. - PyErr_Clear(); - special_method.reset( - PyObject_GetAttr(as_object(this->ob_type), base_name.get()), - ref::null_ok); - - if (special_method.get() != 0) - { - // The special function was found; call it now. Note that if value - // is not included in the format string, it is ignored. - char* format_string = const_cast(value ? "(OsO)" : "(Os)"); - result_object = PyEval_CallFunction( - special_method.get(), format_string, this, name, value); - } - } - - // If we found an appropriate special method, handle the return value. - if (special_method.get() != 0) - { - ref manage_result(result_object); - return 0; - } - - PyErr_Clear(); // Nothing was found; clear the python error state - - if (value == 0) // Try to remove the attribute from our name space - { - const int result = PyDict_DelItemString(m_name_space.reference().get(), - const_cast(name)); - if (result < 0) - { - PyErr_Clear(); - PyErr_SetString(PyExc_AttributeError, "delete non-existing instance attribute"); - } - return result; - } - else // Change the specified item in our name space - { - return PyDict_SetItemString(m_name_space.reference().get(), - const_cast(name), value); - } -} - -PyObject* instance::call(PyObject* args, PyObject* keywords) -{ - return PyEval_CallObjectWithKeywords( - ref(getattr("__call__")).get(), // take possession of the result from getattr() - args, keywords); -} - -PyObject* instance::repr() -{ - return callback::call_method(this, "__repr__"); -} - -int instance::compare(PyObject* other) -{ - return callback::call_method(this, "__cmp__", other); -} - -PyObject* instance::str() -{ - return callback::call_method(this, "__str__"); -} - -long instance::hash() -{ - return callback::call_method(this, "__hash__"); -} - -int instance::length() -{ - return callback::call_method(this, "__len__"); -} - -PyObject* instance::get_subscript(PyObject* key) -{ - return callback::call_method(this, "__getitem__", key); -} - -void instance::set_subscript(PyObject* key, PyObject* value) -{ - if (value == 0) - callback::call_method(this, "__delitem__", key); - else - callback::call_method(this, "__setitem__", key, value); -} - -PyObject* instance::get_slice(int start, int finish) -{ - return callback::call_method(this, "__getslice__", start, finish); -} - -void instance::set_slice(int start, int finish, PyObject* value) -{ - if (value == 0) - callback::call_method(this, "__delslice__", start, finish); - else - callback::call_method(this, "__setslice__", start, finish, value); -} - -PyObject* instance::add(PyObject* other) -{ - return callback::call_method(this, "__add__", other); -} - -PyObject* instance::subtract(PyObject* other) -{ - return callback::call_method(this, "__sub__", other); -} - -PyObject* instance::multiply(PyObject* other) -{ - return callback::call_method(this, "__mul__", other); -} - -PyObject* instance::divide(PyObject* other) -{ - return callback::call_method(this, "__div__", other); -} - -PyObject* instance::remainder(PyObject* other) -{ - return callback::call_method(this, "__mod__", other); -} - -PyObject* instance::divmod(PyObject* other) -{ - return callback::call_method(this, "__divmod__", other); -} - -PyObject* instance::power(PyObject* exponent, PyObject* modulus) -{ - if (as_object(modulus) == Py_None) - return callback::call_method(this, "__pow__", exponent); - else - return callback::call_method(this, "__pow__", exponent, modulus); -} - -PyObject* instance::negative() -{ - return callback::call_method(this, "__neg__"); -} - -PyObject* instance::positive() -{ - return callback::call_method(this, "__pos__"); -} - -PyObject* instance::absolute() -{ - return callback::call_method(this, "__abs__"); -} - -int instance::nonzero() -{ - return callback::call_method(this, "__nonzero__"); -} - -PyObject* instance::invert() -{ - return callback::call_method(this, "__invert__"); -} - -PyObject* instance::lshift(PyObject* other) -{ - return callback::call_method(this, "__lshift__", other); -} - -PyObject* instance::rshift(PyObject* other) -{ - return callback::call_method(this, "__rshift__", other); -} - -PyObject* instance::do_and(PyObject* other) -{ - return callback::call_method(this, "__and__", other); -} - -PyObject* instance::do_xor(PyObject* other) -{ - return callback::call_method(this, "__xor__", other); -} - -PyObject* instance::do_or(PyObject* other) -{ - return callback::call_method(this, "__or__", other); -} - -int instance::coerce(PyObject** x, PyObject** y) -{ - assert(this == *x); - - // Coerce must return a tuple - tuple result(callback::call_method(this, "__coerce__", *y)); - - *x = result[0].release(); - *y = result[1].release(); - return 0; -} - -PyObject* instance::as_int() -{ - return callback::call_method(this, "__int__"); -} - -PyObject* instance::as_long() -{ - return callback::call_method(this, "__long__"); -} - -PyObject* instance::as_float() -{ - return callback::call_method(this, "__float__"); -} - -PyObject* instance::oct() -{ - return callback::call_method(this, "__oct__"); -} - -PyObject* instance::hex() -{ - return callback::call_method(this, "__hex__"); -} - -PyObject* instance::lt(PyObject* other) -{ - return callback::call_method(this, "__lt__", other); -} - -PyObject* instance::le(PyObject* other) -{ - return callback::call_method(this, "__le__", other); -} - -PyObject* instance::eq(PyObject* other) -{ - return callback::call_method(this, "__eq__", other); -} - -PyObject* instance::ne(PyObject* other) -{ - return callback::call_method(this, "__ne__", other); -} - -PyObject* instance::gt(PyObject* other) -{ - return callback::call_method(this, "__gt__", other); -} - -PyObject* instance::ge(PyObject* other) -{ - return callback::call_method(this, "__ge__", other); -} - -PyObject* instance::inplace_add(PyObject* other) -{ - return callback::call_method(this, "__iadd__", other); -} - -PyObject* instance::inplace_subtract(PyObject* other) -{ - return callback::call_method(this, "__isub__", other); -} - -PyObject* instance::inplace_multiply(PyObject* other) -{ - return callback::call_method(this, "__imul__", other); -} - -PyObject* instance::inplace_divide(PyObject* other) -{ - return callback::call_method(this, "__idiv__", other); -} - -PyObject* instance::inplace_remainder(PyObject* other) -{ - return callback::call_method(this, "__imod__", other); -} - -PyObject* instance::inplace_power(PyObject* exponent, PyObject* modulus) -{ - if (modulus == Py_None) - return callback::call_method(this, "__ipow__", exponent); - else - return callback::call_method(this, "__ipow__", exponent, modulus); -} - -PyObject* instance::inplace_lshift(PyObject* other) -{ - return callback::call_method(this, "__ilshift__", other); -} - -PyObject* instance::inplace_rshift(PyObject* other) -{ - return callback::call_method(this, "__irshift__", other); -} - -PyObject* instance::inplace_and(PyObject* other) -{ - return callback::call_method(this, "__iand__", other); -} - -PyObject* instance::inplace_or(PyObject* other) -{ - return callback::call_method(this, "__ior__", other); -} - -PyObject* instance::inplace_xor(PyObject* other) -{ - return callback::call_method(this, "__ixor__", other); -} - -namespace { - struct named_capability - { - const char* name; - detail::type_object_base::capability capability; - }; - - const named_capability enablers[] = - { - { "__hash__", detail::type_object_base::hash }, - { "__cmp__", detail::type_object_base::compare }, - { "__gt__", detail::type_object_base::richcompare }, - { "__ge__", detail::type_object_base::richcompare }, - { "__lt__", detail::type_object_base::richcompare }, - { "__le__", detail::type_object_base::richcompare }, - { "__eq__", detail::type_object_base::richcompare }, - { "__ne__", detail::type_object_base::richcompare }, - { "__iadd__", detail::type_object_base::number_inplace_add }, - { "__isub__", detail::type_object_base::number_inplace_subtract }, - { "__imul__", detail::type_object_base::number_inplace_multiply }, - { "__idiv__", detail::type_object_base::number_inplace_divide }, - { "__imod__", detail::type_object_base::number_inplace_remainder }, - { "__ipow__", detail::type_object_base::number_inplace_power }, - { "__ilshift__", detail::type_object_base::number_inplace_lshift }, - { "__irshift__", detail::type_object_base::number_inplace_rshift }, - { "__iand__", detail::type_object_base::number_inplace_and }, - { "__ixor__", detail::type_object_base::number_inplace_xor }, - { "__ior__", detail::type_object_base::number_inplace_or }, - { "__repr__", detail::type_object_base::repr }, - { "__str__", detail::type_object_base::str }, - { "__call__", detail::type_object_base::call }, - { "__getattr__", detail::type_object_base::getattr }, - { "__setattr__", detail::type_object_base::setattr }, - { "__len__", detail::type_object_base::mapping_length }, - { "__len__", detail::type_object_base::sequence_length }, - { "__getitem__", detail::type_object_base::mapping_subscript }, - { "__getitem__", detail::type_object_base::sequence_item }, - { "__setitem__", detail::type_object_base::mapping_ass_subscript }, - { "__setitem__", detail::type_object_base::sequence_ass_item }, - { "__delitem__", detail::type_object_base::mapping_ass_subscript }, - { "__delitem__", detail::type_object_base::sequence_ass_item }, - { "__getslice__", detail::type_object_base::sequence_slice }, - { "__setslice__", detail::type_object_base::sequence_ass_slice }, - { "__delslice__", detail::type_object_base::sequence_ass_slice }, - { "__add__", detail::type_object_base::number_add }, - { "__sub__", detail::type_object_base::number_subtract }, - { "__mul__", detail::type_object_base::number_multiply }, - { "__div__", detail::type_object_base::number_divide }, - { "__mod__", detail::type_object_base::number_remainder }, - { "__divmod__", detail::type_object_base::number_divmod }, - { "__pow__", detail::type_object_base::number_power }, - { "__neg__", detail::type_object_base::number_negative }, - { "__pos__", detail::type_object_base::number_positive }, - { "__abs__", detail::type_object_base::number_absolute }, - { "__nonzero__", detail::type_object_base::number_nonzero }, - { "__invert__", detail::type_object_base::number_invert }, - { "__lshift__", detail::type_object_base::number_lshift }, - { "__rshift__", detail::type_object_base::number_rshift }, - { "__and__", detail::type_object_base::number_and }, - { "__xor__", detail::type_object_base::number_xor }, - { "__or__", detail::type_object_base::number_or }, - { "__coerce__", detail::type_object_base::number_coerce }, - { "__int__", detail::type_object_base::number_int }, - { "__long__", detail::type_object_base::number_long }, - { "__float__", detail::type_object_base::number_float }, - { "__oct__", detail::type_object_base::number_oct }, - { "__hex__", detail::type_object_base::number_hex } - }; - - bool is_prefix(const char* s1, const char* s2) - { - while (*s1 != 0 && *s2 != 0 && *s1 == *s2) - ++s1, ++s2; - return *s1 == 0; - } - - bool is_special_name(const char* name) - { - if (name[0] != '_' || name[1] != '_' || name[2] == 0 || name[3] == 0) - return false; - - std::size_t name_length = BOOST_CSTD_::strlen(name); - return name[name_length - 1] == '_' && name[name_length - 2] == '_'; - } -} - -namespace detail { - // Enable the special handler for methods of the given name, if any. - void enable_named_method(boost::python::detail::class_base* type_obj, const char* name) - { - const std::size_t num_enablers = PY_ARRAY_LENGTH(enablers); - - // Make sure this ends with "__" since we'll only compare the head of the - // string. This is done to make the __getattr____/__setattr____ - // extension work. - if (!is_special_name(name)) - return; - - for (std::size_t i = 0; i < num_enablers; ++i) - { - if (is_prefix(enablers[i].name + 2, name + 2)) - { - type_obj->enable(enablers[i].capability); - } - } - } -} - -namespace { - // Enable any special methods which are enabled in the base class. - void enable_special_methods(boost::python::detail::class_base* derived, const tuple& bases, const dictionary& name_space) - { - for (std::size_t i = 0; i < bases.size(); ++i) - { - PyObject* base = bases[i].get(); - - for (std::size_t n = 0; n < PY_ARRAY_LENGTH(enablers); ++n) - { - ref attribute( - PyObject_GetAttrString(base, const_cast(enablers[n].name)), - ref::null_ok); - PyErr_Clear(); - if (attribute.get() != 0 && PyCallable_Check(attribute.get())) - detail::add_capability(enablers[n].capability, derived); - } - } - - list keys(name_space.keys()); - for (std::size_t j = 0, len = keys.size(); j < len; ++j) - { - string name_obj(keys.get_item(j)); - const char* name = name_obj.c_str(); - - if (!is_special_name(name)) - continue; - - for (std::size_t i = 0; i < PY_ARRAY_LENGTH(enablers); ++i) - { - if (is_prefix(enablers[i].name + 2, name + 2)) - { - detail::add_capability(enablers[i].capability, derived); - } - } - } - } - - void add_current_module_name(dictionary& name_space) - { - static string module_key("__module__", string::interned); - - // If the user didn't specify a __module__ attribute already - if (name_space.get_item(module_key).get() == 0) - { - if (module_builder::initializing()) - { - // The global __name__ is not properly set in this case - name_space.set_item(module_key, module_builder::name()); - } - else - { - // Get the module name from the global __name__ - PyObject *globals = PyEval_GetGlobals(); - if (globals != NULL) - { - PyObject *module_name = PyDict_GetItemString(globals, const_cast("__name__")); - if (module_name != NULL) - name_space.set_item(module_key, module_name); - } - } - } - } -} - -BOOST_PYTHON_DECL void adjust_slice_indices(PyObject* obj, int& start, int& finish) -{ - int length = callback::call_method(obj, "__len__"); - - // This is standard Python class behavior. - if (start < 0) - start += length; - if (finish < 0) - finish += length; - - // This is not - if (start < 0) - start = 0; - if (finish < 0) - finish = 0; -} - -namespace detail { -const string& setattr_string() -{ - static string x("__setattr__", string::interned); - return x; -} - -const string& getattr_string() -{ - static string x("__getattr__", string::interned); - return x; -} - -const string& delattr_string() -{ - static string x("__delattr__", string::interned); - return x; -} -} - -}} // namespace boost::python diff --git a/src/conversions.cpp b/src/conversions.cpp deleted file mode 100644 index e6b6161a..00000000 --- a/src/conversions.cpp +++ /dev/null @@ -1,240 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 05 Apr 01 added: from_python std::string type checking (rwgk) -// 12 Mar 01 Python 1.5.2 fixes (Ralf W. Grosse-Kunstleve) -// 11 Mar 01 std::string *MAY* include nulls (Alex Martelli) -// 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams) -// 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include -#ifndef BOOST_NO_LIMITS -# include -#endif - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type) -{ - // Why am I clearing the error here before trying to convert? I know there's a reason... - long result; - { - result = PyInt_AsLong(p); - if (PyErr_Occurred()) - throw boost::python::argument_error(); - } - return result; -} - -BOOST_PYTHON_DECL double from_python(PyObject* p, boost::python::type) -{ - double result; - { - result = PyFloat_AsDouble(p); - if (PyErr_Occurred()) - throw boost::python::argument_error(); - } - return result; -} - -template -T integer_from_python(PyObject* p, boost::python::type) -{ - const long long_result = from_python(p, boost::python::type()); - -#ifndef BOOST_NO_LIMITS - try - { - return boost::numeric_cast(long_result); - } - catch(const boost::bad_numeric_cast&) -#else - if (static_cast(long_result) == long_result) - { - return static_cast(long_result); - } - else -#endif - { - char buffer[256]; - const char message[] = "%ld out of range for %s"; - sprintf(buffer, message, long_result, typeid(T).name()); - PyErr_SetString(PyExc_ValueError, buffer); - throw boost::python::argument_error(); - } -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return 0; // Not smart enough to know that the catch clause always rethrows -#endif -} - -template -PyObject* integer_to_python(T value) -{ - long value_as_long; - -#ifndef BOOST_NO_LIMITS - try - { - value_as_long = boost::numeric_cast(value); - } - catch(const boost::bad_numeric_cast&) -#else - value_as_long = static_cast(value); - if (value_as_long != value) -#endif - { - const char message[] = "value out of range for Python int"; - PyErr_SetString(PyExc_ValueError, message); - throw boost::python::error_already_set(); - } - - return to_python(value_as_long); -} - -BOOST_PYTHON_DECL int from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned int i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL unsigned int from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL short from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL float from_python(PyObject* p, boost::python::type) -{ - return static_cast(from_python(p, boost::python::type())); -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned short i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL unsigned short from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(char c) -{ - if (c == '\0') return PyString_FromString(""); - return PyString_FromStringAndSize(&c, 1); -} - -BOOST_PYTHON_DECL char from_python(PyObject* p, boost::python::type) -{ - int l = -1; - if (PyString_Check(p)) l = PyString_Size(p); - if (l < 0 || l > 1) { - PyErr_SetString(PyExc_TypeError, "expected string of length 0 or 1"); - throw boost::python::argument_error(); - } - if (l == 0) return '\0'; - return PyString_AsString(p)[0]; -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned char i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL unsigned char from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(signed char i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL signed char from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned long x) -{ - return integer_to_python(x); -} - -BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL void from_python(PyObject* p, boost::python::type) -{ - if (p != Py_None) { - PyErr_SetString(PyExc_TypeError, "expected argument of type None"); - throw boost::python::argument_error(); - } -} - -BOOST_PYTHON_DECL const char* from_python(PyObject* p, boost::python::type) -{ - const char* s = PyString_AsString(p); - if (!s) - throw boost::python::argument_error(); - return s; -} - -BOOST_PYTHON_DECL PyObject* to_python(const std::string& s) -{ - return PyString_FromStringAndSize(s.data(), s.size()); -} - -BOOST_PYTHON_DECL std::string from_python(PyObject* p, boost::python::type) -{ - if (! PyString_Check(p)) { - PyErr_SetString(PyExc_TypeError, "expected a string"); - throw boost::python::argument_error(); - } - return std::string(PyString_AsString(p), PyString_Size(p)); -} - -BOOST_PYTHON_DECL bool from_python(PyObject* p, boost::python::type) -{ - int value = from_python(p, boost::python::type()); - if (value == 0) - return false; - return true; -} - -#ifdef BOOST_MSVC6_OR_EARLIER -// An optimizer bug prevents these from being inlined. -BOOST_PYTHON_DECL PyObject* to_python(double d) -{ - return PyFloat_FromDouble(d); -} - -BOOST_PYTHON_DECL PyObject* to_python(float f) -{ - return PyFloat_FromDouble(f); -} -#endif // BOOST_MSVC6_OR_EARLIER - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - diff --git a/src/converter/body.cpp b/src/converter/body.cpp deleted file mode 100644 index 637f8c3e..00000000 --- a/src/converter/body.cpp +++ /dev/null @@ -1,18 +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. -#include - -namespace boost { namespace python { namespace converter { - -// default implementation is a no-op. Most handles will not hold any -// data that needs to be managed. Unwrap objects which convert -// by-value are an exception. Fortunately, the concrete body subclass -// has that knowledge. -void body::destroy_handle(handle*) const -{ -} - -}}} // namespace boost::python::converter diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp deleted file mode 100644 index 26834635..00000000 --- a/src/converter/builtin_converters.cpp +++ /dev/null @@ -1,226 +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. - -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include - -namespace boost { namespace python { namespace converter { - -namespace -{ - // Only an object which we know is holding a char const* can be - // converted to one - struct convertible_to_cstring - { - static unaryfunc* execute(PyObject* obj) - { - return PyString_Check(obj) ? &obj->ob_type->tp_str : 0; - } - }; - - struct extract_cstring - { - static char const* execute(PyObject* obj) - { - return PyString_AsString(obj); - } - }; - - // Any object which can be converted to a Python string can also be - // converted to a C++ string, since the latter owns its bytes. - struct convertible_to_string - { - static unaryfunc* execute(PyObject* obj) - { - return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0; - } - }; - - // Transform a function returning a unaryfunc* into one that returns a void* - template - struct return_void_ptr - { - static void* execute(PyObject* p) { return F::execute(p); } - }; - - template < - class T // The target type - , class Convertible // returns a pointer to a unaryfunc producing an object - , class TExtract // ...from which TExtract extracts T's constructor argument - > - struct tp_scalar_from_python - : from_python_converter - { - private: - typedef return_void_ptr convertible_fn; - - public: - tp_scalar_from_python() - : from_python_converter( - &convertible_fn::execute - , convert) - {} - - static T convert(PyObject* obj, from_python_data& data) - { - unaryfunc converter = *(unaryfunc*)data.stage1; - ref converted(converter(obj)); - return TExtract::execute(converted.get()); - } - }; - - // Extract a reference to T using the functions in the source - // object's type slots - template < - class T // The target type - , class Convertible // returns a pointer to a unaryfunc producing an object - , class TExtract // ...from which TExtract extracts T's constructor argument - > - struct tp_cref_from_python - : value_from_python > - { - private: - typedef value_from_python > base; - - public: - tp_cref_from_python() - : base(&return_void_ptr::execute) - {} - - static T const& convert(PyObject* obj, from_python_data& data) - { - unaryfunc converter = *(unaryfunc*)data.stage1; - - void* storage = get_storage(data); - - ref converted(converter(obj)); - - T* const p = new (storage) T(TExtract::execute(converted.get())); - - // note that construction is successful. - data.stage1 = p; - - return *p; - } - }; - - struct convertible_to_int - { - static unaryfunc* execute(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - // For floating types, return the float conversion slot to avoid - // creating a new object. We'll handle that in - // py_int_or_float_as_long, below - if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float) - return &number_methods->nb_float; - - return number_methods && number_methods->nb_int - ? &number_methods->nb_int : 0; - } - }; - - struct py_int_or_float_as_long - { - static long execute(PyObject* obj) - { - if (PyObject_TypeCheck(obj, &PyFloat_Type)) - { - return numeric_cast(PyFloat_AS_DOUBLE(obj)); - } - else - { - return PyInt_AS_LONG(obj); - } - } - }; - - struct convertible_to_double - { - static unaryfunc* execute(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - // For integer types, return the tp_int conversion slot to avoid - // creating a new object. We'll handle that in - // py_float_or_int_as_double, below - if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int) - return &number_methods->nb_int; - - return number_methods && number_methods->nb_float - ? &number_methods->nb_float : 0; - } - }; - - struct py_float_or_int_as_double - { - static double execute(PyObject* obj) - { - if (PyObject_TypeCheck(obj, &PyInt_Type)) - { - return PyInt_AS_LONG(obj); - } - else - { - return PyFloat_AS_DOUBLE(obj); - } - } - }; - - template - struct scalar_from_python - { - tp_cref_from_python cref_converter; - tp_scalar_from_python value_converter; - }; - - template - void register_int_converters(T* = 0) - { - static scalar_from_python x; - }; -} - -#define REGISTER_INT_CONVERTERS(U) register_int_converters() -#define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U) - -void initialize_builtin_converters() -{ - REGISTER_INT_CONVERTERS2(char); - REGISTER_INT_CONVERTERS2(short); - REGISTER_INT_CONVERTERS2(int); - REGISTER_INT_CONVERTERS2(long); - - static scalar_from_python< - float,convertible_to_double,py_float_or_int_as_double> float_from_python; - - static scalar_from_python< - double,convertible_to_double,py_float_or_int_as_double> double_from_python; - - static scalar_from_python< - long double,convertible_to_double,py_float_or_int_as_double> long_double_from_python; - - static scalar_from_python< - char const*, convertible_to_cstring, extract_cstring> cstring_from_python; - - static tp_cref_from_python< - std::string, convertible_to_string, extract_cstring> string_from_python; -} - -}}} // namespace boost::python::converter diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp deleted file mode 100644 index 2e844acf..00000000 --- a/src/converter/from_python.cpp +++ /dev/null @@ -1,26 +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. - -#include -#include - -namespace boost { namespace python { namespace converter { - -from_python_converter_base::from_python_converter_base( - type_id_t type - , from_python_check checker - ) - : body(type) - , m_convertible(checker) - -{ - // Insert this in the converter chain. - from_python_converter_base*& head = registry::from_python_chain(type); - m_next = head; - head = this; -} - -}}} // namespace boost::python::converter diff --git a/src/converter/handle.cpp b/src/converter/handle.cpp deleted file mode 100644 index 1a2b8c31..00000000 --- a/src/converter/handle.cpp +++ /dev/null @@ -1,35 +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. -#include -#include - -namespace boost { namespace python { namespace converter { - -bool handle::convertible() const -{ - for (handle const* p = this; p != 0; p = p->m_next) - { - if (p->m_body == 0) - return false; - } - return true; -} - -void handle::destroy() -{ - // Recurse down the chain releasing from tail to head - if (m_next != 0) - m_next->destroy(); - - // Our body knows how to destroy us. If we never got a body, - // there's nothing to do. - if (m_body) - m_body->destroy_handle(this); -} - -// void handle::dummy::nonnull() {} - -}}} // namespace boost::python::converter diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp deleted file mode 100644 index c90d709d..00000000 --- a/src/converter/registry.cpp +++ /dev/null @@ -1,92 +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. -#include -#include -#include -#include - -namespace boost { namespace python { namespace converter { - -namespace // -{ - // These are the elements stored in the registry - struct entry - { - entry(); - - // The unique to_python converter for the associated C++ type. - to_python_value_function m_to_python_converter; - - // The collection of from_python converters for the associated - // C++ type. - from_python_converter_base* m_from_python_converters; - - // The class object associated with this type - PyTypeObject* m_class_object; - }; - - typedef std::map registry_t; - - registry_t& entries() - { - static registry_t registry; - static bool builtin_converters_initialized = false; - if (!builtin_converters_initialized) - { - // Make this true early because registering the builtin - // converters will cause recursion. - builtin_converters_initialized = true; - - initialize_builtin_converters(); - } - return registry; - } - - entry* find(type_id_t type) - { - return &entries()[type]; - } - - entry::entry() - : m_to_python_converter(0) - , m_from_python_converters(0) - , m_class_object(0) - { - } -} // namespace - -namespace registry -{ - to_python_value_function const& to_python_function( - undecorated_type_id_t key) - { - return find(key)->m_to_python_converter; - } - - void insert(to_python_value_function f, undecorated_type_id_t source_t) - { - to_python_value_function& slot = find(source_t)->m_to_python_converter; - assert(slot == 0); // we have a problem otherwise - if (slot != 0) - { - throw std::runtime_error( - "trying to register to_python_converter for a type which already has a registered to_python_converter"); - } - slot = f; - } - - from_python_converter_base*& from_python_chain(type_id_t key) - { - return find(key)->m_from_python_converters; - } - - PyTypeObject*& class_object(undecorated_type_id_t key) - { - return find(key)->m_class_object; - } -} // namespace registry - -}}} // namespace boost::python::converter diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp deleted file mode 100644 index 904f30d0..00000000 --- a/src/converter/type_id.cpp +++ /dev/null @@ -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. - -#include -#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT -# include -#else -# include -#endif - -namespace boost { namespace python { namespace converter { - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, undecorated_type_id_t const& x) -{ - return os << x.name(); -} - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_id_t const& x) -{ - os << x.m_base_type; - if (x.m_decoration & type_id_t::const_) - os << " const"; - if (x.m_decoration & type_id_t::volatile_) - os << " volatile"; - if (x.m_decoration & type_id_t::reference) - os << "&"; - return os; -} - -}}} // namespace boost::python::converter diff --git a/src/converter/unwrap.cpp b/src/converter/unwrap.cpp deleted file mode 100644 index 6a72ab77..00000000 --- a/src/converter/unwrap.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include - -namespace boost { namespace python { namespace converter { - -namespace -{ - struct pyobject_unwrapper : unwrapper_base - { - pyobject_unwrapper(); - void* can_convert(PyObject*) const; - }; - - pyobject_unwrapper static_unwrapper; - std::pair unwrapper_pair(&static_unwrapper,&static_unwrapper); - - pyobject_unwrapper::pyobject_unwrapper() - : unwrapper_base(type_id()) - { - } - - void* pyobject_unwrapper::can_convert(PyObject*) const - { - return non_null; - } -} - -BOOST_PYTHON_DECL std::pair& -unwrap_more_::m_unwrapper = unwrapper_pair; - -}}} // namespace boost::python::converter diff --git a/src/converter/unwrapper.cpp b/src/converter/unwrapper.cpp deleted file mode 100644 index 6279febf..00000000 --- a/src/converter/unwrapper.cpp +++ /dev/null @@ -1,31 +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. -#include -#include -#include - -namespace boost { namespace python { namespace converter { - -unwrapper_base::unwrapper_base(type_id_t key) - : body(key) -{ - registry::insert(*this); -} - -unwrapper_base::~unwrapper_base() -{ - if (can_unregister()) - registry::remove(*this); -} - -namespace -{ - int arbitrary; -} - -void* const unwrapper_base::non_null = &arbitrary; - -}}} // namespace boost::python::converter diff --git a/src/converter/wrapper.cpp b/src/converter/wrapper.cpp deleted file mode 100644 index 567ff99d..00000000 --- a/src/converter/wrapper.cpp +++ /dev/null @@ -1,41 +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. - -#include -#include - -namespace boost { namespace python { namespace converter { - -wrapper_base::wrapper_base(type_id_t type) - : body(type) -{ - registry::insert(*this); -} - -wrapper_base::~wrapper_base() -{ - if (can_unregister()) - registry::remove(*this); -} - -namespace -{ - // This doesn't actually get called, but we need something to fill - // in the slot in the wrap class. - struct identity_wrapper_t : wrapper - { - PyObject* convert(PyObject* source) const - { - return source; - } - }; - - identity_wrapper_t identity_wrapper_object; -} - -BOOST_PYTHON_DECL body& identity_wrapper = identity_wrapper_object; - -}}} // namespace boost::python::converter diff --git a/src/cross_module.cpp b/src/cross_module.cpp deleted file mode 100644 index 2bce5a61..00000000 --- a/src/cross_module.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, use, - modify, sell and distribute this software is granted provided this - copyright notice appears in all copies. This software is provided - "as is" without express or implied warranty, and with no claim as to - its suitability for any purpose. - - Revision History: - 17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve) -*/ - -#define BOOST_PYTHON_SOURCE - -# include -namespace python = boost::python; -# include // MSVC6.0SP4 does not know std::fprintf -# include // MSVC6.0SP4 does not know std::strcmp - -namespace -{ - - PyObject* get_module_dict(const char* module_name) - { - python::ref module_obj(PyImport_ImportModule((char*) module_name)); - PyObject* module_dict = PyModule_GetDict(module_obj.get()); - if (module_dict == 0) throw python::import_error(); - return module_dict; - } -} - -namespace boost { namespace python { - -namespace detail -{ - BOOST_PYTHON_DECL const char* converters_attribute_name = "__converters__"; - - BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name) - { - static std::string err; - PyObject* module_dict = get_module_dict(const_cast(module_name.c_str())); - PyObject* py_class = PyDict_GetItemString(module_dict, const_cast(py_class_name.c_str())); - if (py_class == 0) { - err = std::string("module ") + module_name + " has no attribute " + py_class_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - python::ref c_obj(PyObject_GetAttrString(py_class, const_cast(attribute_name.c_str())), ref::null_ok); - if (c_obj.get() == 0) { - err = std::string("object ") + module_name + "." + py_class_name - + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - if (! PyCObject_Check(c_obj.get())) { - err = std::string("object ") + module_name + "." + py_class_name + "." - + attribute_name + " is not a PyCObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - return PyCObject_AsVoidPtr(c_obj.get()); - } - - BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor) - { - if (importing_major != imported_major) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Fatal: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - PyErr_SetString(PyExc_RuntimeError, - "Fatal: export_converters_api mismatch"); - throw import_error(); - } - if (importing_minor != imported_minor) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Warning: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - } - } - -} - -}} // namespace boost::python::detail diff --git a/src/errors.cpp b/src/errors.cpp deleted file mode 100644 index 1290df50..00000000 --- a/src/errors.cpp +++ /dev/null @@ -1,68 +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 BOOST_PYTHON_SOURCE -# define BOOST_PYTHON_SOURCE -#endif - -#include - -namespace boost { namespace python { - -// IMPORTANT: this function may only be called from within a catch block! -BOOST_PYTHON_DECL bool handle_exception_impl(function0 f) -{ - try - { - f(); - return false; - } - catch(const boost::python::error_already_set&) - { - // The python error reporting has already been handled. - } - catch(const std::bad_alloc&) - { - PyErr_NoMemory(); - } - catch(const std::exception& x) - { - PyErr_SetString(PyExc_RuntimeError, x.what()); - } - catch(...) - { - PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); - } - return true; -} - -BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x) -{ - if (x == 0) - throw error_already_set(); - return x; -} - -namespace detail { - - BOOST_PYTHON_DECL void expect_complex(PyObject* p) - { - if (!PyComplex_Check(p)) - { - PyErr_SetString(PyExc_TypeError, "expected a complex number"); - throw boost::python::argument_error(); - } - } - -// needed by void_adaptor (see void_adaptor.hpp) -BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 }; - - -} // namespace boost::python::detail - -}} // namespace boost::python - - diff --git a/src/extension_class.cpp b/src/extension_class.cpp deleted file mode 100644 index cc784ca6..00000000 --- a/src/extension_class.cpp +++ /dev/null @@ -1,690 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 04 Mar 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { -namespace detail { - - struct operator_dispatcher - : public PyObject - { - static PyTypeObject type_obj; - static PyNumberMethods number_methods; - - static operator_dispatcher* create(const ref& o, const ref& s); - - ref m_object; - ref m_self; - - // data members for allocation/deallocation optimization - operator_dispatcher* m_free_list_link; - static operator_dispatcher* free_list; - - private: - // only accessible through create() - operator_dispatcher(const ref& o, const ref& s); - }; - - operator_dispatcher* operator_dispatcher::free_list = 0; - -}}} // namespace boost::python::detail - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -inline PyObject* to_python(boost::python::detail::operator_dispatcher* n) { return n; } - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - - -namespace boost { namespace python { - -BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r) -{ - // Introduced sequence points for exception-safety. - ref first(detail::operator_dispatcher::create(l, l)); - - ref second(r->ob_type == &detail::operator_dispatcher::type_obj - ? r - : ref(detail::operator_dispatcher::create(r, ref()))); - - return tuple(first, second); -} - -namespace detail { - - enum { unwrap_exception_code = -1000 }; - - int unwrap_args(PyObject* left, PyObject* right, PyObject*& self, PyObject*& other) - { - if (left->ob_type != &operator_dispatcher::type_obj || - right->ob_type != &operator_dispatcher::type_obj) - { - PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_args(): expecting operator_dispatcher arguments only!"); - return unwrap_exception_code; - } - - typedef reference DPtr; - DPtr lwrapper(static_cast(left), DPtr::increment_count); - DPtr rwrapper(static_cast(right), DPtr::increment_count); - - if (lwrapper->m_self.get() != 0) - { - self = lwrapper->m_self.get(); - other = rwrapper->m_object.get(); - return 0; - } - else - { - self = rwrapper->m_self.get(); - other = lwrapper->m_object.get(); - return 1; - } - } - - int unwrap_pow_args(PyObject* left, PyObject* right, PyObject* m, - PyObject*& self, PyObject*& first, PyObject*& second) - { - if (left->ob_type != &operator_dispatcher::type_obj || - right->ob_type != &operator_dispatcher::type_obj || - m->ob_type != &operator_dispatcher::type_obj) - { - PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_pow_args(): expecting operator_dispatcher arguments only!"); - return unwrap_exception_code; - } - - typedef reference DPtr; - DPtr lwrapper(static_cast(left), DPtr::increment_count); - DPtr rwrapper(static_cast(right), DPtr::increment_count); - DPtr mwrapper(static_cast(m), DPtr::increment_count); - - if (lwrapper->m_self.get() != 0) - { - self = lwrapper->m_self.get(); - first = rwrapper->m_object.get(); - second = mwrapper->m_object.get(); - return 0; - } - else if (rwrapper->m_self.get() != 0) - { - self = rwrapper->m_self.get(); - first = lwrapper->m_object.get(); - second = mwrapper->m_object.get(); - return 1; - } - else - { - self = mwrapper->m_self.get(); - first = lwrapper->m_object.get(); - second = rwrapper->m_object.get(); - return 2; - } - } - -extension_instance* get_extension_instance(PyObject* p) -{ - // The object's type will just be some class_t object, - // but if its meta-type is right, then it is an extension_instance. - if (p->ob_type->ob_type != extension_meta_class()) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw boost::python::argument_error(); - } - return static_cast(p); -} - -void -extension_instance::add_implementation(std::auto_ptr holder) -{ - for (held_objects::const_iterator p = m_wrapped_objects.begin(); - p != m_wrapped_objects.end(); ++p) - { - if (typeid(*holder) == typeid(**p)) - { - PyErr_SetString(PyExc_RuntimeError, "Base class already initialized"); - throw error_already_set(); - } - } - m_wrapped_objects.push_back(holder.release()); -} - -extension_instance::extension_instance(PyTypeObject* class_) - : instance(class_) -{ -} - -extension_instance::~extension_instance() -{ - for (held_objects::const_iterator p = m_wrapped_objects.begin(), - finish = m_wrapped_objects.end(); - p != finish; ++p) - { - delete *p; - } -} - -meta_class* extension_meta_class() -{ - static meta_class result; - return &result; -} - -typedef class_t extension_class_t; - -bool is_subclass(const extension_class_t* derived, - const PyObject* possible_base) -{ - - tuple bases = derived->bases(); - - for (std::size_t i = 0, size = bases.size(); i < size; ++i) - { - const PyObject* base = bases[i].get(); - - if (base == possible_base) - return true; - - if (base->ob_type == extension_meta_class()) - { - const extension_class_t* base_class = downcast(base); - if (is_subclass(base_class, possible_base)) - return true; - } - } - return false; -} - -// Return true iff obj is an obj of target_class -bool is_instance(extension_instance* obj, - class_t* target_class) -{ - if (obj->ob_type == target_class) - return true; - else - { - return is_subclass( - downcast >(obj->ob_type).get(), - as_object(target_class)); - } -} - -void two_string_error(PyObject* exception_object, const char* format, const char* s1, const char* s2) -{ - char buffer[256]; - std::size_t format_length = BOOST_CSTD_::strlen(format); - std::size_t length1 = BOOST_CSTD_::strlen(s1); - std::size_t length2 = BOOST_CSTD_::strlen(s2); - - std::size_t additional_length = length1 + length2; - if (additional_length + format_length > format_length - 1) - { - std::size_t difference = sizeof(buffer) - 1 - additional_length; - length1 -= difference / 2; - additional_length -= difference / 2; - } - - sprintf(buffer, format, length1, s1, length2, s2); - - PyErr_SetString(exception_object, buffer); - if (exception_object == PyExc_TypeError) - throw argument_error(); - else - throw error_already_set(); -} - -// This is called when an attempt has been made to convert the given obj to -// a C++ type for which it doesn't have any obj data. In that case, either -// the obj was not derived from the target_class, or the appropriate -// __init__ function wasn't called to initialize the obj data of the target class. -void report_missing_instance_data( - extension_instance* obj, // The object being converted - class_t* target_class, // the extension class of the C++ type - const std::type_info& target_typeid, // The typeid of the C++ type - bool target_is_ptr) -{ - char buffer[256]; - if (is_instance(obj, target_class)) - { - if (target_is_ptr) - { - two_string_error(PyExc_RuntimeError, - "Object of extension class '%.*s' does not wrap <%.*s>.", - obj->ob_type->tp_name, target_typeid.name()); - } - else - { - const char message[] = "__init__ function for extension class '%.*s' was never called."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, - target_class->tp_name); - } - PyErr_SetString(PyExc_RuntimeError, buffer); - } - else if (target_class == 0) - { - const char message[] = "Cannot convert to <%.*s>; its Python class was never created or has been deleted."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, target_typeid.name()); - PyErr_SetString(PyExc_RuntimeError, buffer); - } - else - { - two_string_error(PyExc_TypeError, "extension class '%.*s' is not convertible into '%.*s'.", - obj->ob_type->tp_name, target_class->tp_name); - } -} - -void report_missing_instance_data( - extension_instance* obj, // The object being converted - class_t* target_class, // the extension class of the C++ type - const std::type_info& target_typeid) // The typeid of the C++ type -{ - report_missing_instance_data(obj, target_class, target_typeid, false); -} - -void report_missing_ptr_data( - extension_instance* obj, // The object being converted - class_t* target_class, // the extension class of the C++ type - const std::type_info& target_typeid) // The typeid of the C++ type -{ - report_missing_instance_data(obj, target_class, target_typeid, true); -} - -void report_missing_class_object(const std::type_info& info) -{ - char buffer[256]; - const char message[] = "Cannot convert <%.*s> to python; its Python class was never created or has been deleted."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name()); - PyErr_SetString(PyExc_RuntimeError, buffer); - throw error_already_set(); -} - -void report_released_smart_pointer(const std::type_info& info) -{ - char buffer[256]; - const char message[] = "Converting from python, pointer or smart pointer to <%.*s> is NULL."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name()); - PyErr_SetString(PyExc_RuntimeError, buffer); - throw argument_error(); -} - -read_only_setattr_function::read_only_setattr_function(const char* name) - : m_name(name) -{ -} - -PyObject* read_only_setattr_function::do_call(PyObject* /*args*/, PyObject* /*keywords*/) const -{ - PyErr_SetObject(PyExc_AttributeError, ("'" + m_name + "' attribute is read-only").get()); - return 0; -} - -const char* read_only_setattr_function::description() const -{ - return "uncallable"; -} - -extension_class_base::extension_class_base(const char* name) - : class_t( - extension_meta_class(), string(name), tuple(), dictionary()) -{ -} - -// This function is used in from_python() to convert wrapped classes that are -// related by inheritance. The problem is this: although C++ provides all necessary -// conversion operators, source and target of a conversion must be known at compile -// time. However, in Python we want to convert classes at runtime. The solution is to -// generate conversion functions at compile time, register them within the appropriate -// class objects and call them when a particular runtime conversion is required. - -// If functions for any possible conversion have to be stored, their number will grow -// qudratically. To reduce this number, we actually store only conversion functions -// between adjacent levels in the inheritance tree. By traversing the tree recursively, -// we can build any allowed conversion as a concatenation of simple conversions. This -// traversal is done in the functions try_base_class_conversions() and -// try_derived_class_conversions(). If a particular conversion is impossible, all -// conversion functions will return a NULL pointer. - -// The function extract_object_from_holder() attempts to actually extract the pointer -// to the contained object from an instance_holder_base (a wrapper class). A conversion -// of the held object to 'T *' is allowed when the conversion -// 'dynamic_cast *>(an_instance_holder_base)' succeeds. -void* extension_class_base::try_class_conversions(instance_holder_base* object) const -{ - void* result = try_derived_class_conversions(object); - if (result) - return result; - - if (!object->held_by_value()) - return try_base_class_conversions(object); - else - return 0; -} - -void* extension_class_base::try_base_class_conversions(instance_holder_base* object) const -{ - for (std::size_t i = 0; i < base_classes().size(); ++i) - { - if (base_classes()[i].convert == 0) - continue; - void* result1 = base_classes()[i].class_object->extract_object_from_holder(object); - if (result1) - return (*base_classes()[i].convert)(result1); - - void* result2 = base_classes()[i].class_object->try_base_class_conversions(object); - if (result2) - return (*base_classes()[i].convert)(result2); - } - return 0; -} - -void* extension_class_base::try_derived_class_conversions(instance_holder_base* object) const -{ - for (std::size_t i = 0; i < derived_classes().size(); ++i) - { - void* result1 = derived_classes()[i].class_object->extract_object_from_holder(object); - if (result1) - return (*derived_classes()[i].convert)(result1); - - void* result2 = derived_classes()[i].class_object->try_derived_class_conversions(object); - if (result2) - return (*derived_classes()[i].convert)(result2); - } - return 0; -} - -void extension_class_base::add_method(function* method, const char* name) -{ - add_method(reference(method), name); -} - -void extension_class_base::add_method(reference method, const char* name) -{ - // Add the attribute to the computed target - function::add_to_namespace(method, name, this->dict().get()); - - // If it is a special member function it should be enabled both here and there. - detail::enable_named_method(this, name); -} - -void extension_class_base::add_constructor_object(function* init_fn) -{ - add_method(init_fn, "__init__"); -} - -void extension_class_base::add_setter_method(function* setter_, const char* name) -{ - reference setter(setter_); - add_method(setter, (detail::setattr_string() + name + "__").c_str()); -} - -void extension_class_base::add_getter_method(function* getter_, const char* name) -{ - reference getter(getter_); - add_method(getter, (detail::getattr_string() + name + "__").c_str()); -} - -void extension_class_base::set_attribute(const char* name, PyObject* x_) -{ - ref x(x_); - set_attribute(name, x); -} - -void extension_class_base::set_attribute(const char* name, ref x) -{ - dict().set_item(string(name), x); - if (PyCallable_Check(x.get())) - detail::enable_named_method(this, name); -} - -operator_dispatcher::operator_dispatcher(const ref& o, const ref& s) - : m_object(o), m_self(s), m_free_list_link(0) - -{ - PyObject* self = this; - PyObject_INIT(self, &type_obj); -} - -operator_dispatcher* -operator_dispatcher::create(const ref& object, const ref& self) -{ - operator_dispatcher* const result = free_list; - if (result == 0) - return new operator_dispatcher(object, self); - - free_list = result->m_free_list_link; - result->m_object = object; - result->m_self = self; - - PyObject* result_as_pyobject = result; - PyObject_INIT(result_as_pyobject, &type_obj); - return result; -} - -extern "C" -{ - -void operator_dispatcher_dealloc(PyObject* self) -{ - operator_dispatcher* obj = static_cast(self); - obj->m_free_list_link = operator_dispatcher::free_list; - operator_dispatcher::free_list = obj; - obj->m_object.reset(); - obj->m_self.reset(); -} - -int operator_dispatcher_coerce(PyObject** l, PyObject** r) -{ - Py_INCREF(*l); - - return handle_exception( - bind_return( - *r - , bind(operator_dispatcher::create, - ref(*r, ref::increment_count), - ref()))) - ? -1 : 0; -} - -#define PY_DEFINE_OPERATOR(id, symbol) \ - PyObject* operator_dispatcher_call_##id(PyObject* left, PyObject* right) \ - { \ - /* unwrap the arguments from their OperatorDispatcher */ \ - PyObject* self; \ - PyObject* other; \ - int reverse = unwrap_args(left, right, self, other); \ - if (reverse == unwrap_exception_code) \ - return 0; \ - \ - /* call the function */ \ - PyObject* result = \ - PyEval_CallMethod(self, \ - const_cast(reverse ? "__r" #id "__" : "__" #id "__"), \ - const_cast("(O)"), \ - other); \ - if (result == 0 && PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError)) \ - { \ - PyErr_Clear(); \ - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for " #symbol); \ - } \ - return result; \ - } - -PY_DEFINE_OPERATOR(add, +) -PY_DEFINE_OPERATOR(sub, -) -PY_DEFINE_OPERATOR(mul, *) -PY_DEFINE_OPERATOR(div, /) -PY_DEFINE_OPERATOR(mod, %) -PY_DEFINE_OPERATOR(divmod, divmod) -PY_DEFINE_OPERATOR(lshift, <<) -PY_DEFINE_OPERATOR(rshift, >>) -PY_DEFINE_OPERATOR(and, &) -PY_DEFINE_OPERATOR(xor, ^) -PY_DEFINE_OPERATOR(or, |) - -/* coercion rules for heterogeneous pow(): - pow(Foo, int): left, right coerced; m: None => reverse = 0 - pow(int, Foo): left, right coerced; m: None => reverse = 1 - pow(Foo, int, int): left, right, m coerced => reverse = 0 - pow(int, Foo, int): left, right, m coerced => reverse = 1 - pow(int, int, Foo): left, right, m coerced => reverse = 2 - pow(Foo, Foo, int): left, right coerced; m coerced twice => reverse = 0 - pow(Foo, int, Foo): left, right, m coerced => reverse = 0 - pow(int, Foo, Foo): left, right, m coerced => reverse = 1 -*/ -PyObject* operator_dispatcher_call_pow(PyObject* left, PyObject* right, PyObject* m) -{ - int reverse; - PyObject* self; - PyObject* first; - PyObject* second; - - if (m->ob_type == Py_None->ob_type) - { - reverse = unwrap_args(left, right, self, first); - second = m; - } - else - { - reverse = unwrap_pow_args(left, right, m, self, first, second); - } - - if (reverse == unwrap_exception_code) - return 0; - - // call the function - PyObject* result = - PyEval_CallMethod(self, - const_cast((reverse == 0) - ? "__pow__" - : (reverse == 1) - ? "__rpow__" - : "__rrpow__"), - const_cast("(OO)"), - first, second); - if (result == 0 && - (PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_TypeError) || - PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError))) - { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()"); - } - return result; -} - -int operator_dispatcher_call_cmp(PyObject* left, PyObject* right) -{ - // unwrap the arguments from their OperatorDispatcher - PyObject* self; - PyObject* other; - int reverse = unwrap_args(left, right, self, other); - if (reverse == unwrap_exception_code) - return -1; - - // call the function - PyObject* result = - PyEval_CallMethod(self, - const_cast(reverse ? "__rcmp__" : "__cmp__"), - const_cast("(O)"), - other); - if (result == 0) - { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for cmp() or <"); - return -1; - } - else - { - try - { - return BOOST_PYTHON_CONVERSION::from_python(result, type()); - } - catch(...) - { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "cmp() didn't return int"); - return -1; - } - } -} - -} // extern "C" - -PyTypeObject operator_dispatcher::type_obj = -{ - PyObject_HEAD_INIT(&PyType_Type) - 0, - const_cast("operator_dispatcher"), - sizeof(operator_dispatcher), - 0, - &operator_dispatcher_dealloc, - 0, - 0, - 0, - &operator_dispatcher_call_cmp, - 0, - &operator_dispatcher::number_methods, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - -PyNumberMethods operator_dispatcher::number_methods = -{ - &operator_dispatcher_call_add, - &operator_dispatcher_call_sub, - &operator_dispatcher_call_mul, - &operator_dispatcher_call_div, - &operator_dispatcher_call_mod, - &operator_dispatcher_call_divmod, - &operator_dispatcher_call_pow, - 0, - 0, - 0, - 0, - 0, - &operator_dispatcher_call_lshift, - &operator_dispatcher_call_rshift, - &operator_dispatcher_call_and, - &operator_dispatcher_call_xor, - &operator_dispatcher_call_or, - &operator_dispatcher_coerce, - 0, - 0, - 0, - 0, - 0 -}; - -} // namespace detail - -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -template class BOOST_PYTHON_DECL meta_class; -template class BOOST_PYTHON_DECL class_t; -# endif - -}} // namespace boost::python diff --git a/src/functions.cpp b/src/functions.cpp deleted file mode 100644 index ecbacf4e..00000000 --- a/src/functions.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include -#include - -namespace boost { namespace python { namespace detail { - -struct function::type_object : - singleton > > -{ - type_object() : singleton_base(&PyType_Type) {} -}; - - -void function::add_to_namespace(reference new_function, const char* name, PyObject* dict) -{ - dictionary d(ref(dict, ref::increment_count)); - string key(name); - - ref existing_object = d.get_item(key.reference()); - if (existing_object.get() == 0) - { - d[key] = ref(new_function.get(), ref::increment_count); - } - else - { - if (existing_object->ob_type == type_object::instance()) - { - function* f = static_cast(existing_object.get()); - while (f->m_overloads.get() != 0) - f = f->m_overloads.get(); - f->m_overloads = new_function; - } - else - { - PyErr_SetObject(PyExc_RuntimeError, - (string("Attempt to overload ") + name - + " failed. The existing attribute has type " - + existing_object->ob_type->tp_name).get()); - throw error_already_set(); - } - } -} - -function::function() - : python_object(type_object::instance()) -{ -} - -PyObject* function::call(PyObject* args, PyObject* keywords) const -{ - // Traverse the linked list of function overloads until we find one that - // matches. - for (const function* f = this; f != 0; f = f->m_overloads.get()) - { - PyErr_Clear(); - try - { - PyObject* const result = f->do_call(args, keywords); - if (result != 0) - return result; - } - catch(const argument_error&) - { - } - } - - // If we get here, no overloads matched the arguments - - // Allow the single-function error-reporting to take effect unless there was - // an overload - if (m_overloads.get() == 0) - return 0; - - // Synthesize a more-explicit error message - PyErr_Clear(); - string message("No overloaded functions match ("); - tuple arguments(ref(args, ref::increment_count)); - for (std::size_t i = 0; i < arguments.size(); ++i) - { - if (i != 0) - message += ", "; - message += arguments[i]->ob_type->tp_name; - } - - message += "). Candidates are:\n"; - for (const function* f1 = this; f1 != 0; f1 = f1->m_overloads.get()) - { - if (f1 != this) - message += "\n"; - message += f1->description(); - } - - PyErr_SetObject(PyExc_TypeError, message.get()); - return 0; -} - -// The instance class whose obj represents the type of bound_function -// objects in Python. bound_functions must be GetAttrable so the __doc__ -// attribute of built-in Python functions can be accessed when bound. -struct bound_function::type_object : - singleton > > > -{ - type_object() : singleton_base(&PyType_Type) {} - -private: // type_object hook override - void dealloc(bound_function*) const; -}; - -bound_function* bound_function::create(const ref& target, const ref& fn) -{ - bound_function* const result = free_list; - if (result == 0) - return new bound_function(target, fn); - - free_list = result->m_free_list_link; - result->m_target = target; - result->m_unbound_function = fn; - - PyObject* self = result; - PyObject_INIT(self, type_object::instance()); - return result; -} - -bound_function::bound_function(const ref& target, const ref& fn) - : python_object(type_object::instance()), - m_target(target), - m_unbound_function(fn), - m_free_list_link(0) -{ -} - -PyObject* -bound_function::call(PyObject* args, PyObject* keywords) const -{ - // Build a new tuple which prepends the target to the arguments - tuple tail_arguments(ref(args, ref::increment_count)); - ref all_arguments(PyTuple_New(tail_arguments.size() + 1)); - - PyTuple_SET_ITEM(all_arguments.get(), 0, m_target.get()); - Py_INCREF(m_target.get()); - for (std::size_t i = 0; i < tail_arguments.size(); ++i) - { - PyTuple_SET_ITEM(all_arguments.get(), i + 1, tail_arguments[i].get()); - Py_INCREF(tail_arguments[i].get()); - } - - return PyEval_CallObjectWithKeywords(m_unbound_function.get(), all_arguments.get(), keywords); -} - -PyObject* bound_function::getattr(const char* name) const -{ - return PyObject_GetAttrString(m_unbound_function.get(), const_cast(name)); -} - -void bound_function::type_object::dealloc(bound_function* obj) const -{ - obj->m_free_list_link = free_list; - free_list = obj; - obj->m_target.reset(); - obj->m_unbound_function.reset(); -} - -bound_function* bound_function::free_list; - -}}} // namespace boost::python::detail diff --git a/src/gen_all.py b/src/gen_all.py deleted file mode 100644 index 3877d181..00000000 --- a/src/gen_all.py +++ /dev/null @@ -1,26 +0,0 @@ -from gen_callback import * -from gen_caller import * -from gen_init_function import * -from gen_signatures import * -from gen_singleton import * -from gen_extclass import * - -def gen_all(args): - open('callback.hpp', 'w').write(gen_callback(args)) - open('caller.hpp', 'w').write(gen_caller(args)) - open('init_function.hpp', 'w').write(gen_init_function(args)) - open('signatures.hpp', 'w').write(gen_signatures(args)) - open('singleton.hpp', 'w').write(gen_singleton(args)) - open('extension_class.hpp', 'w').write(gen_extclass(args)) - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 10 - else: - args = int(sys.argv[1]) - - print gen_all(args) - - diff --git a/src/gen_arg_tuple_size.py b/src/gen_arg_tuple_size.py deleted file mode 100644 index 9de332ab..00000000 --- a/src/gen_arg_tuple_size.py +++ /dev/null @@ -1,139 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_arg_tuple_size.python -''' - -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -_suffix = { - '': ''' -// Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 -''', ' const volatile': ''' -# endif // __MWERKS__ -''' - }; - -def gen_arg_tuple_size(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + ''' -#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP -# define ARG_TUPLE_SIZE_DWA20011201_HPP - -# include - -namespace boost { namespace python { namespace detail { - -// Computes (at compile-time) the number of elements that a Python -// argument tuple must have in order to be passed to a wrapped C++ -// (member) function of the given type. -template struct arg_tuple_size; - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__) - -''' - + gen_functions( -'''template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = %n); -}; - -''', free_function_args) - - + '\n' - - + reduce(lambda x,y: x+'\n'+y - , map( - lambda cv: gen_functions( -'''template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = %+); -}; - -''' - , member_function_args, cv) + _suffix.get(cv, '') - , _cv_qualifiers)) - - + -'''# else - -// We will use the "sizeof() trick" to work around the lack of -// partial specialization in MSVC6 and its broken-ness in borland. -// See http://opensource.adobe.com or -// http://groups.yahoo.com/group/boost/message/5441 for -// more examples - -// The following helper functions are never actually called, since -// they are only used within a sizeof() expression, but the type of -// their return value is used to discriminate between various free -// and member function pointers at compile-time. - -''' - + gen_functions( -'''template -char_array<%n> arg_tuple_size_helper(R (*)(%(A%+%:, %))); - -''', free_function_args) - - + reduce(lambda x,y: x+'\n'+y - , map( - lambda cv: gen_functions( -'''template -char_array<%+> arg_tuple_size_helper(R (A0::*)(%(A%+%:, %))%1); - -''', member_function_args, cv) - , _cv_qualifiers)) - + ''' -template -struct arg_tuple_size -{ - // The sizeof() magic happens here - BOOST_STATIC_CONSTANT(std::size_t, value - = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); -}; -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -}}} // namespace boost::python::detail - -#endif // ARG_TUPLE_SIZE_DWA20011201_HPP -''') - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_arg_tuple_size(member_function_args, free_function_args) - - diff --git a/src/gen_call.py b/src/gen_call.py deleted file mode 100644 index f609c0ae..00000000 --- a/src/gen_call.py +++ /dev/null @@ -1,82 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_call.py - -#ifndef CALL_DWA20011214_HPP -# define CALL_DWA20011214_HPP - -# include - -namespace boost { namespace python { - -''' -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -def gen_call(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return (header % (member_function_args, free_function_args) - + gen_functions( -'''template -inline PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -''', free_function_args) - + -'''// Member functions -''' - + reduce(lambda x,y: x+y - , map(lambda cv: - gen_functions( -'''template -inline PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -''' - , member_function_args, cv) - , _cv_qualifiers)) - + -''' -}} // namespace boost::python - -#endif // CALL_DWA20011214_HPP -''') - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_call(member_function_args, free_function_args) - - diff --git a/src/gen_callback.py b/src/gen_callback.py deleted file mode 100644 index f178212b..00000000 --- a/src/gen_callback.py +++ /dev/null @@ -1,124 +0,0 @@ -from gen_function import * -import string - -def gen_callback(args): - return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for %d-argument python callbacks by gen_callback.python - -#ifndef CALLBACK_DWA_052100_H_ -# define CALLBACK_DWA_052100_H_ - -# include -# include - -namespace boost { namespace python { - -namespace detail { - template - inline void callback_adjust_refcount(PyObject*, type) {} - - inline void callback_adjust_refcount(PyObject* p, type) - { Py_INCREF(p); } -} - -// Calling Python from C++ -template -struct callback -{""" % args - - + gen_functions(''' -%{ template <%(class A%n%:, %)> -%} static R call_method(PyObject* self, const char* name%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(%(O%))")%(, - p%n.get()%))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - -%{ template <%(class A%n%:, %)> -%} static R call(PyObject* self%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallFunction(self, const_cast("(%(O%))")%(, - p%n.get()%))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } -''', args) - + -"""}; - -// This specialization wouldn't be needed, but MSVC6 doesn't correctly allow the following: -// void g(); -// void f() { return g(); } -template <> -struct callback -{ -""" - + gen_functions(''' -%{ template <%(class A%n%:, %)> -%} static void call_method(PyObject* self, const char* name%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(%(O%))")%(, - p%n.get()%))); - } - -%{ template <%(class A%n%:, %)> -%} static void call(PyObject* self%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallFunction(self, const_cast("(%(O%))")%(, - p%n.get()%))); - } -''', args) - + -"""}; - -// Make it a compile-time error to try to return a const char* from a virtual -// function. The standard conversion -// -// from_python(PyObject* string, boost::python::type) -// -// returns a pointer to the character array which is internal to string. The -// problem with trying to do this in a standard callback function is that the -// Python string would likely be destroyed upon return from the calling function -// (boost::python::callback::call[_method]) when its reference count is -// decremented. If you absolutely need to do this and you're sure it's safe (it -// usually isn't), you can use -// -// boost::python::string result(boost::python::callback::call[_method](...args...)); -// ...result.c_str()... // access the char* array -template <> -struct callback -{ - // Try hard to generate a readable error message - typedef struct unsafe_since_python_string_may_be_destroyed {} call, call_method; -}; - -}} // namespace boost::python - -#endif // CALLBACK_DWA_052100_H_ -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_callback(args) diff --git a/src/gen_caller.py b/src/gen_caller.py deleted file mode 100644 index 26bd88c6..00000000 --- a/src/gen_caller.py +++ /dev/null @@ -1,138 +0,0 @@ -# (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# The author gratefully acknowleges the support of Dragon Systems, Inc., in -# producing this work. - -from gen_function import * -import string - -header = '''// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_caller.python -''' - -body_sections = ( -''' -#ifndef CALLER_DWA05090_H_ -# define CALLER_DWA05090_H_ - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// Calling C++ from Python -template -struct caller -{ -''', -''' -''', -''' // Free functions -''', -'''}; - -template <> -struct caller -{ -''', -''' -''', -''' - // Free functions -''', -'''}; - -}} // namespace boost::python - -#endif -''') - -#' - -member_function = ''' template - static PyObject* call(%1 (T::*pmf)(%(A%n%:, %))%2, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; -%( PyObject* a%n; -%) if (!PyArg_ParseTuple(args, const_cast("O%(O%)"), &self%(, &a%n%))) - return 0; - T& target = from_python(self, type()); - %3(target.*pmf)(%(from_python(a%n, type())%:, - %))%4 - } - -''' - -free_function = '''%{ template <%(class A%n%:, %)> -%} static PyObject* call(%1 (*f)(%(A%n%:, %)), PyObject* args, PyObject* /* keywords */ ) { -%( PyObject* a%n; -%) if (!PyArg_ParseTuple(args, const_cast("%(O%)")%(, &a%n%))) - return 0; - %2f(%(from_python(a%n, type())%:, - %))%3 - } - -''' - -def gen_caller(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + body_sections[0] - + gen_functions(member_function, member_function_args, - 'R', '', 'return to_python(', ');') - + body_sections[1] - + gen_functions(member_function, member_function_args, - 'R', ' const', 'return to_python(', ');') - + body_sections[2] - - + gen_functions(free_function, free_function_args, - 'R', 'return to_python(', ');') - + body_sections[3] - - # specialized part for void return values begins here - + gen_functions(member_function, member_function_args, - 'void', '', '', return_none) - + body_sections[4] - + gen_functions(member_function, member_function_args, - 'void', ' const', '', return_none) - + body_sections[5] - - + gen_functions(free_function, free_function_args, - 'void', '', return_none) - + body_sections[6] - ) - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_caller(member_function_args, free_function_args) - - diff --git a/src/gen_extclass.py b/src/gen_extclass.py deleted file mode 100644 index 6316bab9..00000000 --- a/src/gen_extclass.py +++ /dev/null @@ -1,948 +0,0 @@ -from gen_function import * -import string - -def gen_extclass(args): - return ( -"""// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated for %d-argument constructors by -// gen_extclass.python - -// Revision History: -// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve) -// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted -// to_python (Dave Abrahams) - -#ifndef EXTENSION_CLASS_DWA052000_H_ -# define EXTENSION_CLASS_DWA052000_H_ - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// forward declarations -template struct operators; -template struct left_operand; -template struct right_operand; - -enum without_downcast_t { without_downcast }; - -namespace detail -{ - -// forward declarations - class extension_instance; - class extension_class_base; - template class instance_holder; - template class instance_value_holder; - template class instance_ptr_holder; - template struct operand_select; - template struct choose_op; - template struct choose_rop; - template struct choose_unary_op; - template struct define_operator; - - class BOOST_PYTHON_DECL extension_instance : public instance - { - public: - extension_instance(PyTypeObject* class_); - ~extension_instance(); - - void add_implementation(std::auto_ptr holder); - - typedef std::vector held_objects; - const held_objects& wrapped_objects() const - { return m_wrapped_objects; } - private: - held_objects m_wrapped_objects; - }; - -} // namespace detail - -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t; -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class; -# endif - -namespace detail { - -BOOST_PYTHON_DECL meta_class* extension_meta_class(); -BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p); -BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&); -BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&); - -template -T* check_non_null(T* p) -{ - if (p == 0) - report_released_smart_pointer(typeid(T)); - return p; -} - -template class held_instance; - -typedef void* (*conversion_function_ptr)(void*); - -struct BOOST_PYTHON_DECL base_class_info -{ - base_class_info(extension_class_base* t, conversion_function_ptr f) - :class_object(t), convert(f) - {} - - extension_class_base* class_object; - conversion_function_ptr convert; -}; - -typedef base_class_info derived_class_info; - -struct add_operator_base; - -class BOOST_PYTHON_DECL extension_class_base : public class_t -{ - public: - extension_class_base(const char* name); - - public: - // the purpose of try_class_conversions() and its related functions - // is explained in extclass.cpp - void* try_class_conversions(instance_holder_base*) const; - void* try_base_class_conversions(instance_holder_base*) const; - void* try_derived_class_conversions(instance_holder_base*) const; - - void set_attribute(const char* name, PyObject* x); - void set_attribute(const char* name, ref x); - - private: - virtual void* extract_object_from_holder(instance_holder_base* v) const = 0; - virtual std::vector const& base_classes() const = 0; - virtual std::vector const& derived_classes() const = 0; - - protected: - friend struct add_operator_base; - void add_method(reference method, const char* name); - void add_method(function* method, const char* name); - - void add_constructor_object(function*); - void add_setter_method(function*, const char* name); - void add_getter_method(function*, const char* name); -}; - -template -class class_registry -{ - public: - static extension_class_base* class_object() - { return static_class_object; } - - // Register/unregister the Python class object corresponding to T - static void register_class(extension_class_base*); - static void unregister_class(extension_class_base*); - - // Establish C++ inheritance relationships - static void register_base_class(base_class_info const&); - static void register_derived_class(derived_class_info const&); - - // Query the C++ inheritance relationships - static std::vector const& base_classes(); - static std::vector const& derived_classes(); - private: - static extension_class_base* static_class_object; - static std::vector static_base_class_info; - static std::vector static_derived_class_info; -}; - -template -struct is_null_helper -{ - template - static bool test(Ptr x) { return x == 0; } -}; - -template <> -struct is_null_helper -{ - template - static bool test(const Ptr& x) { return x.get() == 0; } -}; - -template -bool is_null(const Ptr& x) -{ - return is_null_helper<(is_pointer::value)>::test(x); -} - -}}} // namespace boost::python::detail - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -// This class' only job is to define from_python and to_python converters for T -// and U. T is the class the user really intends to wrap. U is a class derived -// from T with some virtual function overriding boilerplate, or if there are no -// virtual functions, U = held_instance. -// -// A look-alike of this class in root/boost/python/cross_module.hpp -// is used for the implementation of the cross-module support -// (export_converters and import_converters). If from_python -// and to_python converters are added or removed from the class -// below, the class python_import_extension_class_converters has -// to be modified accordingly. -// -template > -class python_extension_class_converters -{ - public: - // Get an object which can be used to convert T to/from python. This is used - // as a kind of concept check by the global template - // - // PyObject* to_python(const T& x) - // - // below this class, to prevent the confusing messages that would otherwise - // pop up. Now, if T hasn't been wrapped as an extension class, the user - // will see an error message about the lack of an eligible - // py_extension_class_converters() function. - friend python_extension_class_converters py_extension_class_converters(boost::python::type) - { - return python_extension_class_converters(); - } - - // This is a member function because in a conforming implementation, friend - // funcitons defined inline in the class body are all instantiated as soon - // as the enclosing class is instantiated. If T is not copyable, that causes - // a compiler error. Instead, we access this function through the global - // template - // - // PyObject* to_python(const T& x) - // - // defined below this class. Since template functions are instantiated only - // on demand, errors will be avoided unless T is noncopyable and the user - // writes code which causes us to try to copy a T. - PyObject* to_python(const T& x) const - { - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_value_holder(result.get(), x))); - return result.release(); - } - - friend - T* non_null_from_python(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_holder* held = dynamic_cast*>(*p); - if (held != 0) - return held->target(); - - // see extclass.cpp for an explanation of try_class_conversions() - void* target = boost::python::detail::class_registry::class_object()->try_class_conversions(*p); - if(target) - return static_cast(target); - } - boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - throw boost::python::argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return 0; -#endif - } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - return 0; - else - return non_null_from_python(obj, boost::python::type()); - } - - // Extract from obj a mutable reference to the PtrType object which is holding a T. - template - static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_ptr_holder* held = - dynamic_cast*>(*p); - if (held != 0) - return held->ptr(); - } - boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - throw boost::python::argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return *(PtrType*)0; -#endif - } - - // Extract from obj a reference to the PtrType object which is holding a - // T. If it weren't for auto_ptr, it would be a constant reference. Do not - // modify the referent except by copying an auto_ptr! If obj is None, the - // reference denotes a default-constructed PtrType - template - static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - { - static PtrType null_ptr; - return null_ptr; - } - return smart_ptr_reference(obj, boost::python::type()); - } - - template - static PyObject* smart_ptr_to_python(PtrType x) - { - if (boost::python::detail::is_null(x)) - { - return boost::python::detail::none(); - } - - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_ptr_holder(x))); - return result.release(); - } - - static boost::python::reference create_instance() - { - PyTypeObject* class_object = boost::python::detail::class_registry::class_object(); - if (class_object == 0) - boost::python::detail::report_missing_class_object(typeid(T)); - - return boost::python::reference( - new boost::python::detail::extension_instance(class_object)); - } - - // Convert to const T* - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to const T* const& - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T* const& - friend T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T& - friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } - - // Convert to const T& - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend std::auto_ptr from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(std::auto_ptr x) - { return smart_ptr_to_python(x); } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(boost::shared_ptr x) - { return smart_ptr_to_python(x); } -}; - -// Convert T to_python, instantiated on demand and only if there isn't a -// non-template overload for this function. This version is the one invoked when -// T is a wrapped class. See the first 2 functions declared in -// python_extension_class_converters above for more info. -template -PyObject* to_python(const T& x) -{ - return py_extension_class_converters(boost::python::type()).to_python(x); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters); - -namespace detail { - -template class instance_holder; - -class BOOST_PYTHON_DECL read_only_setattr_function : public function -{ - public: - read_only_setattr_function(const char* name); - PyObject* do_call(PyObject* args, PyObject* keywords) const; - const char* description() const; - private: - string m_name; -}; - - template - struct define_conversion - { - static void* upcast_ptr(void* v) - { - return static_cast(static_cast(v)); - } - - static void* downcast_ptr(void* v) - { - return dynamic_cast(static_cast(v)); - } - }; - -// An easy way to make an extension base class which wraps T. Note that Python -// subclasses of this class will simply be class_t objects. -// -// U should be a class derived from T which overrides virtual functions with -// boilerplate code to call back into Python. See extclass_demo.h for examples. -// -// U is optional, but you won't be able to override any member functions in -// Python which are called from C++ if you don't supply it. If you just want to -// be able to use T in python without overriding member functions, you can omit -// U. -template > -class extension_class - : public python_extension_class_converters, // This generates the to_python/from_python functions - public extension_class_base -{ - public: - typedef T wrapped_type; - typedef U callback_type; - - // Construct with a name that comes from typeid(T).name(). The name only - // affects the objects of this class are represented through repr() - extension_class(); - - // Construct with the given name. The name only affects the objects of this - // class are represented through repr() - extension_class(const char* name); - - ~extension_class(); - - // define constructors -""" % args - + gen_function( -""" template <%(class A%n%:, %)> - inline void def(constructor<%(A%n%:, %)>) - // The following incantation builds a signature1, signature2,... object. It - // should _all_ get optimized away. - { add_constructor( - %(prepend(type::id(), - %) signature0()%()%)); - } -""", args) - + -""" - - // export homogeneous operators (type of both lhs and rhs is 'operator') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>()); - - // export homogeneous operators (type of both lhs and rhs is 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>()); - template - inline void def(operators) - { - typedef typename operand_select::template wrapped::type true_operand; - def_operators(operators()); - } - - // export heterogeneous operators (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::right_operand()); - - // export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::right_operand()); - template - inline void def(operators, right_operand r) - { - typedef typename operand_select::template wrapped::type true_left; - def_operators(operators(), r); - } - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::left_operand()); - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::left_operand()); - template - inline void def(operators, left_operand l) - { - typedef typename operand_select::template wrapped::type true_right; - def_operators(operators(), l); - } - - // define a function that passes Python arguments and keywords - // to C++ verbatim (as a 'tuple const&' and 'dictionary const&' - // respectively). This is useful for manual argument passing. - // It's also the only possibility to pass keyword arguments to C++. - // Fn must have a signatur that is compatible to - // PyObject* (*)(PyObject* aTuple, PyObject* aDictionary) - template - inline void def_raw(Fn fn, const char* name) - { - this->add_method(new_raw_arguments_function(fn), name); - } - - // define member functions. In fact this works for free functions, too - - // they act like static member functions, or if they start with the - // appropriate self argument (as a pointer), they can be used just like - // ordinary member functions -- just like Python! - template - inline void def(Fn fn, const char* name) - { - this->add_method(new_wrapped_function(fn), name); - } - - // Define a virtual member function with a default implementation. - // default_fn should be a function which provides the default implementation. - // Be careful that default_fn does not in fact call fn virtually! - template - inline void def(Fn fn, const char* name, DefaultFn default_fn) - { - this->add_method(new_virtual_function(type(), fn, default_fn), name); - } - - // Provide a function which implements x., reading from the given - // member (pm) of the T obj - template - inline void def_getter(MemberType T::*pm, const char* name) - { - this->add_getter_method(new getter_function(pm), name); - } - - // Provide a function which implements assignment to x., writing to - // the given member (pm) of the T obj - template - inline void def_setter(MemberType T::*pm, const char* name) - { - this->add_setter_method(new setter_function(pm), name); - } - - // Expose the given member (pm) of the T obj as a read-only attribute - template - inline void def_readonly(MemberType T::*pm, const char* name) - { - this->add_setter_method(new read_only_setattr_function(name), name); - this->def_getter(pm, name); - } - - // Expose the given member (pm) of the T obj as a read/write attribute - template - inline void def_read_write(MemberType T::*pm, const char* name) - { - this->def_getter(pm, name); - this->def_setter(pm, name); - } - - // define the standard coercion needed for operator overloading - void def_standard_coerce(); - - // declare the given class a base class of this one and register - // up and down conversion functions - template - void declare_base(extension_class* base) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, - &define_conversion::downcast_ptr); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - // declare the given class a base class of this one and register - // only up conversion function - template - void declare_base(extension_class* base, without_downcast_t) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, 0); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - private: // types - typedef instance_value_holder holder; - - private: // extension_class_base virtual function implementations - std::vector const& base_classes() const; - std::vector const& derived_classes() const; - void* extract_object_from_holder(instance_holder_base* v) const; - - private: // Utility functions - template - inline void def_operators(operators) - { - def_standard_coerce(); - - // for some strange reason, this prevents MSVC from having an - // "unrecoverable block scoping error"! - typedef choose_op<(which & op_add)> choose_add; - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - choose_unary_op<(which & op_neg)>::template args::add(this); - choose_unary_op<(which & op_pos)>::template args::add(this); - choose_unary_op<(which & op_abs)>::template args::add(this); - choose_unary_op<(which & op_invert)>::template args::add(this); - choose_unary_op<(which & op_int)>::template args::add(this); - choose_unary_op<(which & op_long)>::template args::add(this); - choose_unary_op<(which & op_float)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_unary_op<(which & op_str)>::template args::add(this); - } - - template - inline void def_operators(operators, right_operand) - { - def_standard_coerce(); - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - } - - template - inline void def_operators(operators, left_operand) - { - def_standard_coerce(); - - choose_rop<(which & op_add)>::template args::add(this); - choose_rop<(which & op_sub)>::template args::add(this); - choose_rop<(which & op_mul)>::template args::add(this); - choose_rop<(which & op_div)>::template args::add(this); - choose_rop<(which & op_mod)>::template args::add(this); - choose_rop<(which & op_divmod)>::template args::add(this); - choose_rop<(which & op_pow)>::template args::add(this); - choose_rop<(which & op_lshift)>::template args::add(this); - choose_rop<(which & op_rshift)>::template args::add(this); - choose_rop<(which & op_and)>::template args::add(this); - choose_rop<(which & op_xor)>::template args::add(this); - choose_rop<(which & op_or)>::template args::add(this); - choose_rop<(which & op_cmp)>::template args::add(this); - } - - template - void add_constructor(signature sig) - { - this->add_constructor_object(init_function::create(sig)); - } -}; - -// A simple wrapper over a T which allows us to use extension_class with a -// single template parameter only. See extension_class, above. -template -class held_instance : public Held -{ - // There are no member functions: we want to avoid inadvertently overriding - // any virtual functions in Held. -public:""" - + gen_functions("""%{ - template <%(class A%n%:, %)>%} - held_instance(PyObject*%(, A%n% a%n%)) : Held( - %(typename unwrap_parameter::type(a%n)%: - , %)) {}""", args) - + """ -}; - -// Abstract base class for all obj holders. Base for template class -// instance_holder<>, below. -class BOOST_PYTHON_DECL instance_holder_base -{ -public: - virtual ~instance_holder_base() {} - virtual bool held_by_value() = 0; -}; - -// Abstract base class which holds a Held, somehow. Provides a uniform way to -// get a pointer to the held object -template -class instance_holder : public instance_holder_base -{ -public: - virtual Held*target() = 0; -}; - -// Concrete class which holds a Held by way of a wrapper class Wrapper. If Held -// can be constructed with arguments (A1...An), Wrapper must have a -// corresponding constructor for arguments (PyObject*, A1...An). Wrapper is -// neccessary to implement virtual function callbacks (there must be a -// back-pointer to the actual Python object so that we can call any -// overrides). held_instance (above) is used as a default Wrapper class when -// there are no virtual functions. -template -class instance_value_holder : public instance_holder -{ -public: - Held* target() { return &m_held; } - Wrapper* value_target() { return &m_held; } - - instance_value_holder(extension_instance* p) : - m_held(p) {} - template - instance_value_holder(extension_instance* p, A1 a1) : - m_held(p, a1) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2) : - m_held(p, a1, a2) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3) : - m_held(p, a1, a2, a3) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4) : - m_held(p, a1, a2, a3, a4) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : - m_held(p, a1, a2, a3, a4, a5) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : - m_held(p, a1, a2, a3, a4, a5, a6) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : - m_held(p, a1, a2, a3, a4, a5, a6, a7) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return true; } - - private: - Wrapper m_held; -}; - -// Concrete class which holds a HeldType by way of a (possibly smart) pointer -// PtrType. By default, these are only generated for PtrType == -// std::auto_ptr and PtrType == boost::shared_ptr. -template -class instance_ptr_holder : public instance_holder -{ - public: - HeldType* target() { return &*m_ptr; } - PtrType& ptr() { return m_ptr; } - - instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return false; } - private: - PtrType m_ptr; -}; - -// -// Template function implementations -// - -template -extension_class::extension_class() - : extension_class_base(typeid(T).name()) -{ - class_registry::register_class(this); -} - -template -extension_class::extension_class(const char* name) - : extension_class_base(name) -{ - class_registry::register_class(this); -} - -template -void extension_class::def_standard_coerce() -{ - ref coerce_fct = dict().get_item(string("__coerce__")); - - if(coerce_fct.get() == 0) // not yet defined - this->def(&standard_coerce, "__coerce__"); -} - -template -inline -std::vector const& -extension_class::base_classes() const -{ - return class_registry::base_classes(); -} - -template -inline -std::vector const& -extension_class::derived_classes() const -{ - return class_registry::derived_classes(); -} - -template -void* extension_class::extract_object_from_holder(instance_holder_base* v) const -{ - instance_holder* held = dynamic_cast*>(v); - if(held) - return held->target(); - return 0; -} - -template -extension_class::~extension_class() -{ - class_registry::unregister_class(this); -} - -template -inline void class_registry::register_class(extension_class_base* p) -{ - // You're not expected to create more than one of these! - assert(static_class_object == 0); - static_class_object = p; -} - -template -inline void class_registry::unregister_class(extension_class_base* p) -{ - // The user should be destroying the same object they created. - assert(static_class_object == p); - (void)p; // unused in shipping version - static_class_object = 0; -} - -template -void class_registry::register_base_class(base_class_info const& i) -{ - static_base_class_info.push_back(i); -} - -template -void class_registry::register_derived_class(derived_class_info const& i) -{ - static_derived_class_info.push_back(i); -} - -template -std::vector const& class_registry::base_classes() -{ - return static_base_class_info; -} - -template -std::vector const& class_registry::derived_classes() -{ - return static_derived_class_info; -} - -// -// Static data member declaration. -// -template -extension_class_base* class_registry::static_class_object; -template -std::vector class_registry::static_base_class_info; -template -std::vector class_registry::static_derived_class_info; - -}}} // namespace boost::python::detail - -#endif // EXTENSION_CLASS_DWA052000_H_ -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_extclass(args) diff --git a/src/gen_function.py b/src/gen_function.py deleted file mode 100644 index dba53c3b..00000000 --- a/src/gen_function.py +++ /dev/null @@ -1,243 +0,0 @@ -r""" ->>> template = ''' template -... static PyObject* call( %1(T::*pmf)(%(A%+%:, %))%2, PyObject* args, PyObject* ) { -... PyObject* self; -... %( PyObject* a%+; -... %) if (!PyArg_ParseTuple(args, const_cast("O%(O%)"), &self%(, &a%+%))) -... return 0; -... T& target = from_python(self, type()); -... %3to_python((target.*pmf)(%( -... from_python(a%+, type())%:,%) -... ));%4 -... }''' - ->>> print gen_function(template, 0, 'R ', '', 'return ', '') - template - static PyObject* call( R (T::*pmf)(), PyObject* args, PyObject* ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)( - )); - } - ->>> print gen_function(template, 2, 'R ', '', 'return ', '') - template - static PyObject* call( R (T::*pmf)(A1, A2), PyObject* args, PyObject* ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)( - from_python(a1, type()), - from_python(a2, type()) - )); - } - ->>> print gen_function(template, 3, 'void ', ' const', '', '\n'+8*' ' + 'return none();') - template - static PyObject* call( void (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - to_python((target.*pmf)( - from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()) - )); - return none(); - } -""" -import string - -def _find(s, sub, start=0, end=None): - """Just like string.find, except it returns end or len(s) when not found. - """ - if end == None: - end = len(s) - - pos = string.find(s, sub, start, end) - if pos < 0: - return end - else: - return pos - -def _raise_no_argument(key, n, args): - raise IndexError(str(key) + " extra arg(s) not passed to gen_function") - -def _gen_common_key(key, n, args, fill = _raise_no_argument): - # import sys - # print >> sys.stderr, "_gen_common_key(", repr(key), ",", repr(n), ',', repr(args), ',', fill, ')' - # sys.stderr.flush() - if len(key) > 0 and key in '123456789': - index = int(key) - 1; - - if index >= len(args): - return fill(key, n, args) - - arg = args[index] - if callable(arg): - return str(arg(key, n, args)) - else: - return str(arg) - elif key in ('x','n','-','+'): - return str(n + {'-':-1,'+':+1,'x':0,'n':0}[key]) - else: - return key - -def _gen_arg(template, n, args, fill = _raise_no_argument): - - result = '' - i = 0 - while i < len(template): # until the template is consumed - # consume everything up to the first '%' - delimiter_pos = _find(template, '%', i) - result = result + template[i:delimiter_pos] - - # The start position of whatever comes after the '%'+key - start = delimiter_pos + 2 - key = template[start - 1 : start] # the key character. If there were no - # '%'s left, key will be empty - - if 0 and key == 'n': - result = result + `n` - else: - result = result + _gen_common_key(key, n, args, fill) - - i = start - - return result - -def gen_function(template, n, *args, **keywords): - r"""gen_function(template, n, [args...] ) -> string - - Generate a function declaration based on the given template. - - Sections of the template between '%(', '%)' pairs are repeated n times. If '%:' - appears in the middle, it denotes the beginning of a '%'. - - Sections of the template between '%{', '%}' pairs are ommitted if n == 0. - - %n is transformed into the string representation of 1..n for each - repetition within %(...%). Elsewhere, %n is transformed into the - string representation of n - - %- is transformed into the string representation of 0..n-1 for - each repetition within %(...%). Elsewhere, %- is transformed into the - string representation of n-1. - - %+ is transformed into the string representation of 2..n+1 for - each repetition within %(...%). Elsewhere, %- is transformed into the - string representation of n+1. - - %x is always transformed into the string representation of n - - %z, where z is a digit, selects the corresponding additional - argument. If that argument is callable, it is called with three - arguments: - key - the string representation of 'z' - n - the iteration number - args - a tuple consisting of all the additional arguments to - this function - otherwise, the selected argument is converted to a string representation - - - for example, - - >>> gen_function('%1 abc%x(%(int a%n%:, %));%{ // all args are ints%}', 2, 'void') - 'void abc2(int a0, int a1); // all args are ints' - - >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, 'x') - 'x abc();' - - >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, lambda key, n, args: 'abcd'[n]) - 'a abc();' - - >>> gen_function('%2 %1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, 'x', fill = lambda key, n, args: 'const') - 'const x abc();' - - >>> gen_function('abc%[k%:v%]', 0, fill = lambda key, n, args, value = None: '<' + key + ',' + value + '>') - 'abc' - -""" - expand = (lambda s, n = n: - apply(gen_function, (s, n) + args, keywords)) - - fill = keywords.get('fill', _raise_no_argument); - result = '' - i = 0 - while i < len(template): # until the template is consumed - # consume everything up to the first '%' - delimiter_pos = _find(template, '%', i) - result = result + template[i:delimiter_pos] - - # The start position of whatever comes after the '%'+key - start = delimiter_pos + 2 - key = template[start - 1 : start] # the key character. If there were no - # '%'s left, key will be empty - - pairs = { '(':')', '{':'}', '[':']' } - - if key in pairs.keys(): - end = string.find(template, '%' + pairs[key], start) - assert end >= 0, "Matching '" + '%' + pairs[key] +"' not found!" - delimiter_pos = end - - if key == '{': - if n > 0: - result = result + expand(template[start:end]) - else: - separator_pos = _find(template, '%:', start, end) - remainder = template[separator_pos+2 : end] - - if key == '(': - for x in range(n): - - iteration = expand( - template[start:separator_pos], x) - - result = result + expand(iteration, x) - - if x != n - 1: - result = result + expand(remainder, x) - else: - function_result = fill( - template[start:separator_pos], n, args, value = remainder) - result = result + expand(function_result) - - else: - result = result + expand(_gen_common_key(key, n, args, fill)) - - i = delimiter_pos + 2 - - return result - -def gen_functions(template, n, *args, **keywords): - r"""gen_functions(template, n, [args...]) -> string - - Call gen_function repeatedly with from 0..n and the given optional - arguments. - - >>> print gen_functions('%1 abc(%(int a%n%:, %));%{ // all args are ints%}\n', 2, 'void'), - void abc(); - void abc(int a0); // all args are ints - void abc(int a0, int a1); // all args are ints - - """ - fill = keywords.get('fill', _raise_no_argument); - result = '' - for x in range(n + 1): - result = result + apply(gen_function, (template, x) + args, keywords) - return result - -if __name__ == '__main__': - import doctest - import sys - doctest.testmod(sys.modules.get(__name__)) diff --git a/src/gen_init_function.py b/src/gen_init_function.py deleted file mode 100644 index ff294dbb..00000000 --- a/src/gen_init_function.py +++ /dev/null @@ -1,215 +0,0 @@ -from gen_function import * -import string - -def gen_init_function(args): - - return ( -"""// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for %d-argument constructors by gen_init_function.python - -#ifndef INIT_FUNCTION_DWA052000_H_ -# define INIT_FUNCTION_DWA052000_H_ - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail { - - // parameter_traits - so far, this is a way to pass a const T& when we can be - // sure T is not a reference type, and a raw T otherwise. This should be - // rolled into boost::call_traits. Ordinarily, parameter_traits would be - // written: - // - // template struct parameter_traits - // { - // typedef const T& const_reference; - // }; - // - // template struct parameter_traits - // { - // typedef T& const_reference; - // }; - // - // template <> struct parameter_traits - // { - // typedef void const_reference; - // }; - // - // ...but since we can't partially specialize on reference types, we need this - // long-winded but equivalent incantation. - - // const_ref_selector -- an implementation detail of parameter_traits (below). This uses - // the usual "poor man's partial specialization" hack for MSVC. - template - struct const_ref_selector - { - template - struct const_ref - { - typedef const T& type; - }; - }; - - template <> - struct const_ref_selector - { - template - struct const_ref - { - typedef T type; - }; - }; - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable: 4181) -# endif // BOOST_MSVC - template - struct parameter_traits - { - private: - enum { is_ref = boost::is_reference::value }; - typedef const_ref_selector selector; - public: - typedef typename selector::template const_ref::type const_reference; - }; -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif // BOOST_MSVC - - // Full spcialization for void - template <> - struct parameter_traits - { - typedef void const_reference; - }; - - struct reference_parameter_base {}; - - template - class reference_parameter - : public reference_parameter_base - { - public: - typedef typename parameter_traits::const_reference const_reference; - reference_parameter(const_reference value) - : value(value) {} - operator const_reference() { return value; } - private: - const_reference value; - }; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct unwrap_parameter - { - typedef typename boost::add_reference::type type; - }; - - template - struct unwrap_parameter > - { - typedef typename reference_parameter::const_reference type; - }; -# else - template - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename T::const_reference type; - }; - }; - - template <> - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename add_reference::type type; - }; - }; - - template - struct unwrap_parameter - { - BOOST_STATIC_CONSTANT( - bool, is_wrapped = (is_base_and_derived::value)); - - typedef typename unwrap_parameter_helper< - is_wrapped - >::template apply::type type; - }; -# endif - -class extension_instance; -class instance_holder_base; - -class init; -""" - + gen_functions('template struct init%x;\n', args) - + """ -template -struct init_function -{ -""" + gen_functions("""%{ - template <%(class A%n%:, %)> -%} static init* create(signature%x%{<%(A%n%:, %)>%}) { - return new init%x::const_reference%)>; - } -""", args)+"""}; - -class init : public function -{ -private: // override function hook - PyObject* do_call(PyObject* args, PyObject* keywords) const; -private: - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0; -}; -""" + gen_functions(""" - -template -struct init%x : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - %(PyObject* a%n; - %)if (!PyArg_ParseTuple(args, const_cast("%(O%)")%(, &a%n%))) - throw argument_error(); - return new T(self%(, - boost::python::detail::reference_parameter(from_python(a%n, type()))%) - ); - } - const char* description() const - { return typeid(void (*)(T&%(, A%n%%))).name(); } -};""", args) + """ - -}}} // namespace boost::python::detail - -#endif // INIT_FUNCTION_DWA052000_H_ -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_init_function(args) - diff --git a/src/gen_returning.py b/src/gen_returning.py deleted file mode 100644 index 80e3342b..00000000 --- a/src/gen_returning.py +++ /dev/null @@ -1,185 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_returning.py -''' - -body_sections = ( -''' -#ifndef RETURNING_DWA20011201_HPP -# define RETURNING_DWA20011201_HPP - -//# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// Calling C++ from Python -template -struct returning -{ -''', -''' -''', -''' // Free functions -''', -'''}; - -template <> -struct returning -{ - typedef void R; -''', -''' -''', -''' - // Free functions -''', -'''}; - -}}} // namespace boost::python::detail - -#endif // RETURNING_DWA20011201_HPP -''') - -#' - -member_function = ''' template - static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args, PyObject* /* keywords */ ) - { - // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); -%( unwrap_more c%+(PyTuple_GET_ITEM(args, %+), c%n); -%) -%[r%: // find the result converter - wrap_more r(c%n); -%] if (!c0) return 0; - %[r%:return r( %]((*c0).*pmf)(%(*c%+%:, %))%[r%: )%];%[v%: - return detail::none();%] - } -''' - -free_function = '''%{ template <%(class A%n%:, %)> -%} static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject*%{ args%}, PyObject* /* keywords */ ) - {%{ - // check that each of the arguments is convertible -%}%( unwrap%{_more%} c%n(PyTuple_GET_ITEM(args, %n)%{, c%-%}); -%)%[r%: - // find the result converter - wrap%{_more%} c%n%{(c%-)%};%]%[not-void-and-0-arg%: - if (!c0) return 0;%] - %[r%:return c%n( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%: - return detail::none();%] - } -''' - -def _returns_value(key, n, args, value): - if key != 'v': - return value - else: - return '' - -def _returns_void(key, n, args, value): - if key == 'v' or key == 'not-void-and-0-arg' and n != 0: - return value - else: - return '' - -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -_prefix = { -# ' const': ''' - -# // missing cv-qualified -> cv-unqualified member pointer conversions -# # if defined(__MWERKS__) && __MWERKS__ <=0x2406 || defined(BOOST_MSVC) && BOOST_MSVC <= 1200 || defined(__BORLANDC__) -# ''', - ' const volatile': ''' -// missing const volatile type traits -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -'''}; - -def gen_returning(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + body_sections[0] - # - # functions returning results - # - - + reduce(lambda x,y: x+y - , map(lambda cv: - _prefix.get(cv,'') - + gen_functions(member_function, - member_function_args, cv, - fill = _returns_value) + '\n' - , _cv_qualifiers)) - + '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -''' -## endif // missing cv-qualified -> cv-unqualified member pointer conversions -#''' - # free functions - + gen_functions(free_function, free_function_args, fill = _returns_value) - + body_sections[3] - - # - # functions returning void - # - - + reduce(lambda x,y: x+y - , map(lambda cv: - _prefix.get(cv,'') - + gen_functions(member_function, - member_function_args, cv, fill = - _returns_void) + '\n' - , _cv_qualifiers)) - - + '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -''' -## endif // missing cv-qualified -> cv-unqualified member pointer conversions -#''' - # free functions - + gen_functions(free_function, free_function_args, fill = _returns_void) - + body_sections[6] - ) - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_returning(member_function_args, free_function_args) - - diff --git a/src/gen_signature.py b/src/gen_signature.py deleted file mode 100644 index 1af3437d..00000000 --- a/src/gen_signature.py +++ /dev/null @@ -1,90 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// (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 %d-argument member functions and %d-argument free -// functions by gen_signature.py -''' - -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -_suffix = { - '': ''' -// Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 -''', ' const volatile': ''' -# endif // __MWERKS__ -''' - }; - -def gen_arg_tuple_size(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + ''' -#ifndef SIGNATURE_DWA2002128_HPP -# define SIGNATURE_DWA2002128_HPP - -# include - -namespace boost { namespace python { namespace detail { -''' - - + gen_functions(''' -template -mpl::type_list -signature(R (*)(%(A%n%:, %))) -{ - return mpl::type_list() -} -''', free_function_args) - - + reduce(lambda x,y: x+'\n'+y - , map( - lambda cv: gen_functions( -'''template -mpl::type_list signature(R (A0::*)(%(A%+%:, %))%1) -{ - return mpl::type_list(); -} - -''', member_function_args, cv) - , _cv_qualifiers)) + '''}}} // namespace boost::python::detail - -#endif // SIGNATURE_DWA2002128_HPP -''') - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_arg_tuple_size(member_function_args, free_function_args) - - diff --git a/src/gen_signatures.py b/src/gen_signatures.py deleted file mode 100644 index f5a97b17..00000000 --- a/src/gen_signatures.py +++ /dev/null @@ -1,158 +0,0 @@ -from gen_function import * -import string - -def gen_struct_signatures(args): - result = '' - for n in range(args, -1, -1): - result = ( - result + gen_function("""%{template <%(class T%n%:, %)> -%}struct signature%x {}; - -""", n) -# + ((n == args) and [""] or -# [gen_function(""" -# template -# static inline signature%1 prepend(type) -# { return signature%1(); }""", -# n, (str(n+1),)) -# ] -# )[0] -# -# + ((n != 0) and [""] or -# [""" -# // This one terminates the chain. Prepending void_t to the head of a void_t -# // signature results in a void_t signature again. -# static inline signature0 prepend(void_t) { return signature0(); }"""] -# )[0] -# + """ -#}; -# -#""" - + ((n == args) and [""] or - [gen_function( -"""template <%(class T%n%, %)class X> -inline signature%1 prepend(type, signature%x%{<%(T%n%:, %)>%}) - { return signature%1(); } - -""", n, str(n+1)) - ] - )[0] - ) - return result - -def gen_signatures(args): - return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated by gen_signatures.python for %d arguments. -#ifndef SIGNATURES_DWA050900_H_ -# define SIGNATURES_DWA050900_H_ - -# include - -namespace boost { namespace python { - -namespace detail { -// A stand-in for the built-in void. This one can be passed to functions and -// (under MSVC, which has a bug, be used as a default template type parameter). -struct void_t {}; -} - -// An envelope in which type information can be delivered for the purposes -// of selecting an overloaded from_python() function. This is needed to work -// around MSVC's lack of partial specialiation/ordering. Where normally we'd -// want to form a function call like void f(), We instead pass -// type as one of the function parameters to select a particular -// overload. -// -// The id typedef helps us deal with the lack of partial ordering by generating -// unique types for constructor signatures. In general, type::id is type, -// but type::id is just void_t. -template -struct type -{ - typedef type id; -}; - -template <> -struct type -{ - typedef boost::python::detail::void_t id; -}; - -namespace detail { -// These basically encapsulate a chain of types, , used to make the syntax of -// add(constructor()) work. We need to produce a unique type for each number -// of non-default parameters to constructor<>. Q: why not use a recursive -// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs -// that involve recursive template nesting. -// -// signature chaining -""" % args - + gen_struct_signatures(args) - + """ -// This one terminates the chain. Prepending void_t to the head of a void_t -// signature results in a void_t signature again. -inline signature0 prepend(void_t, signature0) { return signature0(); } - -} // namespace detail -""" - + gen_function(""" -template <%(class A%n% = detail::void_t%:, %)> -struct constructor -{ -}; -""", args) - + """ -namespace detail { -// Return value extraction: - -// This is just another little envelope for carrying a typedef (see type, -// above). I could have re-used type, but that has a very specific purpose. I -// thought this would be clearer. -template -struct return_value_select { typedef T type; }; - -// free functions""" - + gen_functions(""" -template -return_value_select return_value(R (*)(%(A%n%:, %))) { return return_value_select(); } -""", args) - - + -""" -// TODO(?): handle 'const void' - -// member functions""" - + gen_functions(""" -template -return_value_select return_value(R (T::*)(%(A%n%:, %))) { return return_value_select(); } -""", args) - - + gen_functions(""" -template -return_value_select return_value(R (T::*)(%(A%n%:, %)) const) { return return_value_select(); } -""", args) - - + """ -}}} // namespace boost::python::detail - -#endif -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_signatures(args) - diff --git a/src/gen_singleton.py b/src/gen_singleton.py deleted file mode 100644 index 3a5ca7e3..00000000 --- a/src/gen_singleton.py +++ /dev/null @@ -1,58 +0,0 @@ -from gen_function import * -import string - -def gen_singleton(args): - return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef SINGLETON_DWA051900_H_ -# define SINGLETON_DWA051900_H_ - -# include - -namespace boost { namespace python { namespace detail { - -struct empty {}; -template -struct singleton : Base -{ - typedef singleton singleton_base; // Convenience type for derived class constructors - - static Derived* instance(); - - // Pass-through constructors -""" - + gen_functions("""%{ - template <%(class A%n%:, %)> -%} singleton(%(const A%n& a%n%:, %)) : Base(%(a%n%:, %)) {} -""", args) - + """ -}; - -template -Derived* singleton::instance() -{ - static Derived x; - return &x; -} - -}}} // namespace boost::python::detail - -#endif -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_singleton(args) diff --git a/src/gen_value_holder.py b/src/gen_value_holder.py deleted file mode 100644 index b01e2c0e..00000000 --- a/src/gen_value_holder.py +++ /dev/null @@ -1,35 +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. -# -# This work was funded in part by Lawrence Livermore National Labs - -from gen_function import * -import string - -def _generate(member_function_args, free_function_args = None): - return ('''// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_HOLDER_DWA20011215_HPP -# define VALUE_HOLDER_DWA20011215_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct value_holder : instance_holder -{ - // Forward construction to the held object -''' - + - gen_functions( diff --git a/src/init_function.cpp b/src/init_function.cpp deleted file mode 100644 index 1ebfa501..00000000 --- a/src/init_function.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include - -namespace boost { namespace python { namespace detail { - - PyObject* init::do_call(PyObject* args_, PyObject* keywords) const - { - tuple args(ref(args_, ref::increment_count)); - if (args[0]->ob_type->ob_type != extension_meta_class()) - { - PyErr_SetString(PyExc_TypeError, "argument 1 to __init__ must be an ExtensionInstance"); - return 0; - } - - extension_instance *self = static_cast(args[0].get()); - - tuple ctor_args = args.slice(1, args.size()); - - std::auto_ptr result( - create_holder(self, ctor_args.get(), keywords)); - - self->add_implementation(result); - return none(); - } - -}}} // namespace boost::python::detail diff --git a/src/module.cpp b/src/module.cpp deleted file mode 100644 index dbc81729..00000000 --- a/src/module.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#include - -namespace boost { namespace python { - -module_base::module_base(const char* name) - : m_module( - Py_InitModule(const_cast(name), initial_methods) - , ref::increment_count) -{ -} - -module_base::~module_base() -{ -} - -void module_base::setattr(const char* name, PyObject* x) -{ - setattr(name, ref(x)); -} - -void module_base::setattr(char const* name, ref const& x) -{ - // Use function::add_to_namespace to achieve overloading if - // appropriate. - objects::function::add_to_namespace(m_module, name, x); -} - -void module_base::add(PyTypeObject* x) -{ - this->setattr(x->tp_name, (PyObject*)x); -} - -void module_base::add_type(ref x) -{ - assert(PyObject_TypeCheck(x.get(), &PyType_Type)); - add((PyTypeObject*)x.release()); -} - -PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; - -}} // namespace boost::python diff --git a/src/module_builder.cpp b/src/module_builder.cpp deleted file mode 100644 index 0a195621..00000000 --- a/src/module_builder.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#define BOOST_PYTHON_SOURCE - -#include - -namespace boost { namespace python { - -namespace { - ref name_holder; -} - -bool module_builder_base::initializing() -{ - return name_holder.get() != 0; -} - -string module_builder_base::name() -{ - // If this fails, you haven't created a module_builder object - assert(initializing()); - return string(name_holder); -} - -module_builder_base::module_builder_base(const char* name) - : m_module(Py_InitModule(const_cast(name), initial_methods)) -{ - // If this fails, you've created more than 1 module_builder object in your module - assert(name_holder.get() == 0); - name_holder = ref(PyObject_GetAttrString(m_module, const_cast("__name__"))); -} - -module_builder_base::~module_builder_base() -{ - name_holder.reset(); -} - -void -module_builder_base::add(detail::function* x, const char* name) -{ - reference f(x); // First take possession of the object. - detail::function::add_to_namespace(f, name, PyModule_GetDict(m_module)); -} - -void module_builder_base::add(ref x, const char* name) -{ - PyObject* dictionary = PyModule_GetDict(m_module); - PyDict_SetItemString(dictionary, const_cast(name), x.get()); -} - -void module_builder_base::add(PyTypeObject* x, const char* name /*= 0*/) -{ - this->add(ref(as_object(x)), name ? name : x->tp_name); -} - -PyMethodDef module_builder_base::initial_methods[] = { { 0, 0, 0, 0 } }; - -}} // namespace boost::python diff --git a/src/object/class.cpp b/src/object/class.cpp deleted file mode 100644 index 5d1ecf01..00000000 --- a/src/object/class.cpp +++ /dev/null @@ -1,237 +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. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { namespace objects { - -instance_holder::instance_holder() - : m_next(0) -{ -} - -instance_holder::~instance_holder() -{ -} - -PyTypeObject class_metatype_object = { - PyObject_HEAD_INIT(0)//&PyType_Type) - 0, - "Boost.Python.class", - PyType_Type.tp_basicsize, - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyType_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, - // PyType_GenericNew /* tp_new */ -}; - -// Get the metatype object for all extension classes. -BOOST_PYTHON_DECL ref class_metatype() -{ - if (class_metatype_object.tp_dict == 0) - { - class_metatype_object.ob_type = &PyType_Type; - class_metatype_object.tp_base = &PyType_Type; - if (PyType_Ready(&class_metatype_object)) - return ref(); - } - return ref((PyObject*)&class_metatype_object, ref::increment_count); -} - -// Do we really need this? I'm beginning to think we don't! -PyTypeObject class_type_object = { - PyObject_HEAD_INIT(0) //&class_metatype_object) - 0, - "Boost.Python.instance", - sizeof(instance), - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew -}; - -BOOST_PYTHON_DECL ref class_type() -{ - if (class_type_object.tp_dict == 0) - { - class_type_object.ob_type = (PyTypeObject*)class_metatype().release(); - class_type_object.tp_base = &PyBaseObject_Type; - if (PyType_Ready(&class_type_object)) - return ref(); - } - return ref((PyObject*)&class_type_object, ref::increment_count); -} - -// Install the instance data for a C++ object into a Python instance -// object. -void instance_holder::install(PyObject* self) throw() -{ - assert(self->ob_type->ob_type == &class_metatype_object); - m_next = ((instance*)self)->objects; - ((instance*)self)->objects = this; -} - -BOOST_PYTHON_DECL void* -find_instance_impl(PyObject* inst, converter::type_id_t type) -{ - if (inst->ob_type->ob_type != &class_metatype_object) - return 0; - - instance* self = reinterpret_cast(inst); - - for (instance_holder::iterator match(self->objects), end(0); match != end; ++match) - { - void* const found = (*match).holds(type); - if (found) - return found; - } - return 0; -} - -namespace -{ - struct class_registry - { - public: - ref get(class_id id) const; - void set(class_id, ref class_object); - private: - typedef detail::map_entry entry; - std::vector m_impl; - }; - - class_registry& registry() - { - static class_registry x; - return x; - } - - ref class_registry::get(class_id id) const - { - std::vector::const_iterator start = m_impl.begin(); - std::vector::const_iterator finish = m_impl.end(); - - std::vector::const_iterator p - = boost::detail::lower_bound(start, finish, id); - - if (p == finish && p->key != id) - { - string report("extension class wrapper for base class "); - (report += id.name()) += " has not been created yet"; - PyErr_SetObject(PyExc_RuntimeError, report.get()); - throw error_already_set(); - } - return p->value; - } - - void class_registry::set(class_id id, ref object) - { - std::vector::iterator start = m_impl.begin(); - std::vector::iterator finish = m_impl.end(); - m_impl.insert( - boost::detail::lower_bound(start, finish, id) - , entry(id, object)); - } -} - -class_base::class_base( - char const* name, std::size_t num_types, class_id const* const types) -{ - class_registry& r = registry(); - assert(num_types >= 1); - tuple bases(std::max(num_types - 1, static_cast(1))); - if (num_types > 1) - { - for (std::size_t i = 1; i < num_types; ++i) - bases.set_item(i - 1, r.get(types[i])); - } - else - { - bases.set_item(0, class_type()); - } - - tuple args(3); - args.set_item(0, string(name).reference()); - args.set_item(1, bases.reference()); - args.set_item(2, dictionary().reference()); - - m_object = ref(PyObject_CallObject(class_metatype().get(), args.get())); - r.set(types[0], m_object); -} - -}}} // namespace boost::python::objects diff --git a/src/object/function.cpp b/src/object/function.cpp deleted file mode 100644 index a30e9f15..00000000 --- a/src/object/function.cpp +++ /dev/null @@ -1,182 +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. - -#include -#include -#include -#include - -namespace boost { namespace python { namespace objects { - - -function::function(py_function implementation, unsigned min_args, unsigned max_args) - : m_fn(implementation) - , m_min_args(min_args) - , m_max_args(std::max(max_args,min_args)) - , m_overloads(0) -{ - PyObject* p = this; - PyObject_INIT(p, &function_type); -} - -function::~function() -{ - PyObject* overloads = m_overloads; - Py_XDECREF(overloads); -} - -PyObject* function::call(PyObject* args, PyObject* keywords) const -{ - std::size_t nargs = PyTuple_GET_SIZE(args); - function const* f = this; - do - { - // Check for a plausible number of arguments - if (nargs >= f->m_min_args && nargs <= f->m_max_args) - { - // Call the function - PyObject* result = f->m_fn(args, keywords); - - // If the result is NULL but no error was set, m_fn failed - // the argument-matching test. - - // This assumes that all other error-reporters are - // well-behaved and never return NULL to python without - // setting an error. - if (result != 0 || PyErr_Occurred()) - return result; - } - f = f->m_overloads; - } - while (f); - // None of the overloads matched; time to generate the error message - argument_error(args, keywords); - return 0; -} - -void function::argument_error(PyObject* args, PyObject* keywords) const -{ - // This function needs to be improved to do better error reporting. - PyErr_BadArgument(); -} - -void function::add_overload(function* overload_) -{ - Py_XINCREF(overload_); - - function* parent = this; - - while (parent->m_overloads != 0) - { - parent = parent->m_overloads; - } - parent->m_overloads = overload_; -} - -void function::add_to_namespace( - ref const& name_space, char const* name_, ref const& attribute) -{ - string const name(name_); - PyObject* const ns = name_space.get(); - - if (attribute->ob_type == &function_type) - { - PyObject* dict = 0; - - if (PyClass_Check(ns)) - dict = ((PyClassObject*)ns)->cl_dict; - else if (PyType_Check(ns)) - dict = ((PyTypeObject*)ns)->tp_dict; - else - dict = PyObject_GetAttrString(ns, "__dict__"); - - if (dict == 0) - throw error_already_set(); - - ref existing(PyObject_GetItem(dict, name.get()), ref::null_ok); - - if (existing.get() && existing->ob_type == &function_type) - { - static_cast(existing.get())->add_overload( - static_cast(attribute.get())); - return; - } - } - - // The PyObject_GetAttrString() call above left an active error - PyErr_Clear(); - if (PyObject_SetAttr(ns, name.get(), attribute.get()) < 0) - throw error_already_set(); -} - -extern "C" -{ - // Stolen from Python's funcobject.c - static PyObject * - function_descr_get(PyObject *func, PyObject *obj, PyObject *type_) - { - if (obj == Py_None) - obj = NULL; - return PyMethod_New(func, obj, type_); - } - - static void - function_dealloc(PyObject* p) - { - delete static_cast(p); - } - - static PyObject * - function_call(PyObject *func, PyObject *arg, PyObject *kw) - { - return static_cast(func)->call(arg, kw); - } -} - -PyTypeObject function_type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "Boost.Python.function", - sizeof(function), - 0, - (destructor)function_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, //(reprfunc)func_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - function_call, /* tp_call */ - 0, /* tp_str */ - 0, // PyObject_GenericGetAttr, /* tp_getattro */ - 0, // PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */ - 0, /* tp_doc */ - 0, // (traverseproc)func_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, //offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, // func_memberlist, /* tp_members */ - 0, //func_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - function_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, //offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, - 0 /* tp_new */ -}; - -}}} // namespace boost::python::objects diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp deleted file mode 100644 index 7efc980c..00000000 --- a/src/object/inheritance.cpp +++ /dev/null @@ -1,493 +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. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Procedure: -// -// The search is a BFS over the space of (type,address) pairs -// guided by the edges of the casting graph whose nodes -// correspond to classes, and whose edges are traversed by -// applying associated cast functions to an address. We use -// vertex distance to the goal node in the cast_graph to rate the -// paths. The vertex distance to any goal node is calculated on -// demand and outdated by the addition of edges to the graph. - -namespace boost { -namespace -{ - enum edge_cast_t { edge_cast = 8010 }; -} - -// Install properties -BOOST_INSTALL_PROPERTY(edge, cast); - -namespace -{ - typedef void*(*cast_function)(void*); - - // - // Here we put together the low-level data structures of the - // casting graph representation. - // - typedef python::converter::undecorated_type_id_t class_id; - - // represents a graph of available casts - -#if 0 - struct cast_graph - : -#else - typedef -#endif - adjacency_list > > -#if 0 - {}; -#else - cast_graph; -#endif - - typedef cast_graph::vertex_descriptor vertex_t; - typedef cast_graph::edge_descriptor edge_t; - - struct smart_graph - { - typedef std::vector::const_iterator node_distance_map; - - typedef std::pair out_edges_t; - - // Return a map of the distances from any node to the given - // target node - node_distance_map distances_to(vertex_t target) const - { - std::size_t n = num_vertices(m_topology); - if (m_distances.size() != n * n) - { - m_distances.clear(); - m_distances.resize(n * n, std::numeric_limits::max()); - m_known_vertices = n; - } - - std::vector::iterator to_target = m_distances.begin() + n * target; - - // this node hasn't been used as a target yet - if (to_target[target] != 0) - { - typedef reverse_graph reverse_cast_graph; - reverse_cast_graph reverse_topology(m_topology); - - to_target[target] = 0; - - breadth_first_search( - reverse_topology, target - , visitor( - make_bfs_visitor( - record_distances( - make_iterator_property_map( - to_target - , get(vertex_index, reverse_topology) -# ifdef BOOST_MSVC_STD_ITERATOR - , *to_target -# endif - ) - , on_tree_edge() - )))); - } - - return to_target; - } - - cast_graph& topology() { return m_topology; } - cast_graph const& topology() const { return m_topology; } - - std::size_t known_vertices() const { return m_known_vertices; } - - smart_graph() - : m_known_vertices(0) - {} - - private: - cast_graph m_topology; - mutable std::vector m_distances; - mutable std::size_t m_known_vertices; - }; - - smart_graph& full_graph() - { - static smart_graph x; - return x; - } - - smart_graph& up_graph() - { - static smart_graph x; - return x; - } - - // - // Our index of class types - // - using boost::python::objects::dynamic_id_function; - typedef tuples::tuple< - class_id // static type - , vertex_t // corresponding vertex - , dynamic_id_function // dynamic_id if polymorphic, or 0 - > - index_entry_interface; - typedef index_entry_interface::inherited index_entry; - enum { ksrc_static_t, kvertex, kdynamic_id }; - - typedef std::vector type_index_t; - - - type_index_t& type_index() - { - static type_index_t x; - return x; - } - - template - struct select1st - { - typedef typename tuples::element<0, Tuple>::type result_type; - - result_type const& operator()(Tuple const& x) const - { - return tuples::get<0>(x); - } - }; - - // map a type to a position in the index - inline type_index_t::iterator type_position(class_id type) - { - typedef index_entry entry; - - return std::lower_bound( - type_index().begin(), type_index().end() - , make_tuple(type, vertex_t(), dynamic_id_function(0)) - , boost::bind(std::less() - , boost::bind(select1st(), _1) - , boost::bind(select1st(), _2))); - } - - inline index_entry* seek_type(class_id type) - { - type_index_t::iterator p = type_position(type); - if (p == type_index().end() || tuples::get(*p) != type) - return 0; - else - return &*p; - } - - // Get the entry for a type, inserting if neccessary - inline type_index_t::iterator demand_type(class_id type) - { - type_index_t::iterator p = type_position(type); - - if (p != type_index().end() && tuples::get(*p) == type) - return p; - - vertex_t v = add_vertex(full_graph().topology()); - vertex_t v2 = add_vertex(up_graph().topology()); - assert(v == v2); - return type_index().insert(p, make_tuple(type, v, dynamic_id_function(0))); - } - - // Map a two types to a vertex in the graph, inserting if neccessary - typedef std::pair - type_index_iterator_pair; - - inline type_index_iterator_pair - demand_types(class_id t1, class_id t2) - { - // be sure there will be no reallocation - type_index().reserve(type_index().size() + 2); - type_index_t::iterator first = demand_type(t1); - type_index_t::iterator second = demand_type(t2); - if (first == second) - ++first; - return std::make_pair(first, second); - } - - struct q_elt - { - q_elt(std::size_t distance - , void* src_address - , vertex_t target - , cast_function cast - ) - : distance(distance) - , src_address(src_address) - , target(target) - , cast(cast) - {} - - std::size_t distance; - void* src_address; - vertex_t target; - cast_function cast; - - bool operator<(q_elt const& rhs) const - { - return distance < rhs.distance; - } - }; - - // Optimization: - // - // Given p, src_t, dst_t - // - // Get a pointer pd to the most-derived object - // if it's polymorphic, dynamic_cast to void* - // otherwise pd = p - // - // Get the most-derived typeid src_td - // - // ptrdiff_t offset = p - pd - // - // Now we can keep a cache, for [src_t, offset, src_td, dst_t] of - // the cast transformation function to use on p and the next src_t - // in the chain. src_td, dst_t don't change throughout this - // process. In order to represent unreachability, when a pair is - // found to be unreachable, we stick a 0-returning "dead-cast" - // function in the cache. - - // This is needed in a few places below - inline void* identity_cast(void* p) - { - return p; - } - - void* search(smart_graph const& g, void* p, vertex_t src, vertex_t dst) - { - // I think this test was thoroughly bogus -- dwa - // If we know there's no path; bail now. - // if (src > g.known_vertices() || dst > g.known_vertices()) - // return 0; - - smart_graph::node_distance_map d(g.distances_to(dst)); - - if (d[src] == std::numeric_limits::max()) - return 0; - - typedef property_map::const_type cast_map; - cast_map casts = get(edge_cast, g.topology()); - - typedef std::pair search_state; - typedef std::vector visited_t; - visited_t visited; - std::priority_queue q; - - q.push(q_elt(d[src], p, src, identity_cast)); - while (!q.empty()) - { - q_elt top = q.top(); - q.pop(); - - // Check to see if we have a real state - void* dst_address = top.cast(top.src_address); - if (dst_address == 0) - continue; - - if (top.target == dst) - return dst_address; - - search_state s(top.target,dst_address); - - visited_t::iterator pos = std::lower_bound( - visited.begin(), visited.end(), s); - - // If already visited, continue - if (pos != visited.end() && *pos == s) - continue; - - visited.insert(pos, s); // mark it - - // expand it: - smart_graph::out_edges_t edges = out_edges(s.first, g.topology()); - for (cast_graph::out_edge_iterator p = edges.first - , finish = edges.second - ; p != finish - ; ++p - ) - { - edge_t e = *p; - q.push(q_elt( - d[target(e, g.topology())] - , dst_address - , target(e, g.topology()) - , boost::get(casts, e))); - } - } - return 0; - } - - struct cache_element - { - typedef tuples::tuple< - class_id // source static type - , class_id // target type - , std::ptrdiff_t // offset within source object - , class_id // source dynamic type - >::inherited key_type; - - cache_element(key_type const& k) - : key(k) - , offset(0) - {} - - key_type key; - std::ptrdiff_t offset; - - BOOST_STATIC_CONSTANT( - std::ptrdiff_t, not_found = integer_traits::const_min); - - bool operator<(cache_element const& rhs) const - { - return this->key < rhs.key; - } - - bool unreachable() const - { - return offset == not_found; - } - }; - - enum { kdst_t = ksrc_static_t + 1, koffset, ksrc_dynamic_t }; - typedef std::vector cache_t; - - cache_t& cache() - { - static cache_t x; - return x; - } - - inline void* convert_type(void* const p, class_id src_t, class_id dst_t, bool polymorphic) - { - // Quickly rule out unregistered types - index_entry* src_p = seek_type(src_t); - if (src_p == 0) - return 0; - - index_entry* dst_p = seek_type(dst_t); - if (dst_p == 0) - return 0; - - // Look up the dynamic_id function and call it to get the dynamic - // info - boost::python::objects::dynamic_id_t dynamic_id = polymorphic - ? tuples::get(*src_p)(p) - : std::make_pair(p, src_t); - - // Look in the cache first for a quickie address translation - std::ptrdiff_t offset = (char*)p - (char*)dynamic_id.first; - - cache_element seek(make_tuple(src_t, dst_t, offset, dynamic_id.second)); - cache_t& c = cache(); - cache_t::iterator const cache_pos - = std::lower_bound(c.begin(), c.end(), seek); - - - // if found in the cache, we're done - if (cache_pos != c.end() && cache_pos->key == seek.key) - { - return cache_pos->offset == cache_element::not_found - ? 0 : (char*)p + cache_pos->offset; - } - - // If we are starting at the most-derived type, only look in the up graph - smart_graph const& g = polymorphic && dynamic_id.second != src_t - ? full_graph() : up_graph(); - - void* result = search( - g, p, tuples::get(*src_p) - , tuples::get(*dst_p)); - - // update the cache - c.insert(cache_pos, seek)->offset - = (result == 0) ? cache_element::not_found : (char*)result - (char*)p; - - return result; - } -} - -namespace python { namespace objects { - -BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src_t, class_id dst_t) -{ - return convert_type(p, src_t, dst_t, true); -} - -BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src_t, class_id dst_t) -{ - return convert_type(p, src_t, dst_t, false); -} - -BOOST_PYTHON_DECL void add_cast( - class_id src_t, class_id dst_t, cast_function cast, bool is_downcast) -{ - // adding an edge will invalidate any record of unreachability in - // the cache. - static std::size_t expected_cache_len = 0; - cache_t& c = cache(); - if (c.size() > expected_cache_len) - { - c.erase(std::remove_if( - c.begin(), c.end(), - mem_fn(&cache_element::unreachable)) - , c.end()); - - // If any new cache entries get added, we'll have to do this - // again when the next edge is added - expected_cache_len = c.size(); - } - - type_index_iterator_pair types = demand_types(src_t, dst_t); - vertex_t src = tuples::get(*types.first); - vertex_t dst = tuples::get(*types.second); - - cast_graph* const g[2] = { &up_graph().topology(), &full_graph().topology() }; - - for (cast_graph*const* p = g + (is_downcast ? 1 : 0); p < g + 2; ++p) - { - edge_t e; - bool added; - - tie(e, added) = add_edge(src, dst, **p); - assert(added); - - put(get(edge_cast, **p), e, cast); - put(get(edge_index, **p), e, num_edges(full_graph().topology()) - 1); - } -} - -BOOST_PYTHON_DECL void register_dynamic_id_aux( - class_id static_id, dynamic_id_function get_dynamic_id) -{ - tuples::get(*demand_type(static_id)) = get_dynamic_id; -} - -}}} // namespace boost::python::objects diff --git a/src/objects.cpp b/src/objects.cpp deleted file mode 100644 index b447b262..00000000 --- a/src/objects.cpp +++ /dev/null @@ -1,489 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// TODO: Move inline implementations from objects.cpp here - -#ifndef BOOST_PYTHON_SOURCE -r# define BOOST_PYTHON_SOURCE -#endif - -#include -#include - -namespace boost { namespace python { - -template -T object_from_python(PyObject* p, type) -{ - ref x(p, ref::increment_count); - if (!T::accepts(x)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw error_already_set(); - } - return T(x); -} - -inline PyObject* object_to_python(const object& x) -{ - return x.reference().release(); -} - -object::object(ref p) - : m_p(p) {} - -// Return a reference to the held object -ref object::reference() const -{ - return m_p; -} - -// Return a raw pointer to the held object -PyObject* object::get() const -{ - return m_p.get(); -} - -}} // namespace boost::python - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -tuple_base::tuple_base(std::size_t n) - : object(ref(PyTuple_New(n))) -{ - for (std::size_t i = 0; i < n; ++i) - PyTuple_SET_ITEM(get(), i, detail::none()); -} - -tuple_base::tuple_base(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw error_already_set(); - } -} - -PyTypeObject* tuple_base::type_obj() -{ - return &PyTuple_Type; -} - -bool tuple_base::accepts(ref p) -{ - return PyTuple_Check(p.get()); -} - -std::size_t tuple_base::size() const -{ - return PyTuple_Size(get()); -} - -ref tuple_base::operator[](std::size_t pos) const -{ - return ref(PyTuple_GetItem(get(), static_cast(pos)), - ref::increment_count); -} - -void tuple_base::set_item(std::size_t pos, const ref& rhs) -{ - int failed = PyTuple_SetItem( - get(), static_cast(pos), ref(rhs).release()); // A reference is stolen here. - (void)failed; - assert(failed == 0); -} - -tuple tuple_base::slice(int low, int high) const -{ - return tuple(ref(PyTuple_GetSlice(get(), low, high))); -} - -BOOST_PYTHON_DECL tuple& operator+=(tuple& self, const tuple& rhs) -{ - return self = self + rhs; -} - - -// Construct from an owned PyObject*. -// Precondition: p must point to a python string. -string::string(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw error_already_set(); - } -} - -string::string(const char* s) - : object(ref(PyString_FromString(s))) {} - -string::string(const char* s, std::size_t length) - : object(ref(PyString_FromStringAndSize(s, length))) {} - -string::string(const char* s, interned_t) - : object(ref(PyString_InternFromString(s))) {} - -#if 0 -string::string(const char* s, std::size_t length, interned_t) - : object(ref(PyString_InternFromStringAndSize(s, length))) {} -#endif - -string::string(const string& rhs) - : object(rhs.reference()) {} - -// Get the type object for Strings -PyTypeObject* string::type_obj() -{ return &PyString_Type; } - -// Return true if the given object is a python string -bool string::accepts(ref o) -{ return PyString_Check(o.get()); } - -// Return the length of the string. -std::size_t string::size() const -{ - int size = PyString_GET_SIZE(get()); - assert(size >= 0); - return static_cast(size); -} - -// Returns a null-terminated representation of the contents of string. -// The pointer refers to the internal buffer of string, not a copy. -// The data must not be modified in any way. It must not be de-allocated. -const char* string::c_str() const -{ return PyString_AS_STRING(get()); } - -void string::intern() -{ // UNTESTED!! - *this = string(ref(PyString_InternFromString(c_str()), ref::increment_count)); -} - -string& string::operator*=(unsigned int repeat_count) -{ - *this = string(ref(PySequence_Repeat(get(), repeat_count))); - return *this; -} - -dictionary_base::dictionary_base(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw error_already_set(); - } -} - -dictionary_base::dictionary_base() - : object(ref(PyDict_New())) {} - -PyTypeObject* dictionary_base::type_obj() -{ return &PyDict_Type; } - -bool dictionary_base::accepts(ref p) -{ return PyDict_Check(p.get()); } - -void dictionary_base::clear() -{ PyDict_Clear(get()); } - -const ref& dictionary_proxy::operator=(const ref& rhs) -{ - if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1) - throw error_already_set(); - return rhs; -} - -dictionary_proxy::operator ref() const -{ - return ref(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()), - ref::increment_count); -} - -dictionary_proxy::dictionary_proxy(const ref& dict, const ref& key) - : m_dict(dict), m_key(key) {} - -dictionary_proxy dictionary_base::operator[](ref key) -{ return proxy(reference(), key); } - -ref dictionary_base::operator[](ref key) const { - // An odd MSVC bug causes the ".operator Ptr()" to be needed - return proxy(reference(), key).operator ref(); -} - - -ref dictionary_base::get_item(const ref& key) const -{ - return get_item(key, ref()); -} - -ref dictionary_base::get_item(const ref& key, const ref& default_) const -{ - PyObject* value_or_null = PyDict_GetItem(get(), key.get()); - if (value_or_null == 0 && !PyErr_Occurred()) - return default_; - else - return ref(value_or_null, ref::increment_count); // Will throw if there was another error -} - -void dictionary_base::set_item(const ref& key, const ref& value) -{ - if (PyDict_SetItem(get(), key.get(), value.get()) == -1) - throw error_already_set(); -} - -void dictionary_base::erase(ref key) { - if (PyDict_DelItem(get(), key.get()) == -1) - throw error_already_set(); -} - -list dictionary_base::items() const { return list(ref(PyDict_Items(get()))); } -list dictionary_base::keys() const { return list(ref(PyDict_Keys(get()))); } -list dictionary_base::values() const { return list(ref(PyDict_Values(get()))); } - -std::size_t dictionary_base::size() const { return static_cast(PyDict_Size(get())); } - -string operator+(string x, string y) -{ - PyObject* io_string = x.reference().release(); - PyString_Concat(&io_string, y.get()); - return string(ref(io_string)); -} - -string& string::operator+=(const string& rhs) -{ - return *this = *this + rhs; -} - -string& string::operator+=(const char* y) -{ - return *this += string(y); -} - -string operator%(const string& format, const tuple& args) -{ - return string(ref(PyString_Format(format.get(), args.reference().get()))); -} - -string operator+(string x, const char* y) -{ - return x + string(y); -} - -string operator+(const char* x, string y) -{ - return string(x) + y; -} - -tuple operator+(const tuple& x, const tuple& y) -{ - tuple result(x.size() + y.size()); - for (std::size_t xi = 0; xi < x.size(); ++xi) - result.set_item(xi, x[xi]); - for (std::size_t yi = 0; yi < y.size(); ++yi) - result.set_item(yi + x.size(), y[yi]); - return result; -} - - -list_base::list_base(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw error_already_set(); - } -} - -list_base::list_base(std::size_t sz) - : object(ref(PyList_New(sz))) -{ -} - -PyTypeObject* list_base::type_obj() -{ - return &PyList_Type; -} - -bool list_base::accepts(ref p) -{ - return PyList_Check(p.get()); -} - -std::size_t list_base::size() const -{ - return PyList_Size(get()); -} - -ref list_base::operator[](std::size_t pos) const -{ - return ref(PyList_GetItem(get(), pos), ref::increment_count); -} - -list_proxy list_base::operator[](std::size_t pos) -{ - return proxy(reference(), pos); -} - -void list_base::insert(std::size_t index, const ref& item) -{ - if (PyList_Insert(get(), index, item.get()) == -1) - throw error_already_set(); -} - -void list_base::push_back(const ref& item) -{ - if (PyList_Append(get(), item.get()) == -1) - throw error_already_set(); -} - -void list_base::append(const ref& item) -{ - this->push_back(item); -} - -list list_base::slice(int low, int high) const -{ - return list(ref(PyList_GetSlice(get(), low, high))); -} - -list_slice_proxy list_base::slice(int low, int high) -{ - return list_slice_proxy(reference(), low, high); -} - -void list_base::sort() -{ - if (PyList_Sort(get()) == -1) - throw error_already_set(); -} - -void list_base::reverse() -{ - if (PyList_Reverse(get()) == -1) - throw error_already_set(); -} - -tuple list_base::as_tuple() const -{ - return tuple(ref(PyList_AsTuple(get()))); -} - -const ref& list_proxy::operator=(const ref& rhs) -{ - m_list.set_item(m_index, rhs); - return rhs; -} - -list_proxy::operator ref() const -{ - return ref(PyList_GetItem(m_list.get(), m_index), ref::increment_count); -} - -ref list_base::get_item(std::size_t pos) const -{ - return ref(PyList_GetItem(this->get(), pos), ref::increment_count); -} - -void list_base::set_item(std::size_t pos, const ref& rhs) -{ - int result = PyList_SetItem(this->get(), pos, rhs.get()); - if (result == -1) - throw error_already_set(); - Py_INCREF(rhs.get()); -} - -list_proxy::list_proxy(const ref& list, std::size_t index) - : m_list(list), m_index(index) -{ -} - -const list& list_slice_proxy::operator=(const list& rhs) -{ - if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1) - throw error_already_set(); - return rhs; -} - -list_slice_proxy::operator ref() const -{ - return ref(PyList_GetSlice(m_list.get(), m_low, m_high)); -} - -list_slice_proxy::operator list() const -{ - return list(this->operator ref()); -} - -std::size_t list_slice_proxy::size() const -{ - return this->operator list().size(); -} - -ref list_slice_proxy::operator[](std::size_t pos) const -{ - return this->operator list()[pos].operator ref(); -} - -list_slice_proxy::list_slice_proxy(const ref& list, int low, int high) - : m_list(list), m_low(low), m_high(high) -{ -} - -}} // namespace boost::python diff --git a/src/types.cpp b/src/types.cpp deleted file mode 100644 index e76503d2..00000000 --- a/src/types.cpp +++ /dev/null @@ -1,1273 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include // for handle_exception() -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace -{ - using detail::type_object_base; - using detail::call_object; - - - // Define a family of forwarding functions that can be called from a - // PyTypeObject's slots. These functions dispatch through a (virtual) member - // function pointer in the type_object_base, and handle exceptions in a - // uniform way, preventing us from having to rewrite the dispatching code over - // and over. - - // Given a function object f with signature - // - // PyObject* f(PyTypeObject*,PyObject*) - // - // calls f inside of handle_exception, and returns the result. If an exception - // is thrown by f, returns 0. - template - PyObject* obj_call(PyObject* obj, F f) - { - PyObject* result; - return call_object(result, obj, f) ? 0 : result; - } - - // Call the given integer-returning function object inside of - // handle_exception, returning a value_holder. F is a function - // object with "signature" - // - // R F(PyTypeObject*, PyObject*) - // - // where R is an integer type. - template - R int_call(PyObject* obj, F f, R* = 0) - { - R result; - return call_object(result, obj, f) ? -1 : result; - } - - // Implemented in terms of obj_call, above - PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*) const) - { - return obj_call(obj, bind(f, _1, _2)); - } - - // Implemented in terms of int_call, above - int call(PyObject* obj, int (type_object_base::*f)(PyObject*) const) - { - return int_call(obj, bind(f, _1, _2)); - } - - template - PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*, A1) const, A1 a1) - { - return obj_call(obj, bind(f, _1, _2, a1)); - } - - template - int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1) const, A1 a1) - { - return int_call(obj, bind(f, _1, _2, a1)); - } - - template - PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2) - { - return obj_call(obj, bind(f, _1, _2, a1, a2)); - } - - template - int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2) - { - return int_call(obj, bind(f, _1, _2, a1, a2)); - } - - template - int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1, A2, A3) const, A1 a1, A2 a2, A3 a3) - { - return int_call(obj, bind(f, _1, _2, a1, a2, a3)); - } - - int call_length_function(PyObject* obj, int (type_object_base::*f)(PyObject*) const) - { - int result; - if (call_object(result, obj, bind(f, _1, _2))) - return -1; - - if (result >= 0) - return result; - - PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); - return -1; - } -} // anonymous namespace - -extern "C" { - -// -// These functions actually go into the type object's slots, and dispatch to the -// "call" wrappers defined above. -// -static PyObject* do_instance_repr(PyObject* obj) -{ - return call(obj, &type_object_base::instance_repr); -} - -static PyObject* do_instance_richcompare(PyObject* obj, PyObject* other, int d) -{ -#if PYTHON_API_VERSION >= 1010 - switch(d) - { - case Py_LT: - return call(obj, &type_object_base::instance_lt, other); - case Py_LE: - return call(obj, &type_object_base::instance_le, other); - case Py_EQ: - return call(obj, &type_object_base::instance_eq, other); - case Py_NE: - return call(obj, &type_object_base::instance_ne, other); - case Py_GT: - return call(obj, &type_object_base::instance_gt, other); - case Py_GE: - return call(obj, &type_object_base::instance_ge, other); - } -#endif - return 0; -} - -static int do_instance_compare(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_compare, other); -} - -static PyObject* do_instance_str(PyObject* obj) -{ - return call(obj, &type_object_base::instance_str); -} - -static long do_instance_hash(PyObject* obj) -{ - return int_call(obj, bind(&type_object_base::instance_hash, _1, _2)); -} - -static PyObject* do_instance_call(PyObject* obj, PyObject* args, PyObject* keywords) -{ - return call(obj, &type_object_base::instance_call, args, keywords); -} - -static void do_instance_dealloc(PyObject* obj) -{ - if (handle_exception( - bind(&type_object_base::instance_dealloc - , static_cast(obj->ob_type) - , obj)) - ) - { - assert(!"exception during destruction!"); - } -} - -static PyObject* do_instance_getattr(PyObject* obj, char* name) -{ - const char* name_ = name; - return call(obj, &type_object_base::instance_getattr, name_); -} - -static int do_instance_setattr(PyObject* obj, char* name, PyObject* value) -{ - const char* name_ = name; - return call(obj, &type_object_base::instance_setattr, name_, value); -} - -static int do_instance_mp_length(PyObject* obj) -{ - return call_length_function(obj, &type_object_base::instance_mapping_length); -} - -static int do_instance_sq_length(PyObject* obj) -{ - return call_length_function(obj, &type_object_base::instance_sequence_length); -} - -static PyObject* do_instance_mp_subscript(PyObject* obj, PyObject* index) -{ - return call(obj, &type_object_base::instance_mapping_subscript, index); -} - -static PyObject* do_instance_sq_item(PyObject* obj, int index) -{ - // This is an extension to standard class behavior. If sequence_length - // is implemented and n >= sequence_length(), raise an IndexError. That - // keeps users from having to worry about raising it themselves - const PyTypeObject* const type = obj->ob_type; - if (type->tp_as_sequence != 0 && type->tp_as_sequence->sq_length != 0 - && index >= type->tp_as_sequence->sq_length(obj)) - { - PyErr_SetString(PyExc_IndexError, type->tp_name); - return 0; - } - - return obj_call( - obj - , bind(&type_object_base::instance_sequence_item, _1, _2, index)); -} - -static int do_instance_mp_ass_subscript(PyObject* obj, PyObject* index, PyObject* value) -{ - return call(obj, &type_object_base::instance_mapping_ass_subscript, index, value); -} - -static int do_instance_sq_ass_item(PyObject* obj, int index, PyObject* value) -{ - return call(obj, &type_object_base::instance_sequence_ass_item, index, value); -} - -static PyObject* do_instance_sq_concat(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_sequence_concat, other); -} - -static PyObject* do_instance_sq_repeat(PyObject* obj, int n) -{ - return call(obj, &type_object_base::instance_sequence_repeat, n); -} - -static PyObject* do_instance_sq_slice( - PyObject* obj, int start, int finish) -{ - return call(obj, &type_object_base::instance_sequence_slice, start, finish); -} - -static int do_instance_sq_ass_slice( - PyObject* obj, int start, int finish, PyObject* value) -{ - return call(obj, &type_object_base::instance_sequence_ass_slice, start, finish, value); -} - -static PyObject* do_instance_nb_add(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_add, other); -} - -static PyObject* do_instance_nb_subtract(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_subtract, other); -} - -static PyObject* do_instance_nb_multiply(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_multiply, other); -} - -static PyObject* do_instance_nb_divide(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_divide, other); -} - -static PyObject* do_instance_nb_remainder(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_remainder, other); -} - -static PyObject* do_instance_nb_divmod(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_divmod, other); -} - -static PyObject* do_instance_nb_power(PyObject* obj, PyObject* exponent, PyObject* modulus) -{ - return call(obj, &type_object_base::instance_number_power, exponent, modulus); -} - -static PyObject* do_instance_nb_negative(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_negative); -} - -static PyObject* do_instance_nb_positive(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_positive); -} - -static PyObject* do_instance_nb_absolute(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_absolute); -} - -static int do_instance_nb_nonzero(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_nonzero); -} - -static PyObject* do_instance_nb_invert(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_invert); -} - - -static PyObject* do_instance_nb_lshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_lshift, other); -} - -static PyObject* do_instance_nb_rshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_rshift, other); -} - -static PyObject* do_instance_nb_and(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_and, other); -} - -static PyObject* do_instance_nb_xor(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_xor, other); -} - -static PyObject* do_instance_nb_or(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_or, other); -} - -static int do_instance_nb_coerce(PyObject**obj, PyObject**other) -{ - // no call() overload for this oddball function, so we'll do it manually - return int_call( - *obj, bind( - &type_object_base::instance_number_coerce, _1, _2, obj, other)); -} -static PyObject* do_instance_nb_int(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_int); -} - -static PyObject* do_instance_nb_long(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_long); -} - -static PyObject* do_instance_nb_float(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_float); -} - -static PyObject* do_instance_nb_oct(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_oct); -} - -static PyObject* do_instance_nb_hex(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_hex); -} - -static PyObject* do_instance_nb_inplace_add(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_add, other); -} - -static PyObject* do_instance_nb_inplace_subtract(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_subtract, other); -} - -static PyObject* do_instance_nb_inplace_multiply(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_multiply, other); -} - -static PyObject* do_instance_nb_inplace_divide(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_divide, other); -} - -static PyObject* do_instance_nb_inplace_remainder(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_remainder, other); -} - -static PyObject* do_instance_nb_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) -{ - return call(obj, &type_object_base::instance_number_inplace_power, exponent, modulus); -} - -static PyObject* do_instance_nb_inplace_lshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_lshift, other); -} - -static PyObject* do_instance_nb_inplace_rshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_rshift, other); -} - -static PyObject* do_instance_nb_inplace_and(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_and, other); -} - -static PyObject* do_instance_nb_inplace_or(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_or, other); -} - -static PyObject* do_instance_nb_inplace_xor(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_xor, other); -} - -} // extern "C" - -namespace -{ - -#define ENABLE_GENERAL_CAPABILITY(field) \ - case type_object_base::field: \ - dest->tp_##field = &do_instance_##field; \ - return true - -bool add_capability_general(type_object_base::capability capability, PyTypeObject* dest) -{ - assert(dest != 0); - - switch(capability) - { - ENABLE_GENERAL_CAPABILITY(hash); - ENABLE_GENERAL_CAPABILITY(call); - ENABLE_GENERAL_CAPABILITY(str); - ENABLE_GENERAL_CAPABILITY(getattr); - ENABLE_GENERAL_CAPABILITY(setattr); - ENABLE_GENERAL_CAPABILITY(compare); - ENABLE_GENERAL_CAPABILITY(repr); - default: - return false; - } -} - - -template -void create_method_table_if_null(T*& table) -{ - if(table == 0) - { - detail::shared_pod_manager::create(table); - } - else - { - detail::shared_pod_manager::make_unique_copy(table); - } -} - -bool add_capability_richcompare(type_object_base::capability capability, PyTypeObject* dest) -{ - assert(dest != 0); - if (capability == type_object_base::richcompare) { -#if PYTHON_API_VERSION >= 1010 - dest->tp_richcompare = &do_instance_richcompare; - dest->tp_flags |= Py_TPFLAGS_HAVE_RICHCOMPARE; -#endif - return true; - } - - return false; -} - -#define ENABLE_INPLACE_CAPABILITY(field) \ - case type_object_base::number_##field: \ - create_method_table_if_null(dest->tp_as_number); \ - dest->tp_as_number->nb_##field = &do_instance_nb_##field; \ - detail::shared_pod_manager::replace_if_equal(dest->tp_as_number); \ - dest->tp_flags |= Py_TPFLAGS_HAVE_INPLACEOPS; \ - return true - -bool add_capability_inplace(type_object_base::capability capability, PyTypeObject* dest) -{ - assert(dest != 0); - switch (capability) - { -#if PYTHON_API_VERSION >= 1010 - ENABLE_INPLACE_CAPABILITY (inplace_add); - ENABLE_INPLACE_CAPABILITY (inplace_subtract); - ENABLE_INPLACE_CAPABILITY (inplace_multiply); - ENABLE_INPLACE_CAPABILITY (inplace_divide); - ENABLE_INPLACE_CAPABILITY (inplace_remainder); - ENABLE_INPLACE_CAPABILITY (inplace_power); - ENABLE_INPLACE_CAPABILITY (inplace_lshift); - ENABLE_INPLACE_CAPABILITY (inplace_rshift); - ENABLE_INPLACE_CAPABILITY (inplace_and); - ENABLE_INPLACE_CAPABILITY (inplace_or); - ENABLE_INPLACE_CAPABILITY (inplace_xor); -#endif - default: - return false; - } -} - -#define ENABLE_MAPPING_CAPABILITY(field) \ - case type_object_base::mapping_##field: \ - create_method_table_if_null(dest); \ - dest->mp_##field = &do_instance_mp_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_mapping(type_object_base::capability capability, PyMappingMethods*& dest) -{ - switch(capability) - { - ENABLE_MAPPING_CAPABILITY(length); - ENABLE_MAPPING_CAPABILITY(subscript); - ENABLE_MAPPING_CAPABILITY(ass_subscript); - default: - return false; - } -} - -#define ENABLE_SEQUENCE_CAPABILITY(field) \ - case type_object_base::sequence_##field: \ - create_method_table_if_null(dest); \ - dest->sq_##field = &do_instance_sq_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_sequence(type_object_base::capability capability, PySequenceMethods*& dest) -{ - switch(capability) - { - ENABLE_SEQUENCE_CAPABILITY(length); - ENABLE_SEQUENCE_CAPABILITY(item); - ENABLE_SEQUENCE_CAPABILITY(ass_item); - ENABLE_SEQUENCE_CAPABILITY(concat); - ENABLE_SEQUENCE_CAPABILITY(repeat); - ENABLE_SEQUENCE_CAPABILITY(slice); - ENABLE_SEQUENCE_CAPABILITY(ass_slice); - default: - return false; - } -} - -#define ENABLE_NUMBER_CAPABILITY(field) \ - case type_object_base::number_##field: \ - create_method_table_if_null(dest); \ - dest->nb_##field = &do_instance_nb_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_number(type_object_base::capability capability, PyNumberMethods*& dest) -{ - switch(capability) - { - ENABLE_NUMBER_CAPABILITY(add); - ENABLE_NUMBER_CAPABILITY(subtract); - ENABLE_NUMBER_CAPABILITY(multiply); - ENABLE_NUMBER_CAPABILITY(divide); - ENABLE_NUMBER_CAPABILITY(remainder); - ENABLE_NUMBER_CAPABILITY(divmod); - ENABLE_NUMBER_CAPABILITY(power); - ENABLE_NUMBER_CAPABILITY(negative); - ENABLE_NUMBER_CAPABILITY(positive); - ENABLE_NUMBER_CAPABILITY(absolute); - ENABLE_NUMBER_CAPABILITY(nonzero); - ENABLE_NUMBER_CAPABILITY(invert); - ENABLE_NUMBER_CAPABILITY(lshift); - ENABLE_NUMBER_CAPABILITY(rshift); - ENABLE_NUMBER_CAPABILITY(and); - ENABLE_NUMBER_CAPABILITY(xor); - ENABLE_NUMBER_CAPABILITY(or); - ENABLE_NUMBER_CAPABILITY(coerce); - ENABLE_NUMBER_CAPABILITY(int); - ENABLE_NUMBER_CAPABILITY(long); - ENABLE_NUMBER_CAPABILITY(float); - ENABLE_NUMBER_CAPABILITY(oct); - ENABLE_NUMBER_CAPABILITY(hex); - default: - return false; - } -} - -#define ENABLE_BUFFER_CAPABILITY(field) \ - case type_object_base::buffer_##field: \ - create_method_table_if_null(dest); \ - dest->bf_##field = &do_instance_bf_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_buffer(type_object_base::capability capability, PyBufferProcs*& dest) -{ - (void)dest; // suppress unused argument warning - (void)capability; // likwise -#if 0 - switch(capability) - { - // nothing defined yet - default: - return false; - } -#endif - return false; -} - -} // anonymous namespace - -namespace detail { - - void add_capability( - type_object_base::capability capability, - PyTypeObject* dest_) - { - if(add_capability_general(capability, dest_)) - return; - if(add_capability_richcompare(capability, dest_)) - return; - if(add_capability_inplace(capability, dest_)) - return; - if(add_capability_mapping(capability, dest_->tp_as_mapping)) - return; - if(add_capability_sequence(capability, dest_->tp_as_sequence)) - return; - if(add_capability_number(capability, dest_->tp_as_number)) - return; - if(add_capability_buffer(capability, dest_->tp_as_buffer)) - return; - - // no one recognized the capability - throw std::runtime_error("py::detail::add_capability(): unknown capability"); - } -} // namespace detail - -type_object_base::~type_object_base() -{ - detail::shared_pod_manager::dispose(tp_as_mapping); - detail::shared_pod_manager::dispose(tp_as_sequence); - detail::shared_pod_manager::dispose(tp_as_number); - detail::shared_pod_manager::dispose(tp_as_buffer); -} - -void type_object_base::enable(type_object_base::capability capability) -{ - detail::add_capability(capability, this); -} - -type_object_base::type_object_base(PyTypeObject* t) - : python_type(t) -{ - this->tp_dealloc = do_instance_dealloc; -} - -namespace -{ - typedef long pod_refcount; - - inline pod_refcount pod_refcount_offset(std::size_t size) - { - const std::size_t alignment = boost::alignment_of::value; - return (size + alignment - 1) / alignment * alignment; - } - - inline pod_refcount* counted_pod_refcount(char* pod, std::size_t size) - { - if(pod == 0) - return 0; - - return reinterpret_cast(pod + pod_refcount_offset(size)); - } - - #ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - int pod_instance_counter = 0; - #endif - - inline pod_refcount counted_pod_getref(char* pod, std::size_t size) - { - pod_refcount* ref_count = counted_pod_refcount(pod, size); - return ref_count == 0 ? -1 : *ref_count; - } - - inline pod_refcount counted_pod_decref(char* pod, std::size_t size) - { - pod_refcount* const ref_count = counted_pod_refcount(pod, size); - if (ref_count == 0) - return -1; - --(*ref_count); - if (*ref_count <= 0) - { - #ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - --pod_instance_counter; - #endif - ::operator delete(pod); - return 0; - } - return *ref_count; - } - - pod_refcount counted_pod_incref(char* pod, std::size_t size) - { - pod_refcount* ref_count = counted_pod_refcount(pod, size); - return ref_count == 0 ? -1 : ++(*ref_count); - } - -} // anonymous namespace - -namespace detail -{ - struct shared_pod_manager::compare - { - bool operator()(const std::pair& x1, - const std::pair& x2) const - { - const std::size_t n1 = x1.second; - const std::size_t n2 = x2.second; - return n1 < n2 || n1 == n2 && BOOST_CSTD_::memcmp(x1.first, x2.first, n1) < 0; - } - }; - - struct shared_pod_manager::identical - { - identical(char* p) : pod(p) {} - - bool operator()(const std::pair& x) const - { - return pod == x.first; - } - - char* pod; - }; - - shared_pod_manager& shared_pod_manager::obj() - { - static shared_pod_manager spm; - return spm; - } - - shared_pod_manager::~shared_pod_manager() - { - } - - void* shared_pod_manager::replace_if_equal(void* pod, std::size_t size) - { - if(pod == 0) - return 0; - - const holder element(static_cast(pod), size); - - const storage::iterator found - = std::lower_bound(m_storage.begin(), m_storage.end(), element, compare()); - - if (found != m_storage.end() && pod == found->first) - { - // pod already in list => do nothing - return pod; - } - else if (found != m_storage.end() && !compare()(element, *found)) - { - // equal element in list => replace - void* replacement = found->first; - counted_pod_incref(found->first, size); - dec_ref(element.first, size); // invalidates iterator 'found' - return replacement; - } - else - { - // new element => insert - m_storage.insert(found, element); - return pod; - } - } - - void* shared_pod_manager::make_unique_copy(void* pod, std::size_t size) - { - if(pod == 0) - return 0; - if(counted_pod_getref(static_cast(pod), size) == 1) - { - erase_from_list(pod); - return pod; - } - else - { - void* copy = create(size); - memmove(copy, pod, size); - dec_ref(pod, size); - return copy; - } - } - - void* shared_pod_manager::create(std::size_t size) - { - std::size_t total_size = pod_refcount_offset(size) + sizeof(pod_refcount); - char* pod = static_cast(::operator new(total_size)); - #ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - ++pod_instance_counter; - #endif - memset(pod, 0, total_size); - - *counted_pod_refcount(pod, size) = 1; - - return pod; - } - - void shared_pod_manager::dec_ref(void* pod, std::size_t size) - { - if(pod == 0) - return; - - int ref_count = counted_pod_decref(static_cast(pod), size); - - if(ref_count <= 0) - erase_from_list(pod); - } - - void shared_pod_manager::erase_from_list(void* pod) - { - if(pod == 0) - return; - - const storage::iterator found = - std::find_if(m_storage.begin(), m_storage.end(), - identical(static_cast(pod))); - - if(found != m_storage.end()) - { - m_storage.erase(found); - } - } -} // namespace detail - -namespace { - struct error_type { - operator PyObject*() const { return 0; } - operator int() const { return -1; } - }; - - error_type unimplemented(const char* name) - { - assert(!"Control should never reach here"); - string s("Unimplemented "); - s += string(name); - PyErr_SetObject(PyExc_RuntimeError, s.get()); - return error_type(); - } -} - -PyObject* type_object_base::instance_repr(PyObject*) const -{ - return unimplemented("instance_repr"); -} - -int type_object_base::instance_compare(PyObject*, PyObject*) const -{ - return unimplemented("instance_compare"); -} - -PyObject* type_object_base::instance_str(PyObject*) const -{ - return unimplemented("instance_str"); -} - -long type_object_base::instance_hash(PyObject* /* obj */) const -{ - return unimplemented("instance_hash"); -} - -PyObject* type_object_base::instance_call(PyObject* /*obj*/, PyObject* /*args*/, PyObject* /*kw*/) const -{ - return unimplemented("instance_call"); -} - -PyObject* type_object_base::instance_getattr(PyObject* /*obj*/, const char* /*name*/) const -{ - return unimplemented("instance_getattr"); -} - -int type_object_base::instance_setattr(PyObject* /*obj*/, const char* /*name*/, PyObject* /*value*/) const -{ - return unimplemented("instance_setattr"); -} - -int type_object_base::instance_mapping_length(PyObject*) const -{ - return unimplemented("instance_mapping_length"); -} - -int type_object_base::instance_sequence_length(PyObject*) const -{ - return unimplemented("instance_sequence_length"); -} - -PyObject* type_object_base::instance_mapping_subscript(PyObject*, PyObject*) const -{ - return unimplemented("instance_mapping_subscript"); -} - -PyObject* type_object_base::instance_sequence_item(PyObject*, int) const -{ - return unimplemented("instance_sequence_item"); -} - -int type_object_base::instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const -{ - return unimplemented("instance_mapping_ass_subscript"); -} - -int type_object_base::instance_sequence_ass_item(PyObject*, int, PyObject*) const -{ - return unimplemented("instance_sequence_ass_item"); -} - -PyObject* type_object_base::instance_sequence_concat(PyObject*, PyObject*) const -{ - return unimplemented("instance_sequence_concat"); -} - -PyObject* type_object_base::instance_sequence_repeat(PyObject*, int) const -{ - return unimplemented("instance_sequence_repeat"); -} - -PyObject* type_object_base::instance_sequence_slice(PyObject*, int, int) const -{ - return unimplemented("instance_sequence_slice"); -} - -int type_object_base::instance_sequence_ass_slice(PyObject*, int, int, PyObject*) const -{ - return unimplemented("instance_sequence_ass_slice"); -} - -PyObject* type_object_base::instance_number_add(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_add"); -} - -PyObject* type_object_base::instance_number_subtract(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_subtract"); -} - -PyObject* type_object_base::instance_number_multiply(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_multiply"); -} - -PyObject* type_object_base::instance_number_divide(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_divide"); -} - -PyObject* type_object_base::instance_number_remainder(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_remainder"); -} - -PyObject* type_object_base::instance_number_divmod(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_divmod"); -} - -PyObject* type_object_base::instance_number_power(PyObject*, PyObject*, PyObject*) const -{ - return unimplemented("instance_number_power"); -} - -PyObject* type_object_base::instance_number_negative(PyObject*) const -{ - return unimplemented("instance_number_negative"); -} - -PyObject* type_object_base::instance_number_positive(PyObject*) const -{ - return unimplemented("instance_number_positive"); -} - -PyObject* type_object_base::instance_number_absolute(PyObject*) const -{ - return unimplemented("instance_number_absolute"); -} - -int type_object_base::instance_number_nonzero(PyObject*) const -{ - return unimplemented("instance_number_nonzero"); -} - -PyObject* type_object_base::instance_number_invert(PyObject*) const -{ - return unimplemented("instance_number_invert"); -} - -PyObject* type_object_base::instance_number_lshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_lshift"); -} - -PyObject* type_object_base::instance_number_rshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_rshift"); -} - -PyObject* type_object_base::instance_number_and(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_and"); -} - -PyObject* type_object_base::instance_number_xor(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_xor"); -} - -PyObject* type_object_base::instance_number_or(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_or"); -} - -int type_object_base::instance_number_coerce(PyObject*, PyObject**, PyObject**) const -{ - return unimplemented("instance_number_coerce"); -} - -PyObject* type_object_base::instance_number_int(PyObject*) const -{ - return unimplemented("instance_number_int"); -} - -PyObject* type_object_base::instance_number_long(PyObject*) const -{ - return unimplemented("instance_number_long"); -} - -PyObject* type_object_base::instance_number_float(PyObject*) const -{ - return unimplemented("instance_number_float"); -} - -PyObject* type_object_base::instance_number_oct(PyObject*) const -{ - return unimplemented("instance_number_oct"); -} - -PyObject* type_object_base::instance_number_hex(PyObject*) const -{ - return unimplemented("instance_number_hex"); -} - -PyObject* type_object_base::instance_number_inplace_add(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_add"); -} - -PyObject* type_object_base::instance_number_inplace_subtract(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_subtract"); -} - -PyObject* type_object_base::instance_number_inplace_multiply(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_multiply"); -} - -PyObject* type_object_base::instance_number_inplace_divide(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_divide"); -} - -PyObject* type_object_base::instance_number_inplace_remainder(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_remainder"); -} - -PyObject* type_object_base::instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_power"); -} - -PyObject* type_object_base::instance_number_inplace_lshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_lshift"); -} - -PyObject* type_object_base::instance_number_inplace_rshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_rshift"); -} - -PyObject* type_object_base::instance_number_inplace_and(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_and"); -} - -PyObject* type_object_base::instance_number_inplace_or(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_or"); -} - -PyObject* type_object_base::instance_number_inplace_xor(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_xor"); -} - -PyObject* type_object_base::instance_lt(PyObject*, PyObject*) const -{ - return unimplemented("instance_lt"); -} - -PyObject* type_object_base::instance_le(PyObject*, PyObject*) const -{ - return unimplemented("instance_le"); -} - -PyObject* type_object_base::instance_eq(PyObject*, PyObject*) const -{ - return unimplemented("instance_eq"); -} - -PyObject* type_object_base::instance_ne(PyObject*, PyObject*) const -{ - return unimplemented("instance_ne"); -} - -PyObject* type_object_base::instance_gt(PyObject*, PyObject*) const -{ - return unimplemented("instance_gt"); -} - -PyObject* type_object_base::instance_ge(PyObject*, PyObject*) const -{ - return unimplemented("instance_ge"); -} - -}} // namespace boost::python - -#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - -struct TestTypeObject : boost::python::type_object_base -{ - TestTypeObject() - : boost::python::type_object_base(Py_None->ob_type->ob_type) - {} - - void instance_dealloc(PyObject*) const {} -}; - -struct POD1 -{ - unsigned char data; -}; - -int main() -{ - boost::python::type_object_base *o1, *o2, *o3; - -// POD1 * pod1; -// boost::python::detail::shared_pod_manager::create(pod1); - - o1 = new TestTypeObject; - o2 = new TestTypeObject; - o3 = new TestTypeObject; - - assert(boost::python::pod_instance_counter == 0); - - o1->enable(boost::python::type_object_base::number_add); - o1->enable(boost::python::type_object_base::compare); - - o2->enable(boost::python::type_object_base::number_add); - o2->enable(boost::python::type_object_base::mapping_length); - - o3->enable(boost::python::type_object_base::number_add); - o3->enable(boost::python::type_object_base::sequence_length); - - assert(boost::python::pod_instance_counter == 3); - assert(o1->tp_as_number && !o1->tp_as_mapping && !o1->tp_as_sequence); - assert(o2->tp_as_number && o2->tp_as_mapping && !o2->tp_as_sequence); - assert(o3->tp_as_number && !o3->tp_as_mapping && o3->tp_as_sequence); - assert(o1->tp_as_number == o2->tp_as_number); - assert(o1->tp_as_number == o3->tp_as_number); - assert((void*)o2->tp_as_number != o2->tp_as_mapping); - assert((void*)o2->tp_as_mapping != o3->tp_as_sequence); - - o1->enable(boost::python::type_object_base::number_subtract); - - assert(boost::python::pod_instance_counter == 4); - assert(o1->tp_as_number != o2->tp_as_number); - assert(o2->tp_as_number == o3->tp_as_number); - - o3->enable(boost::python::type_object_base::mapping_subscript); - - assert(boost::python::pod_instance_counter == 5); - assert(o3->tp_as_number && o3->tp_as_mapping && o3->tp_as_sequence); - assert(o2->tp_as_mapping != o3->tp_as_mapping); - - o2->enable(boost::python::type_object_base::mapping_subscript); - o3->enable(boost::python::type_object_base::mapping_length); - - assert(boost::python::pod_instance_counter == 4); - assert(o2->tp_as_number && o2->tp_as_mapping && !o2->tp_as_sequence); - assert(o3->tp_as_number && o3->tp_as_mapping && o3->tp_as_sequence); - assert(o2->tp_as_mapping == o3->tp_as_mapping); - - boost::python::type_object_base *o4 = new TestTypeObject; - - assert(boost::python::pod_instance_counter == 4); - - o4->enable(boost::python::type_object_base::number_add); - - assert(boost::python::pod_instance_counter == 4); - assert(o4->tp_as_number && !o4->tp_as_mapping && !o4->tp_as_sequence); - assert(o4->tp_as_number == o3->tp_as_number); - - delete o3; - - assert(boost::python::pod_instance_counter == 3); - assert(o1->tp_as_number && !o1->tp_as_mapping && !o1->tp_as_sequence); - assert(o2->tp_as_number && o2->tp_as_mapping && !o2->tp_as_sequence); - assert(o4->tp_as_number && !o4->tp_as_mapping && !o4->tp_as_sequence); - assert(o4->tp_as_number == o2->tp_as_number); - - o3 = new TestTypeObject; - - assert(boost::python::pod_instance_counter == 3); - - o3->enable(boost::python::type_object_base::number_add); - o3->enable(boost::python::type_object_base::sequence_length); - - assert(boost::python::pod_instance_counter == 4); - assert(o3->tp_as_number && !o3->tp_as_mapping && o3->tp_as_sequence); - assert(o1->tp_as_number != o3->tp_as_number); - assert(o2->tp_as_number == o3->tp_as_number); - - delete o1; - - assert(boost::python::pod_instance_counter == 3); - - delete o4; - - assert(boost::python::pod_instance_counter == 3); - - delete o3; - - assert(boost::python::pod_instance_counter == 2); - - delete o2; - - assert(boost::python::pod_instance_counter == 0); - - assert(boost::python::detail::shared_pod_manager::obj().m_storage.size() == 0); -} - -#endif diff --git a/test/complicated.hpp b/test/complicated.hpp deleted file mode 100644 index 123c53fe..00000000 --- a/test/complicated.hpp +++ /dev/null @@ -1,39 +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 COMPLICATED_DWA20011215_HPP -# define COMPLICATED_DWA20011215_HPP -# include - -# include "simple_type.hpp" - -struct complicated -{ - complicated(simple const&, int = 0); - ~complicated(); - - int get_n() const; - - char* s; - int n; -}; - -inline complicated::complicated(simple const&s, int n) - : s(s.s), n(n) -{ - std::cout << "constructing complicated: " << this->s << ", " << n << std::endl; -} - -inline complicated::~complicated() -{ - std::cout << "destroying complicated: " << this->s << ", " << n << std::endl; -} - -inline int complicated::get_n() const -{ - return n; -} - -#endif // COMPLICATED_DWA20011215_HPP diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp deleted file mode 100644 index 6c7cc4d3..00000000 --- a/test/comprehensive.cpp +++ /dev/null @@ -1,1260 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// Revision History: -// 04 Mar 01 Changed name of extension module so it would work with DebugPython, -// eliminated useless test that aggravated MSVC (David Abrahams) -#include "comprehensive.hpp" -#include -#include // used for portability on broken compilers -#include // for pow() -#include - -#if defined(__sgi) \ - && ( (defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) \ - && !defined(__GNUC__)) -inline double pow(int x, int y) { return pow(static_cast(x), y); } -#endif - -namespace bpl_test { - -FooCallback::FooCallback(PyObject* self, int x) - : Foo(x), m_self(self) -{ -} - -int FooCallback::add_len(const char* x) const -{ - // Try to call the "add_len" method on the corresponding Python object. - return boost::python::callback::call_method(m_self, "add_len", x); -} - -// A function which Python can call in case bar is not overridden from -// Python. In true Python style, we use a free function taking an initial self -// parameter. This function anywhere needn't be a static member of the callback -// class. The only reason to do it this way is that Foo::add_len is private, and -// FooCallback is already a friend of Foo. -int FooCallback::default_add_len(const Foo* self, const char* x) -{ - // Don't forget the Foo:: qualification, or you'll get an infinite - // recursion! - return self->Foo::add_len(x); -} - -// Since Foo::pure() is pure virtual, we don't need a corresponding -// default_pure(). A failure to override it in Python will result in an -// exception at runtime when pure() is called. -std::string FooCallback::pure() const -{ - return boost::python::callback::call_method(m_self, "pure"); -} - -Foo::PythonClass::PythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "Foo") -{ - def(boost::python::constructor()); - def(&Foo::mumble, "mumble"); - def(&Foo::set, "set"); - def(&Foo::call_pure, "call_pure"); - def(&Foo::call_add_len, "call_add_len"); - - // This is the way we add a virtual function that has a default implementation. - def(&Foo::add_len, "add_len", &FooCallback::default_add_len); - - // Since pure() is pure virtual, we are leaving it undefined. - - // And the nested classes. - boost::python::class_builder foo_a(*this, "Foo_A"); - foo_a.def(boost::python::constructor<>()); - foo_a.def(&Foo::Foo_A::mumble, "mumble"); - - boost::python::class_builder foo_b(get_extension_class(), - "Foo_B"); - foo_b.def(boost::python::constructor<>()); - foo_b.def(&Foo::Foo_B::mumble, "mumble"); -} - -BarPythonClass::BarPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "Bar") -{ - def(boost::python::constructor()); - def(&Bar::first, "first"); - def(&Bar::second, "second"); - def(&Bar::pass_baz, "pass_baz"); -} - -BazPythonClass::BazPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "Baz") // optional -{ - def(boost::python::constructor<>()); - def(&Baz::pass_bar, "pass_bar"); - def(&Baz::clone, "clone"); - def(&Baz::create_foo, "create_foo"); - def(&Baz::get_foo_value, "get_foo_value"); - def(&Baz::eat_baz, "eat_baz"); -} - -StringMapPythonClass::StringMapPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "StringMap") -{ - def(boost::python::constructor<>()); - def(&StringMap::size, "__len__"); - def(&get_item, "__getitem__"); - def(&set_item, "__setitem__"); - def(&del_item, "__delitem__"); -} - -int get_first(const IntPair& p) -{ - return p.first; -} - -void set_first(IntPair& p, int value) -{ - p.first = -value; -} - -void del_first(const IntPair&) -{ - PyErr_SetString(PyExc_AttributeError, "first can't be deleted!"); - throw boost::python::error_already_set(); -} - -IntPairPythonClass::IntPairPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "IntPair") -{ - def(boost::python::constructor()); - def(&getattr, "__getattr__"); - def(&setattr, "__setattr__"); - def(&delattr, "__delattr__"); - def(&get_first, "__getattr__first__"); - def(&set_first, "__setattr__first__"); - def(&del_first, "__delattr__first__"); -} - -void IntPairPythonClass::setattr(IntPair& x, const std::string& name, int value) -{ - if (name == "second") - { - x.second = value; - } - else - { - PyErr_SetString(PyExc_AttributeError, name.c_str()); - throw boost::python::error_already_set(); - } -} - -void IntPairPythonClass::delattr(IntPair&, const char*) -{ - PyErr_SetString(PyExc_AttributeError, "Attributes can't be deleted!"); - throw boost::python::error_already_set(); -} - -int IntPairPythonClass::getattr(const IntPair& p, const std::string& s) -{ - if (s == "second") - { - return p.second; - } - else - { - PyErr_SetString(PyExc_AttributeError, s.c_str()); - throw boost::python::error_already_set(); - } -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return 0; -#endif -} - -namespace { namespace file_local { -void throw_key_error_if_end(const StringMap& m, StringMap::const_iterator p, std::size_t key) -{ - if (p == m.end()) - { - PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(key)); - throw boost::python::error_already_set(); - } -} -}} // namespace ::file_local - -const std::string& StringMapPythonClass::get_item(const StringMap& m, std::size_t key) -{ - const StringMap::const_iterator p = m.find(key); - file_local::throw_key_error_if_end(m, p, key); - return p->second; -} - -void StringMapPythonClass::set_item(StringMap& m, std::size_t key, const std::string& value) -{ - m[key] = value; -} - -void StringMapPythonClass::del_item(StringMap& m, std::size_t key) -{ - const StringMap::iterator p = m.find(key); - file_local::throw_key_error_if_end(m, p, key); - m.erase(p); -} - -// -// Show that polymorphism can work. a DerivedFromFoo object will be passed to -// Python in a smart pointer object. -// -class DerivedFromFoo : public Foo -{ -public: - DerivedFromFoo(int x) : Foo(x) {} - -private: - std::string pure() const - { return "this was never pure!"; } - - int add_len(const char*) const - { return 1000; } -}; - -// -// function implementations -// - -IntPair make_pair(int x, int y) -{ - return std::make_pair(x, y); -} - -const char* Foo::mumble() -{ - return "mumble"; -} - -const char* Foo::Foo_A::mumble() -{ - return "mumble a"; -} - -const char* Foo::Foo_B::mumble() -{ - return "mumble b"; -} - -void Foo::set(long x) -{ - m_x = x; -} - -std::string Foo::call_pure() -{ - return this->pure(); -} - -int Foo::call_add_len(const char* s) const -{ - return this->add_len(s); -} - -int Foo::add_len(const char* s) const // sum the held value and the length of s -{ - return BOOST_CSTD_::strlen(s) + static_cast(m_x); -} - -boost::shared_ptr Baz::create_foo() -{ - return boost::shared_ptr(new DerivedFromFoo(0)); -} - -// Used to check conversion to None -boost::shared_ptr foo_factory(bool create) -{ - return boost::shared_ptr(create ? new DerivedFromFoo(0) : 0); -} - -// Used to check conversion from None -bool foo_ptr_is_null(Foo* p) -{ - return p == 0; -} - -bool foo_shared_ptr_is_null(boost::shared_ptr p) -{ - return p.get() == 0; -} - -// We can accept smart pointer parameters -int Baz::get_foo_value(boost::shared_ptr foo) -{ - return foo->call_add_len(""); -} - -// Show what happens in python when we take ownership from an auto_ptr -void Baz::eat_baz(std::auto_ptr baz) -{ - baz->clone(); // just do something to show that it is valid. -} - -Baz Bar::pass_baz(Baz b) -{ - return b; -} - -std::string stringpair_repr(const StringPair& sp) -{ - return "('" + sp.first + "', '" + sp.second + "')"; -} - -int stringpair_compare(const StringPair& sp1, const StringPair& sp2) -{ - return sp1 < sp2 ? -1 : sp2 < sp1 ? 1 : 0; -} - -boost::python::string range_str(const Range& r) -{ - char buf[200]; - sprintf(buf, "(%d, %d)", r.m_start, r.m_finish); - return boost::python::string(buf); -} - -int range_compare(const Range& r1, const Range& r2) -{ - int d = r1.m_start - r2.m_start; - if (d == 0) - d = r1.m_finish - r2.m_finish; - return d; -} - -long range_hash(const Range& r) -{ - return r.m_start * 123 + r.m_finish; -} - -/************************************************************/ -/* */ -/* some functions to test overloading */ -/* */ -/************************************************************/ - -static std::string testVoid() -{ - return std::string("Hello world!"); -} - -static int testInt(int i) -{ - return i; -} - -static std::string testString(std::string i) -{ - return i; -} - -static int test2(int i1, int i2) -{ - return i1+i2; -} - -static int test3(int i1, int i2, int i3) -{ - return i1+i2+i3; -} - -static int test4(int i1, int i2, int i3, int i4) -{ - return i1+i2+i3+i4; -} - -static int test5(int i1, int i2, int i3, int i4, int i5) -{ - return i1+i2+i3+i4+i5; -} - -/************************************************************/ -/* */ -/* a class to test overloading */ -/* */ -/************************************************************/ - -struct OverloadTest -{ - OverloadTest(): x_(1000) {} - OverloadTest(int x): x_(x) {} - OverloadTest(int x,int y): x_(x+y) { } - OverloadTest(int x,int y,int z): x_(x+y+z) {} - OverloadTest(int x,int y,int z, int a): x_(x+y+z+a) {} - OverloadTest(int x,int y,int z, int a, int b): x_(x+y+z+a+b) {} - - int x() const { return x_; } - void setX(int x) { x_ = x; } - - int p1(int x) { return x; } - int p2(int x, int y) { return x + y; } - int p3(int x, int y, int z) { return x + y + z; } - int p4(int x, int y, int z, int a) { return x + y + z + a; } - int p5(int x, int y, int z, int a, int b) { return x + y + z + a + b; } - private: - int x_; -}; - -static int getX(OverloadTest* u) -{ - return u->x(); -} - - -/************************************************************/ -/* */ -/* classes to test base declarations and conversions */ -/* */ -/************************************************************/ - -struct Dummy -{ - virtual ~Dummy() {} - int dummy_; -}; - -struct Base -{ - virtual int x() const { return 999; }; - virtual ~Base() {} -}; - -// inherit Dummy so that the Base part of Concrete starts at an offset -// otherwise, typecast tests wouldn't be very meaningful -struct Derived1 : public Dummy, public Base -{ - Derived1(int x): x_(x) {} - virtual int x() const { return x_; } - - private: - int x_; -}; - -struct Derived2 : public Dummy, public Base -{ - Derived2(int x): x_(x) {} - virtual int x() const { return x_; } - - private: - int x_; -}; - -static int testUpcast(Base* b) -{ - return b->x(); -} - -static std::auto_ptr derived1Factory(int i) -{ - return std::auto_ptr(i < 0 ? 0 : new Derived1(i)); -} - -static std::auto_ptr derived2Factory(int i) -{ - return std::auto_ptr(new Derived2(i)); -} - -static int testDowncast1(Derived1* d) -{ - return d->x(); -} - -static int testDowncast2(Derived2* d) -{ - return d->x(); -} - -/************************************************************/ -/* */ -/* test classes for interaction of overloading, */ -/* base declarations, and callbacks */ -/* */ -/************************************************************/ - -struct CallbackTestBase -{ - virtual int testCallback(int i) { return callback(i); } - virtual int callback(int i) = 0; - virtual ~CallbackTestBase() {} -}; - -struct CallbackTest : public CallbackTestBase -{ - virtual int callback(int i) { return i + 1; } - virtual std::string callbackString(std::string const & i) { return i + " 1"; } -}; - -struct CallbackTestCallback : public CallbackTest -{ - CallbackTestCallback(PyObject* self) - : m_self(self) - {} - - int callback(int x) - { - return boost::python::callback::call_method(m_self, "callback", x); - } - std::string callbackString(std::string const & x) - { - return boost::python::callback::call_method(m_self, "callback", x); - } - - static int default_callback(CallbackTest* self, int x) - { - return self->CallbackTest::callback(x); - } - static std::string default_callbackString(CallbackTest* self, std::string x) - { - return self->CallbackTest::callbackString(x); - } - - PyObject* m_self; -}; - -int testCallback(CallbackTestBase* b, int i) -{ - return b->testCallback(i); -} - -/************************************************************/ -/* */ -/* test classes for interaction of method lookup */ -/* in the context of inheritance */ -/* */ -/************************************************************/ - -struct A1 { - virtual ~A1() {} - virtual std::string overrideA1() const { return "A1::overrideA1"; } - virtual std::string inheritA1() const { return "A1::inheritA1"; } -}; - -struct A2 { - virtual ~A2() {} - virtual std::string inheritA2() const { return "A2::inheritA2"; } -}; - -struct B1 : A1, A2 { - std::string overrideA1() const { return "B1::overrideA1"; } - virtual std::string overrideB1() const { return "B1::overrideB1"; } -}; - -struct B2 : A1, A2 { - std::string overrideA1() const { return "B2::overrideA1"; } - virtual std::string inheritB2() const { return "B2::inheritB2"; } -}; - -struct C : B1 { - std::string overrideB1() const { return "C::overrideB1"; } -}; - -std::string call_overrideA1(const A1& a) { return a.overrideA1(); } -std::string call_overrideB1(const B1& b) { return b.overrideB1(); } -std::string call_inheritA1(const A1& a) { return a.inheritA1(); } - -std::auto_ptr factoryA1asA1() { return std::auto_ptr(new A1); } -std::auto_ptr factoryB1asA1() { return std::auto_ptr(new B1); } -std::auto_ptr factoryB2asA1() { return std::auto_ptr(new B2); } -std::auto_ptr factoryCasA1() { return std::auto_ptr(new C); } -std::auto_ptr factoryA2asA2() { return std::auto_ptr(new A2); } -std::auto_ptr factoryB1asA2() { return std::auto_ptr(new B1); } -std::auto_ptr factoryB1asB1() { return std::auto_ptr(new B1); } -std::auto_ptr factoryCasB1() { return std::auto_ptr(new C); } - -struct B_callback : B1 { - B_callback(PyObject* self) : m_self(self) {} - - std::string overrideA1() const { return boost::python::callback::call_method(m_self, "overrideA1"); } - std::string overrideB1() const { return boost::python::callback::call_method(m_self, "overrideB1"); } - - static std::string default_overrideA1(B1& x) { return x.B1::overrideA1(); } - static std::string default_overrideB1(B1& x) { return x.B1::overrideB1(); } - - PyObject* m_self; -}; - -struct A_callback : A1 { - A_callback(PyObject* self) : m_self(self) {} - - std::string overrideA1() const { return boost::python::callback::call_method(m_self, "overrideA1"); } - std::string inheritA1() const { return boost::python::callback::call_method(m_self, "inheritA1"); } - - static std::string default_overrideA1(A1& x) { return x.A1::overrideA1(); } - static std::string default_inheritA1(A1& x) { return x.A1::inheritA1(); } - - PyObject* m_self; -}; - -/************************************************************/ -/* */ -/* RawTest */ -/* (test passing of raw arguments to C++) */ -/* */ -/************************************************************/ - -struct RawTest -{ - RawTest(int i) : i_(i) {} - - int i_; -}; - -PyObject* raw(boost::python::tuple const & args, boost::python::dictionary const & keywords); - -int raw1(PyObject* args, PyObject* keywords) -{ - return PyTuple_Size(args) + PyDict_Size(keywords); -} - -int raw2(boost::python::ref args, boost::python::ref keywords) -{ - return PyTuple_Size(args.get()) + PyDict_Size(keywords.get()); -} - - - -/************************************************************/ -/* */ -/* Ratio */ -/* */ -/************************************************************/ - -typedef boost::rational Ratio; - -boost::python::string ratio_str(const Ratio& r) -{ - char buf[200]; - - if (r.denominator() == 1) - sprintf(buf, "%d", r.numerator()); - else - sprintf(buf, "%d/%d", r.numerator(), r.denominator()); - - return boost::python::string(buf); -} - -boost::python::string ratio_repr(const Ratio& r) -{ - char buf[200]; - sprintf(buf, "Rational(%d, %d)", r.numerator(), r.denominator()); - return boost::python::string(buf); -} - -boost::python::tuple ratio_coerce(const Ratio& r1, int r2) -{ - return boost::python::tuple(r1, Ratio(r2)); -} - -// The most reliable way, across compilers, to grab the particular abs function -// we're interested in. -Ratio ratio_abs(const Ratio& r) -{ - return boost::abs(r); -} - -// An experiment, to be integrated into the py_cpp library at some point. -template -struct StandardOps -{ - static T add(const T& x, const T& y) { return x + y; } - static T sub(const T& x, const T& y) { return x - y; } - static T mul(const T& x, const T& y) { return x * y; } - static T div(const T& x, const T& y) { return x / y; } - static T cmp(const T& x, const T& y) { return std::less()(x, y) ? -1 : std::less()(y, x) ? 1 : 0; } -}; - -// This helps us prove that we can now pass non-const reference parameters to constructors -struct Fubar { - Fubar(Foo&) {} - Fubar(int) {} -}; - -/************************************************************/ -/* */ -/* Int */ -/* this class tests operator export */ -/* */ -/************************************************************/ - -#ifndef NDEBUG -int total_Ints = 0; -#endif - -struct Int -{ - explicit Int(int i) : i_(i), j_(0) { -#ifndef NDEBUG - ++total_Ints; -#endif - } - -#ifndef NDEBUG - ~Int() { --total_Ints; } - Int(const Int& rhs) : i_(rhs.i_), j_(rhs.j_) { ++total_Ints; } -#endif - - int i() const { return i_; } - int j() const { return j_; } - - int i_; - int j_; - - Int& operator +=(Int const& r) { ++j_; i_ += r.i_; return *this; } - Int& operator -=(Int const& r) { ++j_; i_ -= r.i_; return *this; } - Int& operator *=(Int const& r) { ++j_; i_ *= r.i_; return *this; } - Int& operator /=(Int const& r) { ++j_; i_ /= r.i_; return *this; } - Int& operator %=(Int const& r) { ++j_; i_ %= r.i_; return *this; } - Int& ipow (Int const& r) { ++j_; - int o=i_; - for (int k=1; k>=(Int const& r) { ++j_; i_ >>= r.i_; return *this; } - Int& operator &=(Int const& r) { ++j_; i_ &= r.i_; return *this; } - Int& operator |=(Int const& r) { ++j_; i_ |= r.i_; return *this; } - Int& operator ^=(Int const& r) { ++j_; i_ ^= r.i_; return *this; } -}; - -Int operator+(Int const & l, Int const & r) { return Int(l.i_ + r.i_); } -Int operator+(Int const & l, int const & r) { return Int(l.i_ + r); } -Int operator+(int const & l, Int const & r) { return Int(l + r.i_); } - -Int operator-(Int const & l, Int const & r) { return Int(l.i_ - r.i_); } -Int operator-(Int const & l, int const & r) { return Int(l.i_ - r); } -Int operator-(int const & l, Int const & r) { return Int(l - r.i_); } -Int operator-(Int const & r) { return Int(- r.i_); } - -Int mul(Int const & l, Int const & r) { return Int(l.i_ * r.i_); } -Int imul(Int const & l, int const & r) { return Int(l.i_ * r); } -Int rmul(Int const & r, int const & l) { return Int(l * r.i_); } - -Int operator/(Int const & l, Int const & r) { return Int(l.i_ / r.i_); } - -Int operator%(Int const & l, Int const & r) { return Int(l.i_ % r.i_); } - -bool operator<(Int const & l, Int const & r) { return l.i_ < r.i_; } -bool operator<(Int const & l, int const & r) { return l.i_ < r; } -bool operator<(int const & l, Int const & r) { return l < r.i_; } - -Int pow(Int const & l, Int const & r) { return Int(static_cast(::pow(l.i_, r.i_))); } -Int powmod(Int const & l, Int const & r, Int const & m) { return Int((int)::pow(l.i_, r.i_) % m.i_); } -Int pow(Int const & l, int const & r) { return Int(static_cast(::pow(l.i_, r))); } - -std::ostream & operator<<(std::ostream & o, Int const & r) { return (o << r.i_); } - -/************************************************************/ -/* */ -/* double tests from Mark Evans() */ -/* */ -/************************************************************/ -double sizelist(boost::python::list list) { return list.size(); } -void vd_push_back(std::vector& vd, const double& x) -{ - vd.push_back(x); -} - -/************************************************************/ -/* */ -/* What if I want to return a pointer? */ -/* */ -/************************************************************/ - -// -// This example exposes the pointer by copying its referent -// -struct Record { - Record(int x) : value(x){} - int value; -}; - -const Record* get_record() -{ - static Record v(1234); - return &v; -} - -} // namespace bpl_test - -namespace boost { namespace python { - template class class_builder; // explicitly instantiate -}} // namespace boost::python - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -inline PyObject* to_python(const bpl_test::Record* p) -{ - return to_python(*p); -} -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -/************************************************************/ -/* */ -/* Enums and non-method class attributes */ -/* */ -/************************************************************/ - -namespace bpl_test { - -struct EnumOwner -{ - public: - enum enum_type { one = 1, two = 2, three = 3 }; - - EnumOwner(enum_type a1, const enum_type& a2) - : m_first(a1), m_second(a2) {} - - void set_first(const enum_type& x) { m_first = x; } - void set_second(const enum_type& x) { m_second = x; } - - enum_type first() { return m_first; } - enum_type second() { return m_second; } - private: - enum_type m_first, m_second; -}; - -} - -namespace boost { namespace python { - template class enum_as_int_converters; - using bpl_test::pow; -}} // namespace boost::python - -// This is just a way of getting the converters instantiated -//struct EnumOwner_enum_type_Converters -// : boost::python::py_enum_as_int_converters -//{ -//}; - -namespace bpl_test { - -/************************************************************/ -/* */ -/* pickling support */ -/* */ -/************************************************************/ - class world - { - private: - std::string country; - int secret_number; - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - }; - - // Support for pickle. - boost::python::tuple world_getinitargs(const world& w) - { - boost::python::tuple result(1); - result.set_item(0, w.get_country()); - return result; - } - - boost::python::tuple world_getstate(const world& w) - { - boost::python::tuple result(1); - result.set_item(0, w.get_secret_number()); - return result; - } - - void world_setstate(world& w, boost::python::tuple state) - { - if (state.size() != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw boost::python::error_already_set(); - } - - const int number = BOOST_PYTHON_CONVERSION::from_python(state[0].get(), boost::python::type()); - if (number != 42) - w.set_secret_number(number); - } - - // Test plain char converters. - char get_plain_char() { return 'x'; } - std::string use_plain_char(char c) { return std::string(3, c); } - - // This doesn't test anything but the compiler, since it has the same signature as the above. - // Since MSVC is broken and gets the signature wrong, we'll skip it. - std::string use_const_plain_char( -#ifndef BOOST_MSVC6_OR_EARLIER - const -#endif - char c) { return std::string(5, c); } - - // Test std::complex converters. - std::complex dpolar(double rho, double theta) { - return std::polar(rho, theta); - } - double dreal(const std::complex& c) { return c.real(); } - double dimag(std::complex c) { return c.imag(); } - - // Test std::complex converters. - std::complex fpolar(float rho, float theta) { - return std::polar(rho, theta); - } - double freal(const std::complex& c) { return c.real(); } - double fimag(std::complex c) { return c.imag(); } - - // Wrappers for inplace operators. - Int& int_iadd(Int& self, const Int& r) { self += r; return self; } - Int& int_isub(Int& self, const Int& r) { self -= r; return self; } - Int& int_imul(Int& self, const Int& r) { self *= r; return self; } - Int& int_idiv(Int& self, const Int& r) { self /= r; return self; } - Int& int_imod(Int& self, const Int& r) { self %= r; return self; } - Int& int_ipow(Int& self, const Int& r) { self.ipow (r); return self; } - Int& int_ilshift(Int& self, const Int& r) { self <<= r; return self; } - Int& int_irshift(Int& self, const Int& r) { self >>= r; return self; } - Int& int_iand(Int& self, const Int& r) { self &= r; return self; } - Int& int_ior(Int& self, const Int& r) { self |= r; return self; } - Int& int_ixor(Int& self, const Int& r) { self ^= r; return self; } - -/************************************************************/ -/* */ -/* init the module */ -/* */ -/************************************************************/ - -void init_module(boost::python::module_builder& m) -{ - m.def(get_record, "get_record"); - boost::python::class_builder record_class(m, "Record"); - record_class.def_readonly(&Record::value, "value"); - - m.def(sizelist, "sizelist"); - - boost::python::class_builder > vector_double(m, "vector_double"); - vector_double.def(boost::python::constructor<>()); - vector_double.def(vd_push_back, "push_back"); - - boost::python::class_builder fubar(m, "Fubar"); - fubar.def(boost::python::constructor()); - fubar.def(boost::python::constructor()); - - Foo::PythonClass foo(m); - BarPythonClass bar(m); - BazPythonClass baz(m); - StringMapPythonClass string_map(m); - IntPairPythonClass int_pair(m); - m.def(make_pair, "make_pair"); - CompareIntPairPythonClass compare_int_pair(m); - - boost::python::class_builder string_pair(m, "StringPair"); - string_pair.def(boost::python::constructor()); - string_pair.def_readonly(&StringPair::first, "first"); - string_pair.def_read_write(&StringPair::second, "second"); - string_pair.def(&stringpair_repr, "__repr__"); - string_pair.def(&stringpair_compare, "__cmp__"); - m.def(first_string, "first_string"); - m.def(second_string, "second_string"); - - // This shows the wrapping of a 3rd-party numeric type. - boost::python::class_builder > rational(m, "Rational"); - rational.def(boost::python::constructor()); - rational.def(boost::python::constructor()); - rational.def(boost::python::constructor<>()); - rational.def(StandardOps::add, "__add__"); - rational.def(StandardOps::sub, "__sub__"); - rational.def(StandardOps::mul, "__mul__"); - rational.def(StandardOps::div, "__div__"); - rational.def(StandardOps::cmp, "__cmp__"); - rational.def(ratio_coerce, "__coerce__"); - rational.def(ratio_str, "__str__"); - rational.def(ratio_repr, "__repr__"); - rational.def(ratio_abs, "__abs__"); - - boost::python::class_builder range(m, "Range"); - range.def(boost::python::constructor()); - range.def(boost::python::constructor()); - range.def((void (Range::*)(std::size_t))&Range::length, "__len__"); - range.def((std::size_t (Range::*)() const)&Range::length, "__len__"); - range.def(&Range::operator[], "__getitem__"); - range.def(&Range::slice, "__getslice__"); - range.def(&range_str, "__str__"); - range.def(&range_compare, "__cmp__"); - range.def(&range_hash, "__hash__"); - range.def_readonly(&Range::m_start, "start"); - range.def_readonly(&Range::m_finish, "finish"); - - m.def(&testVoid, "overloaded"); - m.def(&testInt, "overloaded"); - m.def(&testString, "overloaded"); - m.def(&test2, "overloaded"); - m.def(&test3, "overloaded"); - m.def(&test4, "overloaded"); - m.def(&test5, "overloaded"); - - boost::python::class_builder over(m, "OverloadTest"); - over.def(boost::python::constructor<>()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(&getX, "getX"); - over.def(&OverloadTest::setX, "setX"); - over.def(&OverloadTest::x, "overloaded"); - over.def(&OverloadTest::p1, "overloaded"); - over.def(&OverloadTest::p2, "overloaded"); - over.def(&OverloadTest::p3, "overloaded"); - over.def(&OverloadTest::p4, "overloaded"); - over.def(&OverloadTest::p5, "overloaded"); - - boost::python::class_builder base(m, "Base"); - base.def(&Base::x, "x"); - - boost::python::class_builder derived1(m, "Derived1"); - // this enables conversions between Base and Derived1 - // and makes wrapped methods of Base available - derived1.declare_base(base); - derived1.def(boost::python::constructor()); - - boost::python::class_builder derived2(m, "Derived2"); - // don't enable downcast from Base to Derived2 - derived2.declare_base(base, boost::python::without_downcast); - derived2.def(boost::python::constructor()); - - m.def(&testUpcast, "testUpcast"); - m.def(&derived1Factory, "derived1Factory"); - m.def(&derived2Factory, "derived2Factory"); - m.def(&testDowncast1, "testDowncast1"); - m.def(&testDowncast2, "testDowncast2"); - - boost::python::class_builder callbackTestBase(m, "CallbackTestBase"); - callbackTestBase.def(&CallbackTestBase::testCallback, "testCallback"); - m.def(&testCallback, "testCallback"); - - boost::python::class_builder callbackTest(m, "CallbackTest"); - callbackTest.def(boost::python::constructor<>()); - callbackTest.def(&CallbackTest::callback, "callback", - &CallbackTestCallback::default_callback); - callbackTest.def(&CallbackTest::callbackString, "callback", - &CallbackTestCallback::default_callbackString); - - callbackTest.declare_base(callbackTestBase); - - boost::python::class_builder a1_class(m, "A1"); - a1_class.def(boost::python::constructor<>()); - a1_class.def(&A1::overrideA1, "overrideA1", &A_callback::default_overrideA1); - a1_class.def(&A1::inheritA1, "inheritA1", &A_callback::default_inheritA1); - - boost::python::class_builder a2_class(m, "A2"); - a2_class.def(boost::python::constructor<>()); - a2_class.def(&A2::inheritA2, "inheritA2"); - - boost::python::class_builder b1_class(m, "B1"); - b1_class.declare_base(a1_class); - b1_class.declare_base(a2_class); - - b1_class.def(boost::python::constructor<>()); - b1_class.def(&B1::overrideA1, "overrideA1", &B_callback::default_overrideA1); - b1_class.def(&B1::overrideB1, "overrideB1", &B_callback::default_overrideB1); - - boost::python::class_builder b2_class(m, "B2"); - b2_class.declare_base(a1_class); - b2_class.declare_base(a2_class); - - b2_class.def(boost::python::constructor<>()); - b2_class.def(&B2::overrideA1, "overrideA1"); - b2_class.def(&B2::inheritB2, "inheritB2"); - - m.def(call_overrideA1, "call_overrideA1"); - m.def(call_overrideB1, "call_overrideB1"); - m.def(call_inheritA1, "call_inheritA1"); - - m.def(factoryA1asA1, "factoryA1asA1"); - m.def(factoryB1asA1, "factoryB1asA1"); - m.def(factoryB2asA1, "factoryB2asA1"); - m.def(factoryCasA1, "factoryCasA1"); - m.def(factoryA2asA2, "factoryA2asA2"); - m.def(factoryB1asA2, "factoryB1asA2"); - m.def(factoryB1asB1, "factoryB1asB1"); - m.def(factoryCasB1, "factoryCasB1"); - - boost::python::class_builder rawtest_class(m, "RawTest"); - rawtest_class.def(boost::python::constructor()); - rawtest_class.def_raw(&raw, "raw"); - - m.def_raw(&raw, "raw"); - m.def_raw(&raw1, "raw1"); - m.def_raw(&raw2, "raw2"); - - boost::python::class_builder int_class(m, "Int"); - int_class.def(boost::python::constructor()); - int_class.def(&Int::i, "i"); - int_class.def(&Int::j, "j"); - - // wrap homogeneous operators - int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_neg | - boost::python::op_cmp | boost::python::op_str | boost::python::op_divmod | boost::python::op_pow )>()); - // export non-operator functions as homogeneous operators - int_class.def(&mul, "__mul__"); - int_class.def(&powmod, "__pow__"); - - // wrap heterogeneous operators (lhs: Int const &, rhs: int const &) - int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_cmp | boost::python::op_pow)>(), - boost::python::right_operand()); - // export non-operator function as heterogeneous operator - int_class.def(&imul, "__mul__"); - - // wrap heterogeneous operators (lhs: int const &, rhs: Int const &) - int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_cmp)>(), - boost::python::left_operand()); - // export non-operator function as heterogeneous reverse-argument operator - int_class.def(&rmul, "__rmul__"); - -#if PYTHON_API_VERSION >= 1010 - // inplace operators. - int_class.def(&int_iadd, "__iadd__"); - int_class.def(&int_isub, "__isub__"); - int_class.def(&int_imul, "__imul__"); - int_class.def(&int_idiv, "__idiv__"); - int_class.def(&int_imod, "__imod__"); - int_class.def(&int_ipow, "__ipow__"); - int_class.def(&int_ilshift, "__ilshift__"); - int_class.def(&int_irshift, "__irshift__"); - int_class.def(&int_iand, "__iand__"); - int_class.def(&int_ior, "__ior__"); - int_class.def(&int_ixor, "__ixor__"); -#endif - - - boost::python::class_builder enum_owner(m, "EnumOwner"); - enum_owner.def(boost::python::constructor()); - enum_owner.def(&EnumOwner::set_first, "__setattr__first__"); - enum_owner.def(&EnumOwner::set_second, "__setattr__second__"); - enum_owner.def(&EnumOwner::first, "__getattr__first__"); - enum_owner.def(&EnumOwner::second, "__getattr__second__"); - enum_owner.add(PyInt_FromLong(EnumOwner::one), "one"); - enum_owner.add(PyInt_FromLong(EnumOwner::two), "two"); - enum_owner.add(PyInt_FromLong(EnumOwner::three), "three"); - - // pickling support - - // Create the Python type object for our extension class. - boost::python::class_builder world_class(m, "world"); - - // Add the __init__ function. - world_class.def(boost::python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def(world_getstate, "__getstate__"); - world_class.def(world_setstate, "__setstate__"); - - // Test plain char converters. - m.def(get_plain_char, "get_plain_char"); - m.def(use_plain_char, "use_plain_char"); - m.def(use_const_plain_char, "use_const_plain_char"); - - // Test std::complex converters. - m.def(dpolar, "dpolar"); - m.def(dreal, "dreal"); - m.def(dimag, "dimag"); - - // Test std::complex converters. - m.def(fpolar, "fpolar"); - m.def(freal, "freal"); - m.def(fimag, "fimag"); - - // Test new null-pointer<->None conversions - m.def(foo_factory, "foo_factory"); - m.def(foo_ptr_is_null, "foo_ptr_is_null"); - m.def(foo_shared_ptr_is_null, "foo_shared_ptr_is_null"); -} - -PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& keywords) -{ - if(args.size() != 2 || keywords.size() != 2) - { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::argument_error(); - } - - RawTest* first = BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()); - int second = BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()); - - int third = BOOST_PYTHON_CONVERSION::from_python(keywords[boost::python::string("third")].get(), boost::python::type()); - int fourth = BOOST_PYTHON_CONVERSION::from_python(keywords[boost::python::string("fourth")].get(), boost::python::type()); - - return BOOST_PYTHON_CONVERSION::to_python(first->i_ + second + third + fourth); -} - -BOOST_PYTHON_MODULE_INIT(boost_python_test) -{ - boost::python::module_builder boost_python_test("boost_python_test"); - init_module(boost_python_test); - - // Just for giggles, add a raw metaclass. - boost_python_test.add(new boost::python::meta_class); -} - -CompareIntPairPythonClass::CompareIntPairPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "CompareIntPair") -{ - def(boost::python::constructor<>()); - def(&CompareIntPair::operator(), "__call__"); -} - -} // namespace bpl_test - - -#if defined(_WIN32) -# ifdef __MWERKS__ -# pragma ANSI_strict off -# endif -# include -# ifdef __MWERKS__ -# pragma ANSI_strict reset -# endif -extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); - -# ifdef BOOST_MSVC -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -# endif - -#ifndef NDEBUG -namespace boost { namespace python { namespace detail { - extern int total_Dispatchers; -}}} // namespace boost::python::detail -#endif - -BOOL WINAPI DllMain( - HINSTANCE, //hDllInst - DWORD fdwReason, - LPVOID // lpvReserved - ) -{ -# ifdef BOOST_MSVC - _set_se_translator(structured_exception_translator); -#endif - (void)fdwReason; // warning suppression. - -#ifndef NDEBUG - switch(fdwReason) - { - case DLL_PROCESS_DETACH: - assert(bpl_test::total_Ints == 0); - } -#endif - - return 1; -} -#endif // _WIN32 diff --git a/test/comprehensive.hpp b/test/comprehensive.hpp deleted file mode 100644 index deb68a88..00000000 --- a/test/comprehensive.hpp +++ /dev/null @@ -1,235 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef BPL_TEST_DWA052200_H_ -# define BPL_TEST_DWA052200_H_ -// -// Example code demonstrating extension class usage -// - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace bpl_test { - -// -// example: Foo, Bar, and Baz are C++ classes we want to wrap. -// - -class Foo // prohibit copying, proving that it doesn't choke - : boost::noncopyable // our generation of to_python(). -{ - public: // constructor/destructor - Foo(int x) : m_x(x) {} - virtual ~Foo() {} - - public: // non-virtual functions - const char* mumble(); // mumble something - void set(long x); // change the held value - - // These two call virtual functions - std::string call_pure(); // call a pure virtual fuction - int call_add_len(const char* s) const; // virtual function with a default implementation - - // A couple nested classs. - struct Foo_A { const char* mumble(); }; - struct Foo_B { const char* mumble(); }; - - private: - // by default, sum the held value and the length of s - virtual int add_len(const char* s) const; - - // Derived classes can do whatever they want here, but they must do something! - virtual std::string pure() const = 0; - - public: // friend declarations - // If you have private virtual functions such as add_len which you want to - // override in Python and have default implementations, they must be - // accessible by the thing making the def() call on the extension_class (in - // this case, the nested PythonClass itself), and by the C++ derived class - // which is used to cause the Python callbacks (in this case, - // FooCallback). See the definition of FooCallback::add_len() - struct PythonClass; - friend struct PythonClass; - friend class FooCallback; - - private: - int m_x; // the held value -}; - -// -// Bar and Baz have mutually-recursive type conversion dependencies (see -// pass_xxx functions). I've done this to prove that it doesn't cause a -// problem for Python class definitions, which happen later. -// -// Bar and Baz functions are only virtual to increase the likelihood of a crash -// if I inadvertently use a pointer to garbage memory (a likely thing to test -// for considering the amount of type casting needed to translate to and from -// Python). -struct Baz; -struct Bar -{ - Bar(int x, int y) : m_first(x), m_second(y) {} - virtual int first() const { return m_first; } - virtual int second() const { return m_second; } - virtual Baz pass_baz(Baz x); - - int m_first, m_second; -}; - -struct Baz -{ - virtual Bar pass_bar(const Bar& x) { return x; } - - // We can return smart pointers - virtual std::auto_ptr clone() { return std::auto_ptr(new Baz(*this)); } - - // This illustrates creating a polymorphic derived class of Foo - virtual boost::shared_ptr create_foo(); - - // We can accept smart pointer parameters - virtual int get_foo_value(boost::shared_ptr); - - // Show what happens in python when we take ownership from an auto_ptr - virtual void eat_baz(std::auto_ptr); -}; - -typedef std::map StringMap; -typedef std::pair IntPair; - -IntPair make_pair(int, int); - -typedef std::less CompareIntPair; -typedef std::pair StringPair; - -inline std::string first_string(const StringPair& x) -{ - return x.first; -} - -inline std::string second_string(const StringPair& x) -{ - return x.second; -} - -struct Range -{ - Range(int x) - : m_start(x), m_finish(x) {} - - Range(int start, int finish) - : m_start(start), m_finish(finish) {} - - std::size_t length() const - { return m_finish < m_start ? 0 : m_finish - m_start; } - - void length(std::size_t new_length) - { m_finish = m_start + new_length; } - - int operator[](std::size_t n) - { return m_start + n; } - - Range slice(std::size_t start, std::size_t end) - { - if (start > length()) - start = length(); - if (end > length()) - end = length(); - return Range(m_start + start, m_start + end); - } - - int m_start, m_finish; -}; - -//////////////////////////////////////////////////////////////////////// -// // -// Begin wrapping code. Usually this would live in a separate header. // -// // -//////////////////////////////////////////////////////////////////////// - -// Since Foo has virtual functions which we want overriden in Python, we must -// derive FooCallback. -class FooCallback : public Foo -{ - public: - // Note the additional constructor parameter "self", which is needed to - // allow function overriding from Python. - FooCallback(PyObject* self, int x); - - friend struct PythonClass; // give it access to the functions below - - private: // implementations of Foo virtual functions that are overridable in python. - int add_len(const char* x) const; - - // A function which Python can call in case bar is not overridden from - // Python. In true Python style, we use a free function taking an initial - // self parameter. You can put this function anywhere; it needn't be a - // static member of the wrapping class. - static int default_add_len(const Foo* self, const char* x); - - // Since Foo::pure() is pure virtual, we don't need a corresponding - // default_pure(). A failure to override it in Python will result in an - // exception at runtime when pure() is called. - std::string pure() const; - - private: // Required boilerplate if functions will be overridden - PyObject* m_self; // No, we don't want a boost::python::ref here, or we'd get an ownership cycle. -}; - -// Define the Python base class -struct Foo::PythonClass : boost::python::class_builder { PythonClass(boost::python::module_builder&); }; - -// No virtual functions on Bar or Baz which are actually supposed to behave -// virtually from C++, so we'll rely on the library to define a wrapper for -// us. Even so, Python class_t types for each type we're wrapping should be -// _defined_ here in a header where they can be seen by other extension class -// definitions, since it is the definition of the boost::python::class_builder<> that -// causes to_python/from_python conversion functions to be generated. -struct BarPythonClass : boost::python::class_builder { BarPythonClass(boost::python::module_builder&); }; -struct BazPythonClass : boost::python::class_builder { BazPythonClass(boost::python::module_builder&); }; - -struct StringMapPythonClass - : boost::python::class_builder -{ - StringMapPythonClass(boost::python::module_builder&); - - // These static functions implement the right argument protocols for - // implementing the Python "special member functions" for mapping on - // StringMap. Could just as easily be global functions. - static const std::string& get_item(const StringMap& m, std::size_t key); - static void set_item(StringMap& m, std::size_t key, const std::string& value); - static void del_item(StringMap& m, std::size_t key); -}; - -struct IntPairPythonClass - : boost::python::class_builder -{ - IntPairPythonClass(boost::python::module_builder&); - - // The following could just as well be a free function; it implements the - // getattr functionality for IntPair. - static int getattr(const IntPair&, const std::string& s); - static void setattr(IntPair&, const std::string& name, int value); - static void delattr(IntPair&, const char* name); -}; - -struct CompareIntPairPythonClass - : boost::python::class_builder -{ - CompareIntPairPythonClass(boost::python::module_builder&); -}; - -} // namespace bpl_test - -#endif // BPL_TEST_DWA052200_H_ diff --git a/test/comprehensive.py b/test/comprehensive.py deleted file mode 100644 index 7d0bec79..00000000 --- a/test/comprehensive.py +++ /dev/null @@ -1,1280 +0,0 @@ -r''' -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// Revision History: -// 2001 Nov 01 Python 2.2 pickle problems fixed (rwgk) -// 04 Mar 01 Changed name of extension module so it would work with DebugPython, -// fixed exception message checking to work with Python 2.0 -// (Dave Abrahams) - -Automatic checking of the number and type of arguments. Foo's constructor takes -a single long parameter. - - >>> try: - ... ext = Foo() - ... except TypeError, err: - ... assert re.match(r'function .* exactly 1 argument;? \(?0 given\)?', - ... str(err)) - ... else: - ... print 'no exception' - - >>> try: ext = Foo('foo') - ... except TypeError, err: - ... assert_integer_expected(err) - ... else: - ... print 'no exception' - - >>> ext = Foo(1) - -Call a virtual function. This call takes a trip into C++ where -FooCallback::add_len() looks up the Python "add_len" attribute and finds the -wrapper for FooCallback::default_add_len(), which in turn calls Foo::add_len(). - - >>> ext.add_len('hello') - 6 - >>> ext.set(3) - >>> ext.add_len('hello') - 8 - -Call a pure virtual function which should have been overridden, but was not. - - >>> ext.call_pure() - Traceback (innermost last): - File "", line 1, in ? - AttributeError: pure - -We can subclass Foo. - - >>> class Subclass(Foo): - ... def __init__(self, seq): - ... Foo.__init__(self, len(seq)) - ... - ... def pure(self): - ... return 'not pure anymore!' - ... - ... def get(self): - ... return Foo.add_len(self, '') - ... - ... def add_len(self, s): - ... print 'called add_len()' - ... return self.get() + len(s) - ... - >>> b = Subclass('yippee') - >>> b.get() - 6 - >>> b.mumble() - 'mumble' - >>> b.call_pure() - 'not pure anymore!' - -None corresponds to a NULL pointer or smart pointer - >>> f = foo_factory(1) - >>> f.add_len('xxx') - 1000 - >>> foo_factory(0) is None - 1 - >>> foo_ptr_is_null(None) - 1 - >>> foo_ptr_is_null(f) - 0 - >>> foo_shared_ptr_is_null(None) - 1 - >>> foo_shared_ptr_is_null(f) - 0 - -If no __init__ function is defined, the one from the base class takes effect, just -like in a Python class. - - >>> class DemonstrateInitPassthru(Foo): pass - ... - >>> q = DemonstrateInitPassthru(1) - >>> q.add_len("x") - 2 - -If we don't initialize the base class, we'll get a RuntimeError when we try to -use its methods. The test illustrates the kind of error to expect. - - >>> class BadSubclass(Foo): - ... def __init__(self): pass - ... - >>> barf = BadSubclass() - >>> barf.set(4) - Traceback (innermost last): - ... - RuntimeError: __init__ function for extension class 'Foo' was never called. - -Here we are tesing that the simple definition procedure used in the C++ demo -file for classes without any virtual functions actually worked. - - >>> bar = Bar(3, 4) - >>> bar.first() - 3 - >>> bar.second() - 4 - >>> baz = Baz() - -We can actually return the wrapped classes by value - - >>> baz.pass_bar(bar).first() - 3 - >>> bar.pass_baz(baz) is baz # A copy of the return value is made. - 0 - >>> type(bar.pass_baz(baz)) is type(baz) - 1 - -And, yes, we can multiply inherit from these classes. - - >>> class MISubclass(Subclass, Bar): - ... def __init__(self, s): - ... Subclass.__init__(self, s) - ... Bar.__init__(self, 0, len(s)) - ... - >>> mi = MISubclass('xx') - >>> mi.first() - 0 - >>> mi.second() - 2 - >>> mi.mumble() - 'mumble' - -We can even mulitply inherit from built-in Python classes, even if they are -first in the list of bases - - >>> class RealPythonClass: - ... def real_python_method(self): - ... print 'RealPythonClass.real_python_method()' - ... def other_first(self, other): - ... return other.first() - - >>> class MISubclass2(RealPythonClass, Bar): - ... def new_method(self): - ... print 'MISubclass2.new_method()' - ... bound_function = RealPythonClass().other_first - ... - >>> mi2 = MISubclass2(7, 8) - >>> mi2.first() # we can call inherited member functions from Bar - 7 - >>> mi2.real_python_method() # we can call inherited member functions from RealPythonClass - RealPythonClass.real_python_method() - - >>> mi2.new_method() # we can call methods on the common derived class - MISubclass2.new_method() - - We can call unbound methods from the base class accessed through the derived class - >>> MISubclass2.real_python_method(mi2) - RealPythonClass.real_python_method() - - We have not interfered with ordinary python bound methods - >>> MISubclass2.bound_function(mi2) - 7 - >>> mi2.bound_function() - 7 - -Any object whose class is derived from Bar can be passed to a function expecting -a Bar parameter: - - >>> baz.pass_bar(mi).first() - 0 - -But objects not derived from Bar cannot: - - >>> baz.pass_bar(baz) - Traceback (innermost last): - ... - TypeError: extension class 'Baz' is not convertible into 'Bar'. - -The clone function on Baz returns a smart pointer; we wrap it into an -extension_instance and make it look just like any other Baz obj. - - >>> baz_clone = baz.clone() - >>> baz_clone.pass_bar(mi).first() - 0 - -Functions expecting an std::auto_ptr parameter will not accept a raw Baz - - >>> try: baz.eat_baz(Baz()) - ... except RuntimeError, err: - ... assert re.match("Object of extension class 'Baz' does not wrap <.*>.", - ... str(err)) - ... else: - ... print 'no exception' - -We can pass std::auto_ptr where it is expected - - >>> baz.eat_baz(baz_clone) - -And if the auto_ptr has given up ownership? - - # MSVC6 ships with an outdated auto_ptr that doesn't get zeroed out when it - # gives up ownership. If you are using MSVC6 without the new Dinkumware - # library, SGI STL or the STLport, expect this test to crash unless you put - # --broken-auto-ptr on the command line. - >>> if not '--broken-auto-ptr' in sys.argv: - ... try: baz_clone.clone() - ... except RuntimeError, err: - ... assert re.match('Converting from python, pointer or smart pointer to <.*> is NULL.', str(err)) - ... else: - ... print 'no exeption' - -Polymorphism also works: - - >>> polymorphic_foo = baz.create_foo() - >>> polymorphic_foo.call_pure() - 'this was never pure!' - >>> baz.get_foo_value(polymorphic_foo) - 1000 - -Simple nested class test: - >>> foo_a = Foo.Foo_A() - >>> foo_a.mumble() - 'mumble a' - >>> foo_b = Foo.Foo_B() - >>> foo_b.mumble() - 'mumble b' - -Pickling tests: - - >>> world.__module__ - 'boost_python_test' - >>> world.__safe_for_unpickling__ - 1 - >>> world.__reduce__() - 'world' - >>> reduced = world('Hello').__reduce__() - >>> reduced[0] == world - 1 - >>> reduced[1:] - (('Hello',), (0,)) - >>> import StringIO - >>> import cPickle - >>> pickle = cPickle - >>> for number in (24, 42): - ... wd = world('California') - ... wd.set_secret_number(number) - ... # Dump it out and read it back in. - ... f = StringIO.StringIO() - ... pickle.dump(wd, f) - ... f = StringIO.StringIO(f.getvalue()) - ... wl = pickle.load(f) - ... # - ... print wd.greet(), wd.get_secret_number() - ... print wl.greet(), wl.get_secret_number() - ... - Hello from California! 24 - Hello from California! 24 - Hello from California! 42 - Hello from California! 0 - -Pickle safety measures: - >>> r=Rational(3, 4) - >>> r - Rational(3, 4) - >>> try: s=pickle.dumps(r) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__dict_defines_state__ not set) - >>> r=myrational(3, 4) - >>> r - Rational(3, 4) - >>> s=pickle.dumps(r) - >>> u=pickle.loads(s) - - >>> w = myworld() - >>> w.greet() - 'Hello from anywhere!' - >>> w.__dict__ - {'x': 1} - >>> try: s=pickle.dumps(w) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__getstate_manages_dict__ not set) - - >>> w = myunsafeworld() - >>> w.greet() - 'Hello from anywhere!' - >>> w.__dict__ - {'x': 1} - >>> s=pickle.dumps(w) - -Special member attributes. Tests courtesy of Barry Scott - - >>> class DerivedFromFoo(Foo): - ... def __init__(self): - ... Foo.__init__( self, 1 ) - ... def fred(self): - ... 'Docs for DerivedFromFoo.fred' - ... print 'Barry.fred' - ... def __del__(self): - ... print 'Deleting DerivedFromFoo' - - >>> class Base: - ... i_am_base = 'yes' - ... def fred(self): - ... 'Docs for Base.fred' - ... pass - - - >>> class DerivedFromBase(Base): - ... i_am_derived_from_base = 'yes' - ... def fred(self): - ... 'Docs for DerivedFromBase.fred' - ... pass - - >>> dir(DerivedFromFoo) - ['__del__', '__doc__', '__init__', '__module__', 'fred'] - - >>> df = DerivedFromFoo() - >>> df.__dict__ - {} - >>> df.fred.__doc__ - 'Docs for DerivedFromFoo.fred' - - >>> db = DerivedFromBase() - >>> db.__dict__ - {} - >>> db.fred.__doc__ - 'Docs for DerivedFromBase.fred' - - >>> import sys - >>> if not sys.__dict__.has_key('version_info') or \ - ... sys.version_info[0] < 2 or ( sys.version_info[0] == 2 and - ... sys.version_info[1] < 2 ): - ... assert dir(df) == [] - ... assert dir(db) == [] - ... assert dir(DerivedFromBase) == [ - ... '__doc__', '__module__', 'fred', 'i_am_derived_from_base'] - ... else: - ... assert dir(df) == [ - ... 'Foo_A', 'Foo_B', '__del__', '__doc__', '__init__', '__module__', 'add_len', - ... 'call_add_len', 'call_pure', 'fred', 'mumble', 'set'] - ... assert dir(db) == ['__doc__', '__module__', 'fred' - ... , 'i_am_base', 'i_am_derived_from_base'] - ... assert dir(DerivedFromBase) == [ - ... '__doc__', '__module__', 'fred', 'i_am_base', 'i_am_derived_from_base'] - -Special member functions in action - >>> del df - Deleting DerivedFromFoo - - # force method table sharing - >>> class DerivedFromStringMap(StringMap): pass - ... - - >>> m = StringMap() - -__getitem__() - >>> m[1] - Traceback (innermost last): - File "", line 1, in ? - KeyError: 1 - -__setitem__() - - >>> m[1] = 'hello' - -__getitem__() - >>> m[1] - 'hello' - -__delitem__() - >>> del m[1] - >>> m[1] # prove that it's gone - Traceback (innermost last): - File "", line 1, in ? - KeyError: 1 - -__delitem__() - >>> del m[2] - Traceback (innermost last): - File "", line 1, in ? - KeyError: 2 - -__length__() - >>> len(m) - 0 - >>> m[3] = 'farther' - >>> len(m) - 1 - -Check for sequence/mapping confusion: - >>> for x in m: - ... print x - ... - Traceback (innermost last): - File "", line 1, in ? - KeyError: 0 - -Check for the ability to pass a non-const reference as a constructor parameter - >>> x = Fubar(Foo(1)) - -Some simple overloading tests: - >>> r = Range(3) - >>> print str(r) - (3, 3) - >>> r.start - 3 - >>> r.finish - 3 - >>> r.__len__() - 0 - >>> r.__len__(4) - >>> r.finish - 7 - >>> try: r = Range('yikes') - ... except TypeError, e: - ... assert re.match( - ... 'No overloaded functions match [(]Range, str[a-z]*[)]\. Candidates are:\n.*\n.*', - ... str(e)) - ... else: print 'no exception' - -Sequence tests: - >>> len(Range(3, 10)) - 7 - - >>> map(lambda x:x, Range(3, 10)) - [3, 4, 5, 6, 7, 8, 9] - - >>> map(lambda x:x, Range(3, 10)[-2:]) - [8, 9] - - >>> map(lambda x:x, Range(3, 10)[:-4]) - [3, 4, 5] - - >>> map(lambda x:x, Range(3, 10)[4:]) - [7, 8, 9] - - >>> map(lambda x:x, Range(3, 10)[4:100]) - [7, 8, 9] - - >>> map(lambda x:x, Range(3, 10)[20:]) - [] - - >>> map(lambda x:x, Range(3, 10)[0:4]) - [3, 4, 5, 6] - -Numeric tests: - >>> x = Rational(2,3) - >>> y = Rational(1,4) - >>> print x + y - 11/12 - >>> print x - y - 5/12 - >>> print x * y - 1/6 - >>> print x / y - 8/3 - >>> print x + 1 # testing coercion - 5/3 - >>> print 1 + x # coercion the other way - 5/3 - -delete non-existent attribute: - del m.foobar - Traceback (innermost last): - File "", line 1, in ? - AttributeError: delete non-existing obj attribute - -Testing __getattr__ and __getattr__: - - >>> n = IntPair(1, 2) - >>> n.first - 1 - >>> n.second - 2 - >>> n.third - Traceback (innermost last): - File "", line 1, in ? - AttributeError: third - -Testing __setattr__ and __setattr__: - >>> n.first = 33 # N.B __setattr__first sets first to - >>> n.first # the negative of its argument. - -33 - >>> n.second = 66 - >>> n.second - 66 - -Testing __delattr__ and __delattr__: - >>> del n.first - Traceback (innermost last): - File "", line 1, in ? - AttributeError: first can't be deleted! - >>> del n.second - Traceback (innermost last): - File "", line 1, in ? - AttributeError: Attributes can't be deleted! - >>> del n.third - Traceback (innermost last): - File "", line 1, in ? - AttributeError: Attributes can't be deleted! - - # Now show that we can override it. - - >>> class IntTriple(IntPair): - ... def __getattr__(self, s): - ... if s in ['first', 'second']: - ... return IntPair.__getattr__(self, s) - ... elif s == 'third': - ... return 3 - ... else: - ... raise AttributeError(s) - ... - ... # Also show that __setattr__ is supported - ... def __setattr__(self, name, value): - ... raise AttributeError('no writable attributes') - ... - >>> p = IntTriple(0, 1) - >>> p.first - 0 - >>> p.second - 1 - >>> p.third - 3 - >>> p.bax - Traceback (innermost last): - File "", line 1, in ? - AttributeError: bax - >>> p.third = 'yes' - Traceback (innermost last): - File "", line 1, in ? - AttributeError: no writable attributes - >>> del p.third - Traceback (innermost last): - File "", line 1, in ? - AttributeError: Attributes can't be deleted! - -demonstrate def_readonly, def_read_write: - >>> sp = StringPair("hello", "world") - >>> sp.first # first is read-only - 'hello' - >>> first_string(sp) # prove that we're not just looking in sp's __dict__ - 'hello' - >>> sp.first = 'hi' # we're not allowed to change it - Traceback (innermost last): - File "", line 1, in ? - AttributeError: 'first' attribute is read-only - >>> first_string(sp) # prove that it hasn't changed - 'hello' - - >>> sp.second # second is read/write - 'world' - >>> second_string(sp) - 'world' - >>> sp.second = 'universe' # set the second attribute - >>> sp.second - 'universe' - >>> second_string(sp) # this proves we didn't just set it in sp's __dict__ - 'universe' - -some __str__ and __repr__ tests: - >>> sp - ('hello', 'universe') - >>> repr(sp) - "('hello', 'universe')" - >>> str(sp) - "('hello', 'universe')" - - Range has a __str__ function but not a __repr__ function - >>> range = Range(5, 20) - >>> str(range) - '(5, 20)' - >>> assert re.match('', repr(range)) - -__hash__ and __cmp__ tests: - # Range has both __hash__ and __cmp__, thus is hashable - >>> colors = { Range(3,4): 'blue', Range(7,9): 'red' } - >>> colors[Range(3,4)] - 'blue' - - # StringPair has only __cmp__ - >>> { StringPair('yo', 'eddy'): 1 } - Traceback (innermost last): - File "", line 1, in ? - TypeError: unhashable type - - # But it can be sorted - >>> stringpairs = [ StringPair('yo', 'eddy'), StringPair('yo', 'betty'), sp ] - >>> stringpairs.sort() - >>> stringpairs - [('hello', 'universe'), ('yo', 'betty'), ('yo', 'eddy')] - -make_pair is a global function in the module. - - >>> couple = make_pair(3,12) - >>> couple.first - 3 - >>> couple.second - 12 - -Testing __call__: - >>> couple2 = make_pair(3, 7) - >>> comparator = CompareIntPair() - >>> comparator(couple, couple) - 0 - >>> comparator(couple, couple2) - 0 - >>> comparator(couple2, couple) - 1 - -Testing overloaded free functions - >>> overloaded() - 'Hello world!' - >>> overloaded(1) - 1 - >>> overloaded('foo') - 'foo' - >>> overloaded(1,2) - 3 - >>> overloaded(1,2,3) - 6 - >>> overloaded(1,2,3,4) - 10 - >>> overloaded(1,2,3,4,5) - 15 - >>> try: overloaded(1, 'foo') - ... except TypeError, err: - ... assert re.match("No overloaded functions match \(int, str[a-z]*\)\. Candidates are:", - ... str(err)) - ... else: - ... print 'no exception' - -Testing overloaded constructors - - >>> over = OverloadTest() - >>> over.getX() - 1000 - >>> over = OverloadTest(1) - >>> over.getX() - 1 - >>> over = OverloadTest(1,1) - >>> over.getX() - 2 - >>> over = OverloadTest(1,1,1) - >>> over.getX() - 3 - >>> over = OverloadTest(1,1,1,1) - >>> over.getX() - 4 - >>> over = OverloadTest(1,1,1,1,1) - >>> over.getX() - 5 - >>> over = OverloadTest(over) - >>> over.getX() - 5 - >>> try: over = OverloadTest(1, 'foo') - ... except TypeError, err: - ... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:", - ... str(err)) - ... else: - ... print 'no exception' - -Testing overloaded methods - - >>> over.setX(3) - >>> over.overloaded() - 3 - >>> over.overloaded(1) - 1 - >>> over.overloaded(1,1) - 2 - >>> over.overloaded(1,1,1) - 3 - >>> over.overloaded(1,1,1,1) - 4 - >>> over.overloaded(1,1,1,1,1) - 5 - >>> try: over.overloaded(1,'foo') - ... except TypeError, err: - ... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:", - ... str(err)) - ... else: - ... print 'no exception' - -Testing base class conversions - - >>> testUpcast(over) - Traceback (innermost last): - TypeError: extension class 'OverloadTest' is not convertible into 'Base'. - >>> der1 = Derived1(333) - >>> der1.x() - 333 - >>> testUpcast(der1) - 333 - >>> der1 = derived1Factory(1000) - >>> testDowncast1(der1) - 1000 - >>> testDowncast2(der1) - Traceback (innermost last): - TypeError: extension class 'Base' is not convertible into 'Derived2'. - >>> der2 = Derived2(444) - >>> der2.x() - 444 - >>> testUpcast(der2) - 444 - >>> der2 = derived2Factory(1111) - >>> testDowncast2(der2) - Traceback (innermost last): - TypeError: extension class 'Base' is not convertible into 'Derived2'. - -Testing interaction between callbacks, base declarations, and overloading -- testCallback() calls callback() (within C++) -- callback() is overloaded (in the wrapped class CallbackTest) -- callback() is redefined in RedefineCallback (overloading is simulated by type casing) -- testCallback() should use the redefined callback() - - >>> c = CallbackTest() - >>> c.testCallback(1) - 2 - - >>> try: c.testCallback('foo') - ... except TypeError, err: assert_integer_expected(err) - ... else: print 'no exception' - - >>> c.callback(1) - 2 - >>> c.callback('foo') - 'foo 1' - - >>> import types - >>> class RedefineCallback(CallbackTest): - ... def callback(self, x): - ... if type(x) is types.IntType: - ... return x - 2 - ... else: - ... return CallbackTest.callback(self,x) - ... - >>> r = RedefineCallback() - >>> r.callback(1) - -1 - >>> r.callback('foo') - 'foo 1' - - >>> try: r.testCallback('foo') - ... except TypeError, err: assert_integer_expected(err) - ... else: print 'no exception' - - >>> r.testCallback(1) - -1 - >>> testCallback(r, 1) - -1 - -Regression test for a reference-counting bug thanks to Mark Evans -() - >>> sizelist([]) - 0.0 - >>> sizelist([1, 2, 4]) - 3.0 - -And another for doubles - >>> vector_double().push_back(3.0) - -Tests for method lookup in the context of inheritance -Set up the tests - - >>> a1 = A1() - >>> a2 = A2() - >>> b1 = B1() - >>> b2 = B2() - >>> pa1_a1 = factoryA1asA1() - >>> pb1_a1 = factoryB1asA1() - >>> pb2_a1 = factoryB2asA1() - >>> pc_a1 = factoryCasA1() - >>> pa2_a2 = factoryA2asA2() - >>> pb1_a2 = factoryB1asA2() - >>> pb1_b1 = factoryB1asB1() - >>> pc_b1 = factoryCasB1() - >>> class DA1(A1): - ... def overrideA1(self): - ... return 'DA1.overrideA1' - ... - >>> da1 = DA1() - >>> class DB1(B1): - ... def overrideA1(self): - ... return 'DB1.overrideA1' - ... def overrideB1(self): - ... return 'DB1.overrideB1' - ... - >>> db1 = DB1() - >>> class DB2(B2): pass - ... - >>> db2 = DB2() - -test overrideA1 - - >>> a1.overrideA1() - 'A1::overrideA1' - >>> b1.overrideA1() - 'B1::overrideA1' - >>> b2.overrideA1() - 'B2::overrideA1' - >>> da1.overrideA1() - 'DA1.overrideA1' - >>> db1.overrideA1() - 'DB1.overrideA1' - >>> pa1_a1.overrideA1() - 'A1::overrideA1' - >>> pb1_a1.overrideA1() - 'B1::overrideA1' - >>> pb2_a1.overrideA1() - 'B2::overrideA1' - >>> pb1_b1.overrideA1() - 'B1::overrideA1' - >>> pc_a1.overrideA1() - 'B1::overrideA1' - >>> pc_b1.overrideA1() - 'B1::overrideA1' - -test call_overrideA1 - - >>> call_overrideA1(a1) - 'A1::overrideA1' - >>> call_overrideA1(b1) - 'B1::overrideA1' - >>> call_overrideA1(b2) - 'B2::overrideA1' - >>> call_overrideA1(da1) - 'DA1.overrideA1' - >>> call_overrideA1(db1) - 'DB1.overrideA1' - >>> call_overrideA1(pa1_a1) - 'A1::overrideA1' - >>> call_overrideA1(pb1_a1) - 'B1::overrideA1' - >>> call_overrideA1(pb2_a1) - 'B2::overrideA1' - >>> call_overrideA1(pb1_b1) - 'B1::overrideA1' - >>> call_overrideA1(pc_a1) - 'B1::overrideA1' - >>> call_overrideA1(pc_b1) - 'B1::overrideA1' - -test inheritA1 - - >>> a1.inheritA1() - 'A1::inheritA1' - >>> b1.inheritA1() - 'A1::inheritA1' - >>> b2.inheritA1() - 'A1::inheritA1' - >>> da1.inheritA1() - 'A1::inheritA1' - >>> db1.inheritA1() - 'A1::inheritA1' - >>> pa1_a1.inheritA1() - 'A1::inheritA1' - >>> pb1_a1.inheritA1() - 'A1::inheritA1' - >>> pb2_a1.inheritA1() - 'A1::inheritA1' - >>> pb1_b1.inheritA1() - 'A1::inheritA1' - >>> pc_a1.inheritA1() - 'A1::inheritA1' - >>> pc_b1.inheritA1() - 'A1::inheritA1' - -test call_inheritA1 - - >>> call_inheritA1(a1) - 'A1::inheritA1' - >>> call_inheritA1(b1) - 'A1::inheritA1' - >>> call_inheritA1(b2) - 'A1::inheritA1' - >>> call_inheritA1(da1) - 'A1::inheritA1' - >>> call_inheritA1(db1) - 'A1::inheritA1' - >>> call_inheritA1(pa1_a1) - 'A1::inheritA1' - >>> call_inheritA1(pb1_a1) - 'A1::inheritA1' - >>> call_inheritA1(pb2_a1) - 'A1::inheritA1' - >>> call_inheritA1(pb1_b1) - 'A1::inheritA1' - >>> call_inheritA1(pc_a1) - 'A1::inheritA1' - >>> call_inheritA1(pc_b1) - 'A1::inheritA1' - -test inheritA2 - - >>> a2.inheritA2() - 'A2::inheritA2' - >>> b1.inheritA2() - 'A2::inheritA2' - >>> b2.inheritA2() - 'A2::inheritA2' - >>> db1.inheritA2() - 'A2::inheritA2' - >>> pa2_a2.inheritA2() - 'A2::inheritA2' - >>> pb1_a2.inheritA2() - 'A2::inheritA2' - >>> pb1_b1.inheritA2() - 'A2::inheritA2' - -test overrideB1 - - >>> b1.overrideB1() - 'B1::overrideB1' - >>> db1.overrideB1() - 'DB1.overrideB1' - >>> pb1_b1.overrideB1() - 'B1::overrideB1' - >>> pc_b1.overrideB1() - 'C::overrideB1' - -test call_overrideB1 - - >>> call_overrideB1(b1) - 'B1::overrideB1' - >>> call_overrideB1(db1) - 'DB1.overrideB1' - >>> call_overrideB1(pb1_a1) - 'B1::overrideB1' - >>> call_overrideB1(pc_a1) - 'C::overrideB1' - >>> call_overrideB1(pb1_b1) - 'B1::overrideB1' - >>> call_overrideB1(pc_b1) - 'C::overrideB1' - -test inheritB2 - - >>> b2.inheritB2() - 'B2::inheritB2' - >>> db2.inheritB2() - 'B2::inheritB2' - -========= test the new def_raw() feature ========== - - >>> r = RawTest(1) - >>> raw(r,1,third=1,fourth=1) - 4 - >>> r.raw(1,third=1,fourth=1) - 4 - >>> raw(r,1,third=1,f=1) - Traceback (innermost last): - KeyError: fourth - >>> raw(r,1,third=1) - Traceback (innermost last): - TypeError: wrong number of arguments - >>> raw(r,1) - Traceback (innermost last): - TypeError: wrong number of arguments - >>> raw() - Traceback (innermost last): - TypeError: wrong number of arguments - >>> raw1(1,second=1) - 2 - >>> raw1(1) - 1 - >>> raw1(second=1) - 1 - >>> raw1() - 0 - >>> raw2(1,second=1) - 2 - >>> raw2(1) - 1 - >>> raw2(second=1) - 1 - >>> raw2() - 0 - -========= test export of operators ========== - - >>> i = Int(2) - >>> j = i+i - >>> j.i() - 4 - >>> j = i-i - >>> j.i() - 0 - >>> j = i*i - >>> j.i() - 4 - >>> i>> cmp(i,i) - 0 - >>> k = Int(5) - >>> j = divmod(k, i) - >>> j[0].i() - 2 - >>> j[1].i() - 1 - >>> j = pow(i, k) - >>> j.i() - 32 - >>> j = pow(i, k, k) - >>> j.i() - 2 - >>> j = -i - >>> j.i() - -2 - >>> str(i) - '2' - >>> try: j = i/i - ... except TypeError, err: - ... assert re.match(r'(bad|unsupported) operand type\(s\) for /', - ... str(err)) - ... else: print 'no exception' - - >>> j = abs(i) - Traceback (innermost last): - TypeError: bad operand type for abs() - >>> j = i+1 - >>> j.i() - 3 - >>> j = i-1 - >>> j.i() - 1 - >>> j = i*1 - >>> j.i() - 2 - >>> i<1 - 0 - >>> cmp(i,1) - 1 - >>> j = pow(i, 5) - >>> j.i() - 32 - >>> j = pow(i, 5, k) - Traceback (innermost last): - TypeError: bad operand type(s) for pow() - >>> j = pow(i, 5, 5) - Traceback (innermost last): - TypeError: bad operand type(s) for pow() - >>> j = i/1 - Traceback (innermost last): - TypeError: bad operand type(s) for / - >>> j = 1+i - >>> j.i() - 3 - >>> j = 1-i - >>> j.i() - -1 - >>> j = 1*i - >>> j.i() - 2 - >>> 1>> cmp(1,i) - -1 - >>> j = 1/i - Traceback (innermost last): - TypeError: bad operand type(s) for / - >>> pow(1,i) - Traceback (innermost last): - TypeError: bad operand type(s) for pow() - -Test operator export to a subclass - - # force method table sharing - >>> class IntDerived1(Int): pass - ... - - >>> class IntDerived(Int): - ... def __init__(self, i): - ... Int.__init__(self, i) - ... def __str__(self): - ... return 'IntDerived: ' + str(self.i()) - ... - >>> f = IntDerived(3) - >>> str(f) - 'IntDerived: 3' - >>> j = f * f - >>> j.i() - 9 - >>> j = f * i - >>> j.i() - 6 - >>> j = f * 5 - >>> j.i() - 15 - >>> j = i * f - >>> j.i() - 6 - >>> j = 5 * f - >>> j.i() - 15 - - -========= Prove that the "phantom base class" issue is resolved ========== - - >>> assert pa1_a1.__class__ == A1 - >>> assert pb1_a1.__class__ == A1 - >>> assert pb2_a1.__class__ == A1 - >>> assert pc_a1.__class__ == A1 - >>> assert pa2_a2.__class__ == A2 - >>> assert pb1_a2.__class__ == A2 - >>> assert pb1_b1.__class__ == B1 - >>> assert pc_b1.__class__ == B1 - >>> assert A1 in B1.__bases__ - >>> assert A2 in B1.__bases__ - >>> assert A1 in B2.__bases__ - >>> assert A2 in B2.__bases__ - >>> assert A1 in DA1.__bases__ - >>> assert B1 in DB1.__bases__ - >>> assert B2 in DB2.__bases__ - -=============================================================== -test methodologies for wrapping functions that return a pointer - - >>> get_record().value - 1234 - - In this methodology, the referent is copied - >>> get_record() == get_record() - 0 - -======== Enums and non-method class attributes ============== - >>> eo = EnumOwner(EnumOwner.one, EnumOwner.two) - >>> eo.first - 1 - >>> eo.second - 2 - >>> eo.first = EnumOwner.three - >>> eo.second = EnumOwner.one - >>> eo.first - 3 - >>> eo.second - 1 - -======== test [plain] char converters ============== - >>> get_plain_char() - 'x' - >>> use_plain_char('a') - 'aaa' - >>> use_const_plain_char('b') - 'bbbbb' - -======== test std::complex converters ============== - >>> c = dpolar(3, 5) - >>> type(c) - - >>> '%.3g' % (dreal(c)) - '0.851' - >>> '%.3g' % (dimag(c)) - '-2.88' - >>> '%.3g' % (freal(c)) - '0.851' - >>> '%.3g' % (fimag(c)) - '-2.88' - >>> c = fpolar(7, 13) - >>> type(c) - - >>> '%.3g' % (fimag(c)) - '2.94' - >>> '%.3g' % (freal(c)) - '6.35' - >>> '%.3g' % (dimag(c)) - '2.94' - >>> '%.3g' % (dreal(c)) - '6.35' - >>> '%.3g' % (dreal(3)) - '3' - >>> '%.3g' % (dreal(3L)) - '3' - >>> '%.3g' % (dreal(3.)) - '3' - >>> '%.3g' % (freal(3)) - '3' - >>> '%.3g' % (freal(3L)) - '3' - >>> '%.3g' % (freal(3.)) - '3' - -''' -#' - -__test__ = {} -import sys - -# Inplace ops only exist in python 2.1 or later. -if sys.hexversion >= 0x02010000: - __test__['inplacetests'] = r''' - >>> ii = Int(1) - >>> ii += Int(2) - >>> ii.i() - 3 - >>> ii -= Int(1) - >>> ii.i() - 2 - >>> ii *= Int(3) - >>> ii.i() - 6 - >>> ii /= Int(2) - >>> ii.i() - 3 - >>> ii <<= Int(2) - >>> ii.i() - 12 - >>> ii >>= Int(1) - >>> ii.i() - 6 - >>> ii &= Int(5) - >>> ii.i() - 4 - >>> ii |= Int(9) - >>> ii.i() - 13 - >>> ii ^= Int(7) - >>> ii.i() - 10 - >>> ii %= Int(4) - >>> ii.i() - 2 - >>> ii **= Int(3) - >>> ii.i() - 8 - >>> ii.j() - 11 -''' - -from boost_python_test import * - -# pickle requires these derived classes to be -# at the global scope of the module - -class myrational(Rational): - __dict_defines_state__ = 1 # this is a lie but good enough for testing. - -class myworld(world): - def __init__(self): - world.__init__(self, 'anywhere') - self.x = 1 - -class myunsafeworld(myworld): - __getstate_manages_dict__ = 1 # this is a lie but good enough for testing. - - -def assert_integer_expected(err): - """Handle a common error report which appears differently in Python 1.5.x and 2.0""" - assert isinstance(err, TypeError) - message = str(err) - assert (message == "illegal argument type for built-in operation" - or message == "an integer is required") - -import string -import re -import sys - -def run(args = None): - if args is not None: - sys.argv = args - import doctest, comprehensive - return doctest.testmod(comprehensive) - -if __name__ == '__main__': - sys.exit(run()[0]) diff --git a/test/doctest.py b/test/doctest.py deleted file mode 100644 index 248da82a..00000000 --- a/test/doctest.py +++ /dev/null @@ -1,1112 +0,0 @@ -# Module doctest version 0.9.4 -# Released to the public domain 27-Mar-1999, -# by Tim Peters (tim_one@email.msn.com). - -# Provided as-is; use at your own risk; no warranty; no promises; enjoy! - -"""module_builder doctest -- a framework for running examples in docstrings. - -NORMAL USAGE - -In normal use, end each module M with: - -def _test(): - import doctest, M # replace M with your module's name - return doctest.testmod(M) # ditto - -if __name__ == "__main__": - _test() - -Then running the module as a script will cause the examples in the -docstrings to get executed and verified: - -python M.python - -This won't display anything unless an example fails, in which case -the failing example(s) and the cause(s) of the failure(s) are printed -to stdout (why not stderr? because stderr is a lame hack <0.2 wink>), -and the final line of output is "Test failed.". - -Run it with the -v switch instead: - -python M.python -v - -and a detailed report of all examples tried is printed to stdout, along -with assorted summaries at the end. - -You can force verbose mode by passing "verbose=1" to testmod, or prohibit -it by passing "verbose=0". In either of those cases, sys.argv is not -examined by testmod. - -In any case, testmod returns a 2-tuple of ints (f, t), where f is the -number of docstring examples that failed and t is the total number of -docstring examples attempted. - - -WHICH DOCSTRINGS ARE EXAMINED? - -+ M.__doc__. - -+ f.__doc__ for all functions f in M.__dict__.values(), except those - with private names. - -+ C.__doc__ for all classes C in M.__dict__.values(), except those with - private names. - -+ If M.__test__ exists and "is true", it must be a dict, and - each entry maps a (string) name to a function object, class object, or - string. function and class object docstrings found from M.__test__ - are searched even if the name is private, and strings are searched - directly as if they were docstrings. In output, a key K in M.__test__ - appears with name - .__test__.K - -Any classes found are recursively searched similarly, to test docstrings -in their contained methods and nested classes. Private names reached -from M's globals are skipped, but all names reached from M.__test__ are -searched. - -By default, a name is considered to be private if it begins with an -underscore (like "_my_func") but doesn't both begin and end with (at -least) two underscores (like "__init__"). You can change the default -by passing your own "isprivate" function to testmod. - -If you want to test docstrings in objects with private names too, stuff -them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your -own isprivate function to Tester's constructor, or call the rundoc method -of a Tester obj). - -Warning: imports can cause trouble; e.g., if you do - -from XYZ import XYZclass - -then XYZclass is a name in M.__dict__ too, and doctest has no way to -know that XYZclass wasn't *defined* in M. So it may try to execute the -examples in XYZclass's docstring, and those in turn may require a -different set of globals to work correctly. I prefer to do "import *"- -friendly imports, a la - -import XYY -_XYZclass = XYZ.XYZclass -del XYZ - -and then the leading underscore stops testmod from going nuts. You may -prefer the method in the next section. - - -WHAT'S THE EXECUTION CONTEXT? - -By default, each time testmod finds a docstring to test, it uses a -*copy* of M's globals (so that running tests on a module doesn't change -the module's real globals, and so that one test in M can't leave behind -crumbs that accidentally allow another test to work). This means -examples can freely use any names defined at top-level in M. It also -means that sloppy imports (see above) can cause examples in external -docstrings to use globals inappropriate for them. - -You can force use of your own dict as the execution context by passing -"globs=your_dict" to testmod instead. Presumably this would be a copy -of M.__dict__ merged with the globals from other imported modules. - - -WHAT IF I WANT TO TEST A WHOLE PACKAGE? - -Piece o' cake, provided the modules do their testing from docstrings. -Here's the test.python I use for the world's most elaborate Rational/ -floating-base-conversion pkg (which I'll distribute some day): - -from Rational import Cvt -from Rational import Format -from Rational import machprec -from Rational import Rat -from Rational import Round -from Rational import utils - -modules = (Cvt, - Format, - machprec, - Rat, - Round, - utils) - -def _test(): - import doctest - import sys - verbose = "-v" in sys.argv - for mod in modules: - doctest.testmod(mod, verbose=verbose, report=0) - doctest.master.summarize() - -if __name__ == "__main__": - _test() - -IOW, it just runs testmod on all the pkg modules. testmod remembers the -names and outcomes (# of failures, # of tries) for each item it's seen, -and passing "report=0" prevents it from printing a summary in verbose -mode. Instead, the summary is delayed until all modules have been -tested, and then "doctest.master.summarize()" forces the summary at the -end. - -So this is very nice in practice: each module can be tested individually -with almost no work beyond writing up docstring examples, and collections -of modules can be tested too as a unit with no more work than the above. - - -WHAT ABOUT EXCEPTIONS? - -No problem, as long as the only output generated by the example is the -traceback itself. For example: - - >>> 1/0 - Traceback (innermost last): - File "", line 1, in ? - ZeroDivisionError: integer division or modulo - >>> - -Note that only the exception type and value are compared (specifically, -only the last line in the traceback). - - -ADVANCED USAGE - -doctest.testmod() captures the testing policy I find most useful most -often. You may want other policies. - -testmod() actually creates a local obj of class doctest.Tester, -runs appropriate methods of that class, and merges the results into -global Tester obj doctest.master. - -You can create your own instances of doctest.Tester, and so build your -own policies, or even run methods of doctest.master directly. See -doctest.Tester.__doc__ for details. - - -SO WHAT DOES A DOCSTRING EXAMPLE LOOK LIKE ALREADY!? - -Oh ya. It's easy! In most cases a copy-and-paste of an interactive -console session works fine -- just make sure the leading whitespace -is rigidly consistent (you can mix tabs and spaces if you're too lazy -to do it right, but doctest is not in the business of guessing what -you think a tab means). - - >>> # comments are ignored - >>> x = 12 - >>> x - 12 - >>> if x == 13: - ... print "yes" - ... else: - ... print "no" - ... print "NO" - ... print "NO!!!" - ... - no - NO - NO!!! - >>> - -Any expected output must immediately follow the final ">>>" or "..." -line containing the code, and the expected output (if any) extends -to the next ">>>" or all-whitespace line. That's it. - -Bummers: - -+ Expected output cannot contain an all-whitespace line, since such a - line is taken to signal the end of expected output. - -+ Output to stdout is captured, but not output to stderr (exception - tracebacks are captured via a different means). - -+ If you continue a line via backslashing in an interactive session, - or for any other reason use a backslash, you need to double the - backslash in the docstring version. This is simply because you're - in a string, and so the backslash must be escaped for it to survive - intact. Like: - ->>> if "yes" == \\ -... "y" + \\ -... "es": # in the source code you'll see the doubled backslashes -... print 'yes' -yes - -The starting column doesn't matter: - ->>> assert "Easy!" - >>> import math - >>> math.floor(1.9) - 1.0 - -and as many leading whitespace characters are stripped from the expected -output as appeared in the initial ">>>" line that triggered it. - -If you execute this very file, the examples above will be found and -executed, leading to this output in verbose mode: - -Running doctest.__doc__ -Trying: 1/0 -Expecting: -Traceback (innermost last): - File "", line 1, in ? -ZeroDivisionError: integer division or modulo -ok -Trying: x = 12 -Expecting: nothing -ok -Trying: x -Expecting: 12 -ok -Trying: -if x == 13: - print "yes" -else: - print "no" - print "NO" - print "NO!!!" -Expecting: -no -NO -NO!!! -ok -... and a bunch more like that, with this summary at the end: - -5 items had no tests: - doctest.Tester.__init__ - doctest.Tester.run__test__ - doctest.Tester.summarize - doctest.run_docstring_examples - doctest.testmod -12 items passed all tests: - 8 tests in doctest - 6 tests in doctest.Tester - 10 tests in doctest.Tester.merge - 7 tests in doctest.Tester.rundict - 3 tests in doctest.Tester.rundoc - 3 tests in doctest.Tester.runstring - 2 tests in doctest.__test__._TestClass - 2 tests in doctest.__test__._TestClass.__init__ - 2 tests in doctest.__test__._TestClass.get - 1 tests in doctest.__test__._TestClass.square - 2 tests in doctest.__test__.string - 7 tests in doctest.is_private -53 tests in 17 items. -53 passed and 0 failed. -Test passed. -""" - -# 0,0,1 06-Mar-1999 -# initial version posted -# 0,0,2 06-Mar-1999 -# loosened parsing: -# cater to stinkin' tabs -# don't insist on a blank after PS2 prefix -# so trailing "... " line from a compound stmt no longer -# breaks if the file gets whitespace-trimmed -# better error msgs for inconsistent leading whitespace -# 0,9,1 08-Mar-1999 -# exposed the Tester class and added client methods -# plus docstring examples of their use (eww - head-twisting!) -# fixed logic error in reporting total # of tests & failures -# added __test__ support to testmod (a pale reflection of Christian -# Tismer's vision ...) -# removed the "deep" argument; fiddle __test__ instead -# simplified endcase logic for extracting tests, and running them. -# before, if no output was expected but some was produced -# anyway via an eval'ed result, the discrepancy wasn't caught -# made TestClass private and used __test__ to get at it -# many doc updates -# speed _SpoofOut for long expected outputs -# 0,9,2 09-Mar-1999 -# throw out comments from examples, enabling use of the much simpler -# exec compile(... "single") ... -# for simulating the runtime; that barfs on comment-only lines -# used the traceback module to do a much better job of reporting -# exceptions -# run __doc__ values thru str(), "just in case" -# privateness of names now determined by an overridable "isprivate" -# function -# by default a name now considered to be private iff it begins with -# an underscore but doesn't both begin & end with two of 'em; so -# e.g. class_t.__init__ etc are searched now -- as they always -# should have been -# 0,9,3 18-Mar-1999 -# added .flush stub to _SpoofOut (JPython buglet diagnosed by -# Hugh Emberson) -# repaired ridiculous docs about backslashes in examples -# minor internal changes -# changed source to Unix line-end conventions -# moved __test__ logic into new Tester.run__test__ method -# 0,9,4 27-Mar-1999 -# report item name and line # in failing examples -# 0,9,5 29-Jun-1999 -# allow straightforward exceptions in examples - thanks to Mark Hammond! -# 0,9,5,1 31-Mar-2000 -# break cyclic references to functions which are defined in docstrings, -# avoiding cyclic trash -# 0,9,5,2 11-Apr-2000 -# made module argument to testmod optional; it runs testmod on the __main__ -# module in that case. - -__version__ = 0, 9, 5 - -import types -_FunctionType = types.FunctionType -_ClassType = types.ClassType -_ModuleType = types.ModuleType -_StringType = types.StringType -del types - -import string -_string_find = string.find -_string_join = string.join -_string_split = string.split -_string_rindex = string.rindex -del string - -import re -PS1 = ">>>" -PS2 = "..." -_isPS1 = re.compile(r"(\s*)" + re.escape(PS1)).match -_isPS2 = re.compile(r"(\s*)" + re.escape(PS2)).match -_isEmpty = re.compile(r"\s*$").match -_isComment = re.compile(r"\s*#").match -del re - -# Extract interactive examples from a string. Return a list of triples, -# (source, outcome, lineno). "source" is the source code, and ends -# with a newline iff the source spans more than one line. "outcome" is -# the expected output if any, else an empty string. When not empty, -# outcome always ends with a newline. "lineno" is the line number, -# 0-based wrt the start of the string, of the first source line. - -def _extract_examples(s): - isPS1, isPS2 = _isPS1, _isPS2 - isEmpty, isComment = _isEmpty, _isComment - examples = [] - lines = _string_split(s, "\n") - i, n = 0, len(lines) - while i < n: - line = lines[i] - i = i + 1 - m = isPS1(line) - if m is None: - continue - j = m.end(0) # beyond the prompt - if isEmpty(line, j) or isComment(line, j): - # a bare prompt or comment -- not interesting - continue - lineno = i - 1 - if line[j] != " ": - raise ValueError("line " + `lineno` + " of docstring lacks " - "blank after " + PS1 + ": " + line) - j = j + 1 - blanks = m.group(1) - nblanks = len(blanks) - # suck up this and following PS2 lines - source = [] - while 1: - source.append(line[j:]) - line = lines[i] - m = isPS2(line) - if m: - if m.group(1) != blanks: - raise ValueError("inconsistent leading whitespace " - "in line " + `i` + " of docstring: " + line) - i = i + 1 - else: - break - if len(source) == 1: - source = source[0] - else: - # get rid of useless null line from trailing empty "..." - if source[-1] == "": - del source[-1] - source = _string_join(source, "\n") + "\n" - # suck up response - if isPS1(line) or isEmpty(line): - expect = "" - else: - expect = [] - while 1: - if line[:nblanks] != blanks: - raise ValueError("inconsistent leading whitespace " - "in line " + `i` + " of docstring: " + line) - expect.append(line[nblanks:]) - i = i + 1 - line = lines[i] - if isPS1(line) or isEmpty(line): - break - expect = _string_join(expect, "\n") + "\n" - examples.append( (source, expect, lineno) ) - return examples - -# Capture stdout when running examples. - -class _SpoofOut: - def __init__(self): - self.clear() - def write(self, s): - self.buf.append(s) - def get(self): - return _string_join(self.buf, "") - def clear(self): - self.buf = [] - def flush(self): - # JPython calls flush - pass - -# Display some tag-and-msg pairs nicely, keeping the tag and its msg -# on the same line when that makes sense. - -def _tag_out(printer, *tag_msg_pairs): - for tag, msg in tag_msg_pairs: - printer(tag + ":") - msg_has_nl = msg[-1:] == "\n" - msg_has_two_nl = msg_has_nl and \ - _string_find(msg, "\n") < len(msg) - 1 - if len(tag) + len(msg) < 76 and not msg_has_two_nl: - printer(" ") - else: - printer("\n") - printer(msg) - if not msg_has_nl: - printer("\n") - -# Run list of examples, in context globs. "out" can be used to display -# stuff to "the real" stdout, and fakeout is an obj of _SpoofOut -# that captures the examples' std output. Return (#failures, #tries). - -def _run_examples_inner(out, fakeout, examples, globs, verbose, name): - import sys, traceback - OK, BOOM, FAIL = range(3) - NADA = "nothing" - stderr = _SpoofOut() - failures = 0 - for source, want, lineno in examples: - if verbose: - _tag_out(out, ("Trying", source), - ("Expecting", want or NADA)) - fakeout.clear() - try: - exec compile(source, "", "single") in globs - got = fakeout.get() - state = OK - except: - # See whether the exception was expected. - if _string_find(want, "Traceback (innermost last):\n") == 0: - # Only compare exception type and value - the rest of - # the traceback isn't necessary. - want = _string_split(want, '\n')[-2] + '\n' - exc_type, exc_val, exc_tb = sys.exc_info() - got = traceback.format_exception_only(exc_type, exc_val)[0] - state = OK - else: - # unexpected exception - stderr.clear() - traceback.print_exc(file=stderr) - state = BOOM - - if state == OK: - if got == want: - if verbose: - out("ok\n") - continue - state = FAIL - - assert state in (FAIL, BOOM) - failures = failures + 1 - out("*" * 65 + "\n") - _tag_out(out, ("Failure in example", source)) - out("from line #" + `lineno` + " of " + name + "\n") - if state == FAIL: - _tag_out(out, ("Expected", want or NADA), ("Got", got)) - else: - assert state == BOOM - _tag_out(out, ("Exception raised", stderr.get())) - return failures, len(examples) - -# Run list of examples, in context globs. Return (#failures, #tries). - -def _run_examples(examples, globs, verbose, name): - import sys - saveout = sys.stdout - try: - sys.stdout = fakeout = _SpoofOut() - x = _run_examples_inner(saveout.write, fakeout, examples, - globs, verbose, name) - finally: - sys.stdout = saveout - return x - -def run_docstring_examples(f, globs, verbose=0, name="NoName"): - """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__. - - Use dict globs as the globals for execution. - Return (#failures, #tries). - - If optional arg verbose is true, print stuff even if there are no - failures. - Use string name in failure msgs. - """ - - try: - doc = f.__doc__ - if not doc: - # docstring empty or None - return 0, 0 - # just in case CT invents a doc object that has to be forced - # to look like a string <0.9 wink> - doc = str(doc) - except: - return 0, 0 - - e = _extract_examples(doc) - if not e: - return 0, 0 - return _run_examples(e, globs, verbose, name) - -def is_private(prefix, base): - """prefix, base -> true iff name prefix + "." + base is "private". - - Prefix may be an empty string, and base does not contain a period. - Prefix is ignored (although functions you write conforming to this - protocol may make use of it). - Return true iff base begins with an (at least one) underscore, but - does not both begin and end with (at least) two underscores. - - >>> is_private("a.b", "my_func") - 0 - >>> is_private("____", "_my_func") - 1 - >>> is_private("someclass", "__init__") - 0 - >>> is_private("sometypo", "__init_") - 1 - >>> is_private("x.y.z", "_") - 1 - >>> is_private("_x.y.z", "__") - 0 - >>> is_private("", "") # senseless but consistent - 0 - """ - - return base[:1] == "_" and not base[:2] == "__" == base[-2:] - -class Tester: - """class_t Tester -- runs docstring examples and accumulates stats. - -In normal use, function doctest.testmod() hides all this from you, -so use that if you can. Create your own instances of Tester to do -fancier things. - -Methods: - runstring(s, name) - Search string s for examples to run; use name for logging. - Return (#failures, #tries). - - rundoc(object, name=None) - Search object.__doc__ for examples to run; use name (or - object.__name__) for logging. Return (#failures, #tries). - - rundict(d, name) - Search for examples in docstrings in all of d.values(); use name - for logging. Return (#failures, #tries). - - run__test__(d, name) - Treat dict d like module.__test__. Return (#failures, #tries). - - summarize(verbose=None) - Display summary of testing results, to stdout. Return - (#failures, #tries). - - merge(other) - Merge in the test results from Tester obj "other". - ->>> from doctest import Tester ->>> t = Tester(globs={'x': 42}, verbose=0) ->>> t.runstring(r''' -... >>> x = x * 2 -... >>> print x -... 42 -... ''', 'XYZ') -***************************************************************** -Failure in example: print x -from line #2 of XYZ -Expected: 42 -Got: 84 -(1, 2) ->>> t.runstring(">>> x = x * 2\\n>>> print x\\n84\\n", 'example2') -(0, 2) ->>> t.summarize() -1 items had failures: - 1 of 2 in XYZ -***Test Failed*** 1 failures. -(1, 4) ->>> t.summarize(verbose=1) -1 items passed all tests: - 2 tests in example2 -1 items had failures: - 1 of 2 in XYZ -4 tests in 2 items. -3 passed and 1 failed. -***Test Failed*** 1 failures. -(1, 4) ->>> -""" - - def __init__(self, mod=None, globs=None, verbose=None, - isprivate=None): - """mod=None, globs=None, verbose=None, isprivate=None - -See doctest.__doc__ for an overview. - -Optional keyword arg "mod" is a module, whose globals are used for -executing examples. If not specified, globs must be specified. - -Optional keyword arg "globs" gives a dict to be used as the globals -when executing examples; if not specified, use the globals from -module mod. - -In either case, a copy of the dict is used for each docstring -examined. - -Optional keyword arg "verbose" prints lots of stuff if true, only -failures if false; by default, it's true iff "-v" is in sys.argv. - -Optional keyword arg "isprivate" specifies a function used to determine -whether a name is private. The default function is doctest.is_private; -see its docs for details. -""" - - if mod is None and globs is None: - raise TypeError("Tester.__init__: must specify mod or globs") - if mod is not None and type(mod) is not _ModuleType: - raise TypeError("Tester.__init__: mod must be a module; " + - `mod`) - if globs is None: - globs = mod.__dict__ - self.globs = globs - - if verbose is None: - import sys - verbose = "-v" in sys.argv - self.verbose = verbose - - if isprivate is None: - isprivate = is_private - self.isprivate = isprivate - - self.name2ft = {} # map name to (#failures, #trials) pair - - def runstring(self, s, name): - """ - s, name -> search string s for examples to run, logging as name. - - Use string name as the key for logging the outcome. - Return (#failures, #examples). - - >>> t = Tester(globs={}, verbose=1) - >>> test = r''' - ... # just an example - ... >>> x = 1 + 2 - ... >>> x - ... 3 - ... ''' - >>> t.runstring(test, "Example") - Running string Example - Trying: x = 1 + 2 - Expecting: nothing - ok - Trying: x - Expecting: 3 - ok - 0 of 2 examples failed in string Example - (0, 2) - """ - - if self.verbose: - print "Running string", name - f = t = 0 - e = _extract_examples(s) - if e: - globs = self.globs.copy() - f, t = _run_examples(e, globs, self.verbose, name) - globs.clear() # DWA - break cyclic references to functions defined in docstrings - if self.verbose: - print f, "of", t, "examples failed in string", name - self.__record_outcome(name, f, t) - return f, t - - def rundoc(self, object, name=None): - """ - object, name=None -> search object.__doc__ for examples to run. - - Use optional string name as the key for logging the outcome; - by default use object.__name__. - Return (#failures, #examples). - If object is a class object, search recursively for method - docstrings too. - object.__doc__ is examined regardless of name, but if object is - a class, whether private names reached from object are searched - depends on the constructor's "isprivate" argument. - - >>> t = Tester(globs={}, verbose=0) - >>> def _f(): - ... '''Trivial docstring example. - ... >>> assert 2 == 2 - ... ''' - ... return 32 - ... - >>> t.rundoc(_f) # expect 0 failures in 1 example - (0, 1) - """ - - if name is None: - try: - name = object.__name__ - except AttributeError: - raise ValueError("Tester.rundoc: name must be given " - "when object.__name__ doesn't exist; " + `object`) - if self.verbose: - print "Running", name + ".__doc__" - globs = self.globs.copy() - f, t = run_docstring_examples(object, globs, - self.verbose, name) - globs.clear() # DWA - break cyclic references to functions defined in docstrings - - if self.verbose: - print f, "of", t, "examples failed in", name + ".__doc__" - self.__record_outcome(name, f, t) - if type(object) is _ClassType: - f2, t2 = self.rundict(object.__dict__, name) - f = f + f2 - t = t + t2 - return f, t - - def rundict(self, d, name): - """ - d. name -> search for docstring examples in all of d.values(). - - For k, v in d.items() such that v is a function or class, - do self.rundoc(v, name + "." + k). Whether this includes - objects with private names depends on the constructor's - "isprivate" argument. - Return aggregate (#failures, #examples). - - >>> def _f(): - ... '''>>> assert 1 == 1 - ... ''' - >>> def g(): - ... '''>>> assert 2 != 1 - ... ''' - >>> d = {"_f": _f, "g": g} - >>> t = Tester(globs={}, verbose=0) - >>> t.rundict(d, "rundict_test") # _f is skipped - (0, 1) - >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) - >>> t.rundict(d, "rundict_test_pvt") # both are searched - (0, 2) - """ - - if not hasattr(d, "items"): - raise TypeError("Tester.rundict: d must support .items(); " + - `d`) - f = t = 0 - for thisname, value in d.items(): - if type(value) in (_FunctionType, _ClassType): - f2, t2 = self.__runone(value, name + "." + thisname) - f = f + f2 - t = t + t2 - return f, t - - def run__test__(self, d, name): - """d, name -> Treat dict d like module.__test__. - - Return (#failures, #tries). - See testmod.__doc__ for details. - """ - - failures = tries = 0 - prefix = name + "." - savepvt = self.isprivate - try: - self.isprivate = lambda *args: 0 - for k, v in d.items(): - thisname = prefix + k - if type(v) is _StringType: - f, t = self.runstring(v, thisname) - elif type(v) in (_FunctionType, _ClassType): - f, t = self.rundoc(v, thisname) - else: - raise TypeError("Tester.run__test__: values in " - "dict must be strings, functions " - "or classes; " + `v`) - failures = failures + f - tries = tries + t - finally: - self.isprivate = savepvt - return failures, tries - - def summarize(self, verbose=None): - """ - verbose=None -> summarize results, return (#failures, #tests). - - Print summary of test results to stdout. - Optional arg 'verbose' controls how wordy this is. By - default, use the verbose setting established by the - constructor. - """ - - if verbose is None: - verbose = self.verbose - notests = [] - passed = [] - failed = [] - totalt = totalf = 0 - for x in self.name2ft.items(): - name, (f, t) = x - assert f <= t - totalt = totalt + t - totalf = totalf + f - if t == 0: - notests.append(name) - elif f == 0: - passed.append( (name, t) ) - else: - failed.append(x) - if verbose: - if notests: - print len(notests), "items had no tests:" - notests.sort() - for thing in notests: - print " ", thing - if passed: - print len(passed), "items passed all tests:" - passed.sort() - for thing, count in passed: - print " %3d tests in %s" % (count, thing) - if failed: - print len(failed), "items had failures:" - failed.sort() - for thing, (f, t) in failed: - print " %3d of %3d in %s" % (f, t, thing) - if verbose: - print totalt, "tests in", len(self.name2ft), "items." - print totalt - totalf, "passed and", totalf, "failed." - if totalf: - print "***Test Failed***", totalf, "failures." - elif verbose: - print "Test passed." - return totalf, totalt - - def merge(self, other): - """ - other -> merge in test results from the other Tester obj. - - If self and other both have a test result for something - with the same name, the (#failures, #tests) results are - summed, and a warning is printed to stdout. - - >>> from doctest import Tester - >>> t1 = Tester(globs={}, verbose=0) - >>> t1.runstring(''' - ... >>> x = 12 - ... >>> print x - ... 12 - ... ''', "t1example") - (0, 2) - >>> - >>> t2 = Tester(globs={}, verbose=0) - >>> t2.runstring(''' - ... >>> x = 13 - ... >>> print x - ... 13 - ... ''', "t2example") - (0, 2) - >>> common = ">>> assert 1 + 2 == 3\\n" - >>> t1.runstring(common, "common") - (0, 1) - >>> t2.runstring(common, "common") - (0, 1) - >>> t1.merge(t2) - *** Tester.merge: 'common' in both testers; summing outcomes. - >>> t1.summarize(1) - 3 items passed all tests: - 2 tests in common - 2 tests in t1example - 2 tests in t2example - 6 tests in 3 items. - 6 passed and 0 failed. - Test passed. - (0, 6) - >>> - """ - - d = self.name2ft - for name, (f, t) in other.name2ft.items(): - if d.has_key(name): - print "*** Tester.merge: '" + name + "' in both" \ - " testers; summing outcomes." - f2, t2 = d[name] - f = f + f2 - t = t + t2 - d[name] = f, t - - def __record_outcome(self, name, f, t): - if self.name2ft.has_key(name): - print "*** Warning: '" + name + "' was tested before;", \ - "summing outcomes." - f2, t2 = self.name2ft[name] - f = f + f2 - t = t + t2 - self.name2ft[name] = f, t - - def __runone(self, target, name): - if "." in name: - i = _string_rindex(name, ".") - prefix, base = name[:i], name[i+1:] - else: - prefix, base = "", base - if self.isprivate(prefix, base): - return 0, 0 - return self.rundoc(target, name) - -master = None - -def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None, - report=1): - """m=None, name=None, globs=None, verbose=None, isprivate=None, report=1 - - Test examples in docstrings in functions and classes reachable from - module m, starting with m.__doc__. Private names are skipped. - - Also test examples reachable from dict m.__test__ if it exists and is - not None. m.__dict__ maps names to functions, classes and strings; - function and class docstrings are tested even if the name is private; - strings are tested directly, as if they were docstrings. - - Return (#failures, #tests). - - See doctest.__doc__ for an overview. - - Optional keyword arg "name" gives the name of the module; by default - use m.__name__. - - Optional keyword arg "globs" gives a dict to be used as the globals - when executing examples; by default, use m.__dict__. A copy of this - dict is actually used for each docstring, so that each docstring's - examples start with a clean slate. - - Optional keyword arg "verbose" prints lots of stuff if true, prints - only failures if false; by default, it's true iff "-v" is in sys.argv. - - Optional keyword arg "isprivate" specifies a function used to - determine whether a name is private. The default function is - doctest.is_private; see its docs for details. - - Optional keyword arg "report" prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else very brief (in fact, empty if all tests passed). - - Advanced tomfoolery: testmod runs methods of a local obj of - class doctest.Tester, then merges the results into (or creates) - global Tester obj doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. - Passing report=0 to testmod is especially useful then, to delay - displaying a summary. Invoke doctest.master.summarize(verbose) - when you're done fiddling. - """ - - global master - - if m is None: - import sys - # DWA - m will still be None if this wasn't invoked from the command - # line, in which case the following TypeError is about as good an error - # as we should expect - m = sys.modules.get('__main__') - - if type(m) is not _ModuleType: - raise TypeError("testmod: module required; " + `m`) - if name is None: - name = m.__name__ - tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate) - failures, tries = tester.rundoc(m, name) - f, t = tester.rundict(m.__dict__, name) - failures = failures + f - tries = tries + t - if hasattr(m, "__test__"): - testdict = m.__test__ - if testdict: - if not hasattr(testdict, "items"): - raise TypeError("testmod: module.__test__ must support " - ".items(); " + `testdict`) - f, t = tester.run__test__(testdict, name + ".__test__") - failures = failures + f - tries = tries + t - if report: - tester.summarize() - if master is None: - master = tester - else: - master.merge(tester) - return failures, tries - -class _TestClass: - """ - A pointless class, for sanity-checking of docstring testing. - - Methods: - square() - get() - - >>> _TestClass(13).get() + _TestClass(-12).get() - 1 - >>> hex(_TestClass(13).square().get()) - '0xa9' - """ - - def __init__(self, val): - """val -> _TestClass object with associated value val. - - >>> t = _TestClass(123) - >>> print t.get() - 123 - """ - - self.val = val - - def square(self): - """square() -> square TestClass's associated value - - >>> _TestClass(13).square().get() - 169 - """ - - self.val = self.val ** 2 - return self - - def get(self): - """get() -> return TestClass's associated value. - - >>> x = _TestClass(-42) - >>> print x.get() - -42 - """ - - return self.val - -__test__ = {"_TestClass": _TestClass, - "string": r""" - Example of a string object, searched as-is. - >>> x = 1; y = 2 - >>> x + y, x * y - (3, 2) - """ - } - -def _test(): - import doctest - return doctest.testmod(doctest) - -if __name__ == "__main__": - _test() diff --git a/test/m1.cpp b/test/m1.cpp deleted file mode 100644 index b42742ab..00000000 --- a/test/m1.cpp +++ /dev/null @@ -1,284 +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. - - -#include "simple_type.hpp" -#include "complicated.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Declare some straightforward extension types -extern "C" void -dealloc(PyObject* self) -{ - PyObject_Del(self); -} - -// Noddy is a type we got from one of the Python sample files -struct NoddyObject : PyObject -{ - int x; -}; - -PyTypeObject NoddyType = { - PyObject_HEAD_INIT(NULL) - 0, - "Noddy", - sizeof(NoddyObject), - 0, - dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -// Create a Noddy containing 42 -PyObject* new_noddy() -{ - NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType); - noddy->x = 42; - return (PyObject*)noddy; -} - -// Simple is a wrapper around a struct simple, which just contains a char* -struct SimpleObject -{ - PyObject_HEAD - simple x; -}; - -struct extract_simple_object -{ - static simple& execute(SimpleObject& o) { return o.x; } -}; - -PyTypeObject SimpleType = { - PyObject_HEAD_INIT(NULL) - 0, - "Simple", - sizeof(SimpleObject), - 0, - dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -// Create a Simple containing "hello, world" -PyObject* new_simple() -{ - SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType); - simple->x.s = "hello, world"; - return (PyObject*)simple; -} - -// -// Declare some wrappers/unwrappers to test the low-level conversion -// mechanism. See boost/python/converter/source.hpp,target.hpp for a -// description of how the type parameters to wrapper<> and unwrapper<> -// are selected. -// -using boost::python::converter::from_python_data; -using boost::python::to_python_converter; - -// Wrap a simple by copying it into a Simple -struct simple_to_python - : to_python_converter -{ - static PyObject* convert(simple const& x) - { - SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); - p->x = x; - return (PyObject*)p; - } -}; - -int noddy_to_int(PyObject* p, from_python_data&) -{ - return static_cast(p)->x; -} - -// Extract a mutable reference to an int from a Noddy. -int& noddy_to_int_ref(PyObject* p, from_python_data&) -{ - return static_cast(p)->x; -} - -// -// Some C++ functions to expose to Python -// - -// Returns the length of s's held string -int f(simple const& s) -{ - return strlen(s.s); -} - -// A trivial passthru function for simple objects -simple const& g(simple const& x) -{ - return x; -} - -struct A -{ - A() : x(0) {} - virtual ~A() {} - char const* name() { return "A"; } - int x; -}; - -struct B : A -{ - B() : x(1) {} - char const* name() { return "B"; } - int x; -}; - - -struct C : A -{ - C() : x(2) {} - char const* name() { return "C"; } - virtual ~C() {} - int x; -}; - -struct D : B, C -{ - D() : x(3) {} - char const* name() { return "D"; } - int x; -}; - -A take_a(A const& a) { return a; } -B take_b(B const& b) { return b; } -C take_c(C const& c) { return c; } -D take_d(D const& d) { return d; } - -BOOST_PYTHON_MODULE_INIT(m1) -{ - using boost::python::module; - using boost::python::class_; - using boost::python::converter::from_python_converter; - using boost::python::reference_from_python; - using boost::python::value_from_python; - using boost::python::type_from_python; - using boost::python::get_member; - using boost::python::copy_const_reference; - using boost::python::return_value_policy; - using boost::mpl::type_list; - - // Create the converters; they are self-registering/unregistering. - static simple_to_python c1; - - static from_python_converter c2( - &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int); - - static from_python_converter c3( - &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int_ref); - - static boost::python::reference_from_python< - &SimpleType - , simple - , SimpleObject - , extract_simple_object - > - unwrap_simple; - - module m1("m1"); - - typedef boost::python::objects::pointer_holder_generator< - boost::python::objects::shared_ptr_generator - > use_shared_ptr; - - m1 - // Insert the metaclass for all extension classes - .setattr("xclass", boost::python::objects::class_metatype()) - - // Insert the base class for all extension classes - .setattr("xinst", boost::python::objects::class_type()) - - .def("new_noddy", new_noddy) - .def("new_simple", new_simple) - - // Expose f() - .def("f", f) - - // Expose g() - .def("g", g , return_value_policy() - ) - - .def("take_a", take_a) - .def("take_b", take_b) - .def("take_c", take_c) - .def("take_d", take_d) - - .add( - class_, use_shared_ptr>("A") - .def_init() - .def("name", &A::name) - ) - - ; - - // sequence points don't ensure that "A" is constructed before "B" - // or "C" below if we make them part of the same chain - m1 - .add( - class_, use_shared_ptr>("B") - .def_init() - .def("name", &B::name) - ) - - .add( - class_, use_shared_ptr>("C") - .def_init() - .def("name", &C::name) - ) - ; - - m1 - .add( - class_, use_shared_ptr>("D") - .def_init() - .def("name", &D::name) - ) - - .add( - class_("complicated") - .def_init(type_list()) - .def_init(type_list()) - .def("get_n", &complicated::get_n) - ) - ; -} - -#include "module_tail.cpp" diff --git a/test/m2.cpp b/test/m2.cpp deleted file mode 100644 index afffb27d..00000000 --- a/test/m2.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// This module exercises the converters exposed in m1 at a low level -// by exposing raw Python extension functions that use wrap<> and -// unwrap<> objects. -#include -#include -#include -#include -#include "simple_type.hpp" - -// Get a simple (by value) from the argument, and return the -// string it holds. -PyObject* unwrap_simple(simple x) -{ - return PyString_FromString(x.s); -} - -// Likewise, but demands that its possible to get a non-const -// reference to the simple. -PyObject* unwrap_simple_ref(simple& x) -{ - return PyString_FromString(x.s); -} - -// Likewise, with a const reference to the simple object. -PyObject* unwrap_simple_const_ref(simple const& x) -{ - return PyString_FromString(x.s); -} - -// Get an int (by value) from the argument, and convert it to a -// Python Int. -PyObject* unwrap_int(int x) -{ - return PyInt_FromLong(x); -} - -// Get a non-const reference to an int from the argument -PyObject* unwrap_int_ref(int& x) -{ - return PyInt_FromLong(x); -} - -// Get a const reference to an int from the argument. -PyObject* unwrap_int_const_ref(int const& x) -{ - return PyInt_FromLong(x); -} - -// rewrap extracts a T from the argument, then converts the T back -// to a PyObject* and returns it. -template -struct rewrap -{ - static T f(T x) { return x; } -}; - -BOOST_PYTHON_MODULE_INIT(m2) -{ - using boost::python::return_value_policy; - using boost::python::copy_const_reference; - using boost::python::copy_non_const_reference; - - boost::python::module("m2") - .def("unwrap_int", unwrap_int) - .def("unwrap_int_ref", unwrap_int_ref) - .def("unwrap_int_const_ref", unwrap_int_const_ref) - .def("unwrap_simple", unwrap_simple) - .def("unwrap_simple_ref", unwrap_simple_ref) - .def("unwrap_simple_const_ref", unwrap_simple_const_ref) - - .def("wrap_int", &rewrap::f) - - .def("wrap_int_ref", &rewrap::f - , return_value_policy() - ) - - .def("wrap_int_const_ref", &rewrap::f - , return_value_policy() - ) - - .def("wrap_simple", &rewrap::f) - - .def("wrap_simple_ref", &rewrap::f - , return_value_policy() - ) - - .def("wrap_simple_const_ref", &rewrap::f - , return_value_policy() - ) - ; -} - -#include "module_tail.cpp" diff --git a/test/module_tail.cpp b/test/module_tail.cpp deleted file mode 100644 index 6849bf83..00000000 --- a/test/module_tail.cpp +++ /dev/null @@ -1,39 +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. - -#if defined(_WIN32) -# ifdef __MWERKS__ -# pragma ANSI_strict off -# endif -# include -# ifdef __MWERKS__ -# pragma ANSI_strict reset -# endif - -extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); - -# ifdef BOOST_MSVC -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -# endif - -BOOL WINAPI DllMain( - HINSTANCE, //hDllInst - DWORD fdwReason, - LPVOID // lpvReserved - ) -{ -# ifdef BOOST_MSVC - _set_se_translator(structured_exception_translator); -# endif - (void)fdwReason; // warning suppression. - - return 1; -} -#endif // _WIN32 - diff --git a/test/newtest.py b/test/newtest.py deleted file mode 100644 index 4e6de142..00000000 --- a/test/newtest.py +++ /dev/null @@ -1,162 +0,0 @@ -""" ->>> from m1 import * - ->>> from m2 import * - ->>> n = new_noddy() ->>> s = new_simple() ->>> unwrap_int(n) -42 ->>> unwrap_int_ref(n) -42 ->>> unwrap_int_const_ref(n) -42 ->>> unwrap_simple(s) -'hello, world' ->>> unwrap_simple_ref(s) -'hello, world' ->>> unwrap_simple_const_ref(s) -'hello, world' ->>> unwrap_int(5) -5 - -Can't get a non-const reference to a built-in integer object ->>> try: -... unwrap_int_ref(7) -... except: pass -... else: print 'no exception' - ->>> unwrap_int_const_ref(9) -9 - ->>> wrap_int(n) -42 - -try: wrap_int_ref(n) -... except: pass -... else: print 'no exception' - ->>> wrap_int_const_ref(n) -42 - ->>> unwrap_simple_ref(wrap_simple(s)) -'hello, world' - ->>> unwrap_simple_ref(wrap_simple_ref(s)) -'hello, world' - ->>> unwrap_simple_ref(wrap_simple_const_ref(s)) -'hello, world' - ->>> f(s) -12 - ->>> unwrap_simple(g(s)) -'hello, world' - ->>> f(g(s)) -12 - -Create an extension class which wraps "complicated" (init1 and get_n) -are a complicated constructor and member function, respectively. - ->>> c1 = complicated(s, 99) ->>> c1.get_n() -99 ->>> c2 = complicated(s) ->>> c2.get_n() -0 - ->>> a = A() ->>> b = B() ->>> c = C() ->>> d = D() - ------- ->>> take_a(a).name() -'A' - ->>> try: -... take_b(a) -... except: pass -... else: print 'no exception' - ->>> try: -... take_c(a) -... except: pass -... else: print 'no exception' - ->>> try: -... take_d(a) -... except: pass -... else: print 'no exception' - ------- ->>> take_a(b).name() -'A' - ->>> take_b(b).name() -'B' - ->>> try: -... take_c(b) -... except: pass -... else: print 'no exception' - ->>> try: -... take_d(b) -... except: pass -... else: print 'no exception' - -------- ->>> take_a(c).name() -'A' - ->>> try: -... take_b(c) -... except: pass -... else: print 'no exception' - ->>> take_c(c).name() -'C' - ->>> try: -... take_d(c) -... except: pass -... else: print 'no exception' - -------- ->>> take_a(d).name() -'A' ->>> take_b(d).name() -'B' ->>> take_c(d).name() -'C' ->>> take_d(d).name() -'D' - - -""" - -def run(args = None): - - ### Strange bug somewhere: with Metrowerks: it will crash in - ### garbage-collection code unless traceback and sre have been - ### loaded before m1. - -# import traceback -# import sre -# import m2 -# import m1 - import sys - import doctest - - if args is not None: - sys.argv = args - # import sys - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/simple_type.hpp b/test/simple_type.hpp deleted file mode 100644 index 2df97cfd..00000000 --- a/test/simple_type.hpp +++ /dev/null @@ -1,14 +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 SIMPLE_TYPE_DWA2001128_HPP -# define SIMPLE_TYPE_DWA2001128_HPP - -struct simple -{ - char* s; -}; - -#endif // SIMPLE_TYPE_DWA2001128_HPP diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp deleted file mode 100644 index 6ffccdf9..00000000 --- a/test/test_builtin_converters.cpp +++ /dev/null @@ -1,65 +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. -#include -#include -#include -#include - - -template -struct by_value -{ - static T rewrap(T x) - { - return x; - } -}; - -template -struct by_const_reference -{ - static T rewrap(T const& x) - { - return x; - } -}; - -BOOST_PYTHON_MODULE_INIT(builtin_converters_ext) -{ - boost::python::module("builtin_converters_ext") - - .def("rewrap_value_signed_char", by_value::rewrap) - .def("rewrap_value_unsigned_char", by_value::rewrap) - .def("rewrap_value_int", by_value::rewrap) - .def("rewrap_value_unsigned_int", by_value::rewrap) - .def("rewrap_value_short", by_value::rewrap) - .def("rewrap_value_unsigned_short", by_value::rewrap) - .def("rewrap_value_long", by_value::rewrap) - .def("rewrap_value_unsigned_long", by_value::rewrap) - .def("rewrap_value_float", by_value::rewrap) - .def("rewrap_value_double", by_value::rewrap) - .def("rewrap_value_long_double", by_value::rewrap) - .def("rewrap_value_string", by_value::rewrap) - .def("rewrap_value_cstring", by_value::rewrap) - - - .def("rewrap_const_reference_signed_char", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_char", by_const_reference::rewrap) - .def("rewrap_const_reference_int", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_int", by_const_reference::rewrap) - .def("rewrap_const_reference_short", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_short", by_const_reference::rewrap) - .def("rewrap_const_reference_long", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap) - .def("rewrap_const_reference_float", by_const_reference::rewrap) - .def("rewrap_const_reference_double", by_const_reference::rewrap) - .def("rewrap_const_reference_long_double", by_const_reference::rewrap) - .def("rewrap_const_reference_string", by_const_reference::rewrap) - .def("rewrap_const_reference_cstring", by_const_reference::rewrap) - - ; -} - diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py deleted file mode 100644 index 3941a29c..00000000 --- a/test/test_builtin_converters.py +++ /dev/null @@ -1,86 +0,0 @@ -""" ->>> from builtin_converters_ext import * ->>> rewrap_value_signed_char(42) -42 ->>> rewrap_value_unsigned_char(42) -42 ->>> rewrap_value_int(42) -42 ->>> rewrap_value_unsigned_int(42) -42 ->>> rewrap_value_short(42) -42 ->>> rewrap_value_unsigned_short(42) -42 ->>> rewrap_value_long(42) -42 ->>> rewrap_value_unsigned_long(42) -42 - ->>> abs(rewrap_value_float(4.2) - 4.2) < .000001 -1 ->>> rewrap_value_double(4.2) - 4.2 -0.0 ->>> rewrap_value_long_double(4.2) - 4.2 -0.0 - ->>> rewrap_value_cstring('hello, world') -'hello, world' ->>> rewrap_value_string('yo, wassup?') -'yo, wassup?' - ->>> rewrap_const_reference_signed_char(42) -42 ->>> rewrap_const_reference_unsigned_char(42) -42 ->>> rewrap_const_reference_int(42) -42 ->>> rewrap_const_reference_unsigned_int(42) -42 ->>> rewrap_const_reference_short(42) -42 ->>> rewrap_const_reference_unsigned_short(42) -42 ->>> rewrap_const_reference_long(42) -42 ->>> rewrap_const_reference_unsigned_long(42) -42 ->>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 -1 ->>> rewrap_const_reference_double(4.2) - 4.2 -0.0 ->>> rewrap_const_reference_long_double(4.2) - 4.2 -0.0 - ->>> rewrap_const_reference_cstring('hello, world') -'hello, world' ->>> rewrap_const_reference_string('yo, wassup?') -'yo, wassup?' - -Now check implicit conversions between floating/integer types - ->>> rewrap_const_reference_float(42) -42.0 - ->>> rewrap_const_reference_int(42.0) -42 - ->>> rewrap_value_float(42) -42.0 - ->>> rewrap_value_int(42.0) -42 - -""" -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/todo.txt b/todo.txt deleted file mode 100644 index d97eade5..00000000 --- a/todo.txt +++ /dev/null @@ -1,426 +0,0 @@ -Check for const reference parameters in all from_python functions in py.h, including implementations. -Better python and C++ exception handling/error reporting. -long long support -use Python generic numeric coercion in from_python() for C++ numeric types -Rename PyPtr to Reference. -Report Cygwin linker memory issues -__init__ stuff - Make abstract classes non-instantiable (?) - Call default __init__ functions automatically where applicable (?) -Support for Python LONG types in Objects.h -Throw TypeError after asserting when objects from objects.cpp detect a type mismatch. -Figure out how to package everything as a shared library. -Unicode string support -Add read-only wrapper for __dict__ attribute -Objects.h support for generic objects, Sequence objects, etc. -empty() member functions for objects.hpp - -Testing - Python 2.0 - object revival in __del__ - More thorough tests of objects.h/cpp classes - Better reference-count checking - -Optimizations - Remove one level of indirection on type objects (no vtbl?). - Specializations of Caller<> for commmon combinations of argument types (?) - Replace uses of XXXable classes - Don't allocate instance __dict__ unless used. - - -Documentation: - - differences between Python classes and ExtensionClasses - additional capabilities of ExtensionClasses - slice adjustment - - Why special attributes other than __doc__ and __name__ are immutable. - - An example of the problems with the built-in Python classes. - - >>> class A: - ... def __getattr__(self, name): - ... return 'A.__getattr__' - ... - >>> class B(A): pass - ... - >>> class C(B): pass - ... - >>> C().x - 'A.__getattr__' - >>> B.__bases__ = () - >>> C().x - 'A.__getattr__' - - Smart pointers - #ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE - namespace py { - #endif - - template - struct VtkConverters - { - typedef py::PyExtensionClassConverters Converters; - - friend vtk_ptr& from_python(PyObject* p, py::Type&>) - { return Converters::ptr_from_python(p, py::Type >()); } - - friend vtk_ptr& from_python(PyObject* p, py::Type >) - { return Converters::ptr_from_python(p, py::Type >()); } - - friend const vtk_ptr& from_python(PyObject* p, py::Type&>) - { return Converters::ptr_from_python(p, py::Type >()); } - - friend PyObject* to_python(vtk_ptr x) - { return Converters::ptr_to_python(x); } - }; - - #ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE - } - #endif - - template - struct VtkWrapper : py::ClassWrapper, py::VtkConverters - { - typedef py::ClassWrapper Base; - VtkWrapper(Module& module, const char* name) - : Base(module, name) {} - }; - - exception handling - - Advanced Topics: - Advanced Type Conversion - adding conversions for fundamental types - generic conversions for template types (with partial spec). - - Interacting with built-in Python objects and types from C++ - - dealing with non-const reference/pointer parameters - - extending multiple-argument support using gen_all.py - - - Fancy wrapping tricks - templates - Yes. If you look at the examples in extclass_demo.cpp you'll see that I have - exposed several template instantiations (e.g. std::pair) in Python. - Keep in mind, however, that you can only expose a template instantiation, - not a template. In other words, MyTemplate can be exposed. MyTemplate - itself cannot. - - Well, that's not strictly true. Wow, this is more complicated to explain - than I thought. - You can't make an ExtensionClass, since after all MyTemplate is - not a type. You can only expose a concrete type to Python. - - What you *can* do (if your compiler supports partial ordering of function - templates - MSVC is broken and does not) is to write appropriate - from_python() and to_python() functions for converting a whole class of - template instantiations to/from Python. That won't let you create an - instance of MyTemplate from Python, but it will let you - pass/return arbitrary MyTemplate instances to/from your - wrapped C++ functions. - - template - MyTemplate from_python(PyObject* x, py::Type >) - { - // code to convert x into a MyTemplate... that part is up to you - } - - template - PyObject* from_python(const MyTemplate&) - { - // code to convert MyTemplate into a PyObject*... that part is up to - you - } - - For example, you could use this to convert Python lists to/from - std::vector automatically. - - Pointer return values - - Case 1: - - > I am now also able to wrap the problematic TextRecordIterator for Python. - > However, one of its function compiles with this warning: - > - > d:\py_cpp/caller.h(33) : warning C4800: 'const class Record *const ' - > : forcing value to bool 'true' or 'false' (performance warning) - > d:\py_cpp/functions.h(54) : see reference to function template - > instantiation 'struct _object *__cdecl py::Caller::call(const class Record - > *const (__thiscall TextRecordIterator::*)(void),struct _object *,struct - > _object *)' being compiled - > - > If you look at the offending code, you'll see that we really do need to - > get back that pointer: - > - > const Record* const TextRecordIterator::Next() { - > if (fStatus != RecordIterator::SUCCESS) { - > return 0; - > } else { - > return &fData; - > } - > } - > - > The point of the TextRecordIterator is to hand over one reord after - > another. A bool wouldn't do us much good here :-) - > - > Do you have any suggestions for fixing this? - - In general, py_cpp doesn't automatically convert pointer return values - to_python because pointers have too many potential meanings. Is it an - iterator? A pointer to a single element? An array? Is ownership being passed - to Python or is the pointer really just a reference? If the latter, what - happens when some C++ code deletes the referent. The only exception to this - rule is const char*, since it has a generally accepted interpretation (could - be trouble with some generic code, though!) - - If you have wrapped the Record class, you could add this to namespace py: - - PyObject* to_python(const Record* p) { - return to_python(*p); - } - - Of course, this will cause the Record class to be copied. If you can't live - with that (Record would have to be /really/ heavyweight to make this - worthwhile), you can follow one of these dangerous approaches: - - 1. Use the technique I described with dangerous_array in - http://www.egroups.com/message/boost/6196. You do not have to expose Record - explicitly in this case. Instead the class you expose will be more of a - Record_proxy - - 2. Wrap Record in the usual way, then add the following to namespace py: - - PyObject* to_python(const Record* p) - { - return ExtensionClass::ptr_to_python(const_cast(p)); - } - - This will cause the Record* to be treated as though it were an owning smart - pointer, even though it's not. Be sure you don't use the reference for - anything from Python once the pointer becomes invalid, though. Don't worry - too much about the const-correctness issue: Const-correctness is completely - lost to Python anyway! - - 3. As above, but instead wrap const Record rather than plain Record. Then - you can avoid the const_cast, but you obviously can't def() any non-const - member functions of Record. - - Case 2: - - > I have yet another question. This is more a general wrapper question. - > Let me say that there is a function that returns a float* which most - > probably is an array. Similarly if I have a function that takes a - > float* as an argument, what is the best way of wrapping this? - - I think you have correctly perceived that it doesn't make sense for me to - automatically convert all pointers, since the ownership semantics are so - blurry. - - > 1) If the array is small it makes sense to convert it to either a - > tuple or list. What is the easiest way to do this?? I am looking - > for a way that makes one write the least code. :) - - How can you tell the length of the array from a single pointer? - Once you've answered that question, you can expose a wrapper function which - returns an instance of the py::Tuple or py::List class from objects.h. If - you are using a List, for example, you could write something like this: - - py::List wrap_f() - { - T* start = f(); - py::List x; - for (T* p = start; p != start + length_constant; ++p) - x.push_back(py::to_python(*p)); - return x; - } - - > 2) If the array is large it may not make sense to use a list/tuple - > esp. if the values are used for computationally intense programs. - - In this case you can do one of several somewhat dangerous things. Why - dangerous? Because python can not control the lifetime of the data, so the - data in the array may be destroyed or become invalid before the last - reference to it disappears. The basic approach is to make a small C++ class - which contains the pointer, and expose that: - - // UNTESTED - template - struct dangerous_array - { - dangerous_array(T* start, T* end) - : m_start(start), m_end(end) {} - - // exposed as "__len__" - std::size_t length() { - return m_end - m_start; - } - - // exposed as "__getitem__" - T get_item(std::size_t n) { - check_range(n); - return start[n]; - } - - // exposed as "__setitem__" if the array is mutable - void set_item(std::size_t n, const T& x) { - check_range(n); - start[n] = x; - } - private: - void check_range(std::size_t n) { - if (n >= m_end - m_start) { - PyErr_SetString(PyExc_IndexError, "array index out of range"); - throw py::ErrorAlreadySet; - } - } - T* m_start; - T* m_end; - }; - - A reasonably safe approach would be to make a wrapper function for each - function that returns a T*, and expose that instead. If you're too lazy and - you really like to live on the edge, though, you can write to_python(T*) in - terms of to_python(const dangerous_array&), and you'll automatically - convert all T* return values to a wrapped dangerous_array. - - > 3) For an arbitrary class "class_A", say, can py_cpp handle - > references to class_A &instance, or class_A *instance?? i.e. will it - > wrap function calls to such objects? This question is obviously - > related to the earlier questions. - - Yes, iff class_A has been exposed to python with a ClassWrapper. - See http://people.ne.mediaone.net/abrahams/downloads/under-the-hood.html for - a few details. - - raw C++ arrays - You could expose a function like this one to get the desired effect: - - #include - void set_len(UnitCell& x, py::Tuple tuple) - { - double len[3]; - for (std::size_t i =0; i < 3; ++i) - len[i] = py::from_python(tuple[i].get(), py::Type()); - x.set_len(len); - } - - Types that are already wrapped by other libraries - - It's not documented yet, but you should be able to use a raw PyObject* or a - py::Ptr as one parameter to your C++ function. Then you can manipulate it as - any other generic Python object. - - Alternatively, If the NTL gives you a C/C++ interface, you can also write - your own converter function: - - some_ntl_type& from_python(PyObject* p, py::Type) - { - // an Example implementation. Basically, you need - // to extract the NTL type from the PyObject*. - if (p->ob_type != NTL_long_type) { - PyErr_SetString(PyExc_TypeErr, "NTL long required"); - throw py::ArgumentError(); - } - return *static_cast(p); - } - - then the C++ functions you're wrapping can take a some_NTL_type& parameter - directly. - - "Thin converting wrappers" for constructors - - hijack some of the functionality - described in the section on Overridable Virtual Functions (even though you - don't have any virtual functions). I suggest this workaround: - - struct UnitCellWrapper : UnitCell - { - UnitCellWrapper(PyObject* self, py::Tuple x, py::Tuple y) - : UnitCell(from_python(x[1], py::Type()), - from_python(x[2], py::Type()), - from_python(x[3], py::Type()), - from_python(y[1], py::Type()), - from_python(y[2], py::Type()), - from_python(y[3], py::Type())) - {} - } - - py::ClassWrapper unit_cell_class; - unit_cell_class.def(py::Constructor()); - ... - - returning references to wrapped objects - - the importance of declaration order of ClassWrappers/ExtensionInstances - - out parameters and non-const pointers - - Calling back into Python: - // caveat: UNTESTED! - #include - #include - #include - #include - int main() - { - try { - py::Ptr module(PyImport_ImportModule("weapons")); - const int strength = 10; - const char* manufacturer = "Vordon Empire"; - py::Ptr a_blaster(py::Callback::call_method( - module.get(), "Blaster", strength, manufacturer)); - py::Callback::call_method(a_blaster.get(), "Fire"); - int old_strength = py::Callback::call_method(a_blaster.get(), "get_strength"); - py::Callback::call_method(a_blaster.get(), "set_strength", 5); - } - catch(...) - { - } - } - - Miscellaneous - About the vc6 project and the debug build - About doctest.py - -Boost remarks: - - > > One of us is completely nuts ;->. How can I move the test - > > (is_prefix(enablers[i].name + 2, name + 2)) outside the loop if it - depends - > > on the loop index, i? - > > - > name += 2; - > for() - > { - > if (is_prefix(enablers[i].name + 2, name)) - > } - - I see now. I guess I should stop pussyfooting and either go for optimization - or clarity here, eh? - - ------ - - > Re: Dict - > Why abbreviate this? Code is read 5 or 6 times for every time its - > written. The few extra characters don't affect compile time or program - > speed. It's part of my personal goal of write what you mean, name them - what - > they are. - - I completely agree. Abbrevs rub me the wrong way, 2 ;-> - - ------- - - - - -Later: - keyword and varargs? - Put explicit Type<> arguments at the beginnings of overloads, to make them look more like template instance specifications. - -Known bugs - can't handle 'const void' return values - Who returns 'const void'? I did it once, by mistake ;)