diff --git a/build/Attic/python_v1.zip b/build/Attic/python_v1.zip deleted file mode 100644 index 0377a07b..00000000 Binary files a/build/Attic/python_v1.zip and /dev/null differ diff --git a/build/Jamfile b/build/Jamfile deleted file mode 100644 index b58c22dc..00000000 --- a/build/Jamfile +++ /dev/null @@ -1,84 +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 library Jamfile - - -# 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 ; - -if [ check-python-config ] -{ - - local bpl-linkflags ; - - if $(UNIX) && ( $(OS) = AIX ) - { - bpl-linkflags = "-e initlibboost_python" ; - } - - # Enabling intrinsics (/0i) or maximize speed (/02) seem to cause - # internal compiler errors with this toolset. - local msvc-stlport-workarounds - = off "-Ogty -O1 -Gs" ; - - local sources = - numeric.cpp - list.cpp - long.cpp - dict.cpp - tuple.cpp - str.cpp - - aix_init_module.cpp - converter/from_python.cpp - converter/registry.cpp - converter/type_id.cpp - object/enum.cpp - object/class.cpp - object/function.cpp - object/inheritance.cpp - object/life_support.cpp - object/pickle_support.cpp - errors.cpp - module.cpp - converter/builtin_converters.cpp - converter/arg_to_python_base.cpp - object/iterator.cpp - object_protocol.cpp - object_operators.cpp - ; - - dll boost_python - : ../src/$(sources) - : $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - $(bpl-linkflags) - $(msvc-stlport-workarounds) - ; - - lib boost_python - : # sources - ../src/$(sources) - - : # requirements - $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - BOOST_STATIC_LIB - $(bpl-linkflags) - $(msvc-stlport-workarounds) - ; - - stage bin-stage : boost_python boost_python - : "_debug" - "_pydebug" - : - debug release - ; -} \ No newline at end of file diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 deleted file mode 100644 index 7b9e21f1..00000000 --- a/build/Jamfile.v2 +++ /dev/null @@ -1,85 +0,0 @@ -import os ; - -# Use a very crude way to sense there python is locatted - -local PYTHON_PATH ; - -if [ GLOB /usr/local/include/python2.2 : * ] -{ - PYTHON_PATH = /usr/local ; -} -else if [ GLOB /usr/include/python2.2 : * ] -{ - PYTHON_PATH = /usr ; -} - -if [ os.name ] in CYGWIN NT -{ - lib_condition = shared: ; - defines = USE_DL_IMPORT ; - - # Declare a target for the python interpreter library - lib python : : python2.2.dll ; - PYTHON_LIB = python ; -} -else -{ - lib python : : python2.2 ; - PYTHON_LIB = python ; -} - - - -if $(PYTHON_PATH) { - - -project boost/python - : source-location ../src - : requirements $(PYTHON_PATH)/include/python2.2 - $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config - shared:$(PYTHON_LIB) - $(defines) - : usage-requirements # requirement that will be propageted to *users* of this library - $(PYTHON_PATH)/include/python2.2 - -# We have a bug which causes us to conclude that conditionalized -# properties in this section are not free. -# $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config -# true:$(PYTHON_LIB) - - $(PYTHON_PATH)/lib/python2.2/config - $(PYTHON_LIB) - ; - -lib boost_python - : - numeric.cpp - - list.cpp - long.cpp - dict.cpp - tuple.cpp - str.cpp - - aix_init_module.cpp - converter/from_python.cpp - converter/registry.cpp - converter/type_id.cpp - object/enum.cpp - object/class.cpp - object/function.cpp - object/inheritance.cpp - object/life_support.cpp - object/pickle_support.cpp - errors.cpp - module.cpp - converter/builtin_converters.cpp - converter/arg_to_python_base.cpp - object/iterator.cpp - object_protocol.cpp - object_operators.cpp - : static:BOOST_PYTHON_STATIC_LIB - BOOST_PYTHON_SOURCE - : shared - ; -} diff --git a/build/VisualStudio/boost_python.dsp b/build/VisualStudio/boost_python.dsp deleted file mode 100644 index 1e4c5358..00000000 --- a/build/VisualStudio/boost_python.dsp +++ /dev/null @@ -1,882 +0,0 @@ -# Microsoft Developer Studio Project File - Name="boost_python" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=BOOST_PYTHON - WIN32 RELEASE -!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 "boost_python.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 "boost_python.mak" CFG="BOOST_PYTHON - WIN32 RELEASE" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "boost_python - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "boost_python - Win32 Debug" (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)" == "boost_python - 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 "../bin-stage" -# PROP Intermediate_Dir "release-obj" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -F90=df.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /c -# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1409 /d "NDEBUG" -# ADD RSC /l 0x1409 /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 /nologo /dll /machine:I386 - -!ELSEIF "$(CFG)" == "boost_python - 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 "../bin-stage" -# PROP Intermediate_Dir "debug-obj" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -F90=df.exe -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /GZ /c -# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "../../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /Zm800 /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1409 /d "_DEBUG" -# ADD RSC /l 0x1409 /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 /nologo /dll /incremental:no /debug /machine:I386 /out:"../bin-stage/boost_python_debug.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "boost_python - Win32 Release" -# Name "boost_python - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\aix_init_module.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\arg_to_python_base.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\builtin_converters.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\class.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\dict.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\enum.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\errors.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\from_python.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\function.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\inheritance.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\iterator.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\life_support.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\list.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\long.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\module.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\numeric.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object_operators.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object_protocol.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\pickle_support.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\registry.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\str.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\tuple.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\type_id.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Group "detail" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\aix_init_module.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\api_placeholder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\arg_tuple_size.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\borrowed_ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\call_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\caller.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\char_array.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\config.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\construct.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\convertible.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\cv_category.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\decorated_type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\def_helper.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\defaults_def.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\defaults_gen.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\dependent.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\destroy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\exception_handler.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\force_instantiate.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\if_else.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\indirect_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\make_keyword_range_fn.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\make_tuple.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\map_entry.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\member_function_cast.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\module_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\module_init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\msvc_typeinfo.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\none.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\not_specified.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\operator_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\overloads_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\preprocessor.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\python22_fixed.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\raw_pyobject.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\referent_storage.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\result.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\returning.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\scope.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\string_literal.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\target.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\translate_exception.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_impl.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_impl_no_pts.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_utils.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\unwind_type.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\void_ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\void_return.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\wrap_python.hpp -# End Source File -# End Group -# Begin Group "converter" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_to_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_to_python_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\builtin_converters.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\constructor_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\convertible_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\implicit.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\obj_mgr_arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\object_manager.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pointer_type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pyobject_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pyobject_type.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pytype_arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pytype_object_mgr_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registered.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registered_pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registrations.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registry.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\return_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\rvalue_from_python_data.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\to_python_function_type.hpp -# End Source File -# End Group -# Begin Group "object" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\add_to_namespace.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_converters.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_detail.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_wrapper.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\construct.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\enum_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\find_instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\forward.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function_handle.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\inheritance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\iterator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\iterator_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\life_support.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\make_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\make_instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\pickle_support.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\pointer_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\py_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\select_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\value_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\value_holder_fwd.hpp -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\..\..\boost\python\arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\args.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\args_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\back_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\base_type_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\bases.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\borrowed.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\call.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\call_method.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\cast.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\class.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\class_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\copy_const_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\copy_non_const_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\data_members.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\def.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\default_call_policies.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\dict.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\enum.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\errors.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\exception_translator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\extract.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\handle.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\handle_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\has_back_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\implicit.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\instance_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\iterator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\list.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\long.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\lvalue_from_pytype.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\make_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\manage_new_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\module.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\module_init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\numeric.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_attributes.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_call.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_items.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_operators.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_protocol.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_protocol_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_slices.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\operators.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\operators2.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\other.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\overloads.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\proxy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\refcount.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\reference_existing_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\return_internal_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\return_value_policy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\scope.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\self.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\signature.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\slice_nil.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\str.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\tag.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_converter.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_indirect.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_value.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\tuple.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\with_custodian_and_ward.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/VisualStudio/boost_python.dsw b/build/VisualStudio/boost_python.dsw deleted file mode 100644 index 574c3bf8..00000000 --- a/build/VisualStudio/boost_python.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "boost_python"=".\boost_python.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/build/python_v1.zip b/build/python_v1.zip deleted file mode 100644 index 0377a07b..00000000 Binary files a/build/python_v1.zip and /dev/null differ diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt deleted file mode 100644 index 8113f50e..00000000 --- a/doc/PyConDC_2003/bpl.txt +++ /dev/null @@ -1,853 +0,0 @@ -+++++++++++++++++++++++++++++++++++++++++++ - Building Hybrid Systems with Boost.Python -+++++++++++++++++++++++++++++++++++++++++++ - -:Author: David Abrahams -:Contact: dave@boost-consulting.com -:organization: `Boost Consulting`_ -:date: $Date$ - -:Author: Ralf W. Grosse-Kunstleve - -:status: Draft -:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved - -.. contents:: Table of Contents - - -.. _`Boost Consulting`: http://www.boost-consulting.com - -========== - Abstract -========== - -Boost.Python is an open source C++ library which provides a concise -IDL-like interface for binding C++ classes and functions to -Python. Leveraging the full power of C++ compile-time introspection -and of recently developed metaprogramming techniques, this is achieved -entirely in pure C++, without introducing a new syntax. -Boost.Python's rich set of features and high-level interface make it -possible to engineer packages from the ground up as hybrid systems, -giving programmers easy and coherent access to both the efficient -compile-time polymorphism of C++ and the extremely convenient run-time -polymorphism of Python. - -============== - Introduction -============== - -Python and C++ are in many ways as different as two languages could -be: while C++ is usually compiled to machine-code, Python is -interpreted. Python's dynamic type system is often cited as the -foundation of its flexibility, while in C++ static typing is the -cornerstone of its efficiency. C++ has an intricate and difficult -compile-time meta-language, while in Python, practically everything -happens at runtime. - -Yet for many programmers, these very differences mean that Python and -C++ complement one another perfectly. Performance bottlenecks in -Python programs can be rewritten in C++ for maximal speed, and -authors of powerful C++ libraries choose Python as a middleware -language for its flexible system integration capabilities. -Furthermore, the surface differences mask some strong similarities: - -* 'C'-family control structures (if, while, for...) - -* Support for object-orientation, functional programming, and generic - programming (these are both *multi-paradigm* programming languages.) - -* Comprehensive operator overloading facilities, recognizing the - importance of syntactic variability for readability and - expressivity. - -* High-level concepts such as collections and iterators. - -* High-level encapsulation facilities (C++: namespaces, Python: modules) - to support the design of re-usable libraries. - -* Exception-handling for effective management of error conditions. - -* C++ idioms in common use, such as handle/body classes and - reference-counted smart pointers mirror Python reference semantics. - -Given Python's rich 'C' interoperability API, it should in principle -be possible to expose C++ type and function interfaces to Python with -an analogous interface to their C++ counterparts. However, the -facilities provided by Python alone for integration with C++ are -relatively meager. Compared to C++ and Python, 'C' has only very -rudimentary abstraction facilities, and support for exception-handling -is completely missing. 'C' extension module writers are required to -manually manage Python reference counts, which is both annoyingly -tedious and extremely error-prone. Traditional extension modules also -tend to contain a great deal of boilerplate code repetition which -makes them difficult to maintain, especially when wrapping an evolving -API. - -These limitations have lead to the development of a variety of wrapping -systems. SWIG_ is probably the most popular package for the -integration of C/C++ and Python. A more recent development is SIP_, -which was specifically designed for interfacing Python with the Qt_ -graphical user interface library. Both SWIG and SIP introduce their -own specialized languages for customizing inter-language bindings. -This has certain advantages, but having to deal with three different -languages (Python, C/C++ and the interface language) also introduces -practical and mental difficulties. The CXX_ package demonstrates an -interesting alternative. It shows that at least some parts of -Python's 'C' API can be wrapped and presented through a much more -user-friendly C++ interface. However, unlike SWIG and SIP, CXX does -not include support for wrapping C++ classes as new Python types. - -The features and goals of Boost.Python_ overlap significantly with -many of these other systems. That said, Boost.Python attempts to -maximize convenience and flexibility without introducing a separate -wrapping language. Instead, it presents the user with a high-level -C++ interface for wrapping C++ classes and functions, managing much of -the complexity behind-the-scenes with static metaprogramming. -Boost.Python also goes beyond the scope of earlier systems by -providing: - -* Support for C++ virtual functions that can be overridden in Python. - -* Comprehensive lifetime management facilities for low-level C++ - pointers and references. - -* Support for organizing extensions as Python packages, - with a central registry for inter-language type conversions. - -* A safe and convenient mechanism for tying into Python's powerful - serialization engine (pickle). - -* Coherence with the rules for handling C++ lvalues and rvalues that - can only come from a deep understanding of both the Python and C++ - type systems. - -The key insight that sparked the development of Boost.Python is that -much of the boilerplate code in traditional extension modules could be -eliminated using C++ compile-time introspection. Each argument of a -wrapped C++ function must be extracted from a Python object using a -procedure that depends on the argument type. Similarly the function's -return type determines how the return value will be converted from C++ -to Python. Of course argument and return types are part of each -function's type, and this is exactly the source from which -Boost.Python deduces most of the information required. - -This approach leads to *user guided wrapping*: as much information is -extracted directly from the source code to be wrapped as is possible -within the framework of pure C++, and some additional information is -supplied explicitly by the user. Mostly the guidance is mechanical -and little real intervention is required. Because the interface -specification is written in the same full-featured language as the -code being exposed, the user has unprecedented power available when -she does need to take control. - -.. _Python: http://www.python.org/ -.. _SWIG: http://www.swig.org/ -.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php -.. _Qt: http://www.trolltech.com/ -.. _CXX: http://cxx.sourceforge.net/ -.. _Boost.Python: http://www.boost.org/libs/python/doc - -=========================== - Boost.Python Design Goals -=========================== - -The primary goal of Boost.Python is to allow users to expose C++ -classes and functions to Python using nothing more than a C++ -compiler. In broad strokes, the user experience should be one of -directly manipulating C++ objects from Python. - -However, it's also important not to translate all interfaces *too* -literally: the idioms of each language must be respected. For -example, though C++ and Python both have an iterator concept, they are -expressed very differently. Boost.Python has to be able to bridge the -interface gap. - -It must be possible to insulate Python users from crashes resulting -from trivial misuses of C++ interfaces, such as accessing -already-deleted objects. By the same token the library should -insulate C++ users from low-level Python 'C' API, replacing -error-prone 'C' interfaces like manual reference-count management and -raw ``PyObject`` pointers with more-robust alternatives. - -Support for component-based development is crucial, so that C++ types -exposed in one extension module can be passed to functions exposed in -another without loss of crucial information like C++ inheritance -relationships. - -Finally, all wrapping must be *non-intrusive*, without modifying or -even seeing the original C++ source code. Existing C++ libraries have -to be wrappable by third parties who only have access to header files -and binaries. - -========================== - Hello Boost.Python World -========================== - -And now for a preview of Boost.Python, and how it improves on the raw -facilities offered by Python. Here's a function we might want to -expose:: - - char const* greet(unsigned x) - { - static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; - - if (x > 2) - throw std::range_error("greet: index out of range"); - - return msgs[x]; - } - -To wrap this function in standard C++ using the Python 'C' API, we'd -need something like this:: - - extern "C" // all Python interactions use 'C' linkage and calling convention - { - // Wrapper to handle argument/result conversion and checking - PyObject* greet_wrap(PyObject* args, PyObject * keywords) - { - int x; - if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments - { - char const* result = greet(x); // invoke wrapped function - return PyString_FromString(result); // convert result to Python - } - return 0; // error occurred - } - - // Table of wrapped functions to be exposed by the module - static PyMethodDef methods[] = { - { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" } - , { NULL, NULL, 0, NULL } // sentinel - }; - - // module initialization function - DL_EXPORT init_hello() - { - (void) Py_InitModule("hello", methods); // add the methods to the module - } - } - -Now here's the wrapping code we'd use to expose it with Boost.Python:: - - #include - using namespace boost::python; - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet, "return one of 3 parts of a greeting"); - } - -and here it is in action:: - - >>> import hello - >>> for x in range(3): - ... print hello.greet(x) - ... - hello - Boost.Python - world! - -Aside from the fact that the 'C' API version is much more verbose, -it's worth noting a few things that it doesn't handle correctly: - -* The original function accepts an unsigned integer, and the Python - 'C' API only gives us a way of extracting signed integers. The - Boost.Python version will raise a Python exception if we try to pass - a negative number to ``hello.greet``, but the other one will proceed - to do whatever the C++ implementation does when converting an - negative integer to unsigned (usually wrapping to some very large - number), and pass the incorrect translation on to the wrapped - function. - -* That brings us to the second problem: if the C++ ``greet()`` - function is called with a number greater than 2, it will throw an - exception. Typically, if a C++ exception propagates across the - boundary with code generated by a 'C' compiler, it will cause a - crash. As you can see in the first version, there's no C++ - scaffolding there to prevent this from happening. Functions wrapped - by Boost.Python automatically include an exception-handling layer - which protects Python users by translating unhandled C++ exceptions - into a corresponding Python exception. - -* A slightly more-subtle limitation is that the argument conversion - used in the Python 'C' API case can only get that integer ``x`` in - *one way*. PyArg_ParseTuple can't convert Python ``long`` objects - (arbitrary-precision integers) which happen to fit in an ``unsigned - int`` but not in a ``signed long``, nor will it ever handle a - wrapped C++ class with a user-defined implicit ``operator unsigned - int()`` conversion. Boost.Python's dynamic type conversion - registry allows users to add arbitrary conversion methods. - -================== - Library Overview -================== - -This section outlines some of the library's major features. Except as -neccessary to avoid confusion, details of library implementation are -omitted. - ------------------- - Exposing Classes ------------------- - -C++ classes and structs are exposed with a similarly-terse interface. -Given:: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -The following code will expose it in our extension module:: - - #include - BOOST_PYTHON_MODULE(hello) - { - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -Although this code has a certain pythonic familiarity, people -sometimes find the syntax bit confusing because it doesn't look like -most of the C++ code they're used to. All the same, this is just -standard C++. Because of their flexible syntax and operator -overloading, C++ and Python are great for defining domain-specific -(sub)languages -(DSLs), and that's what we've done in Boost.Python. To break it down:: - - class_("World") - -constructs an unnamed object of type ``class_`` and passes -``"World"`` to its constructor. This creates a new-style Python class -called ``World`` in the extension module, and associates it with the -C++ type ``World`` in the Boost.Python type conversion registry. We -might have also written:: - - class_ w("World"); - -but that would've been more verbose, since we'd have to name ``w`` -again to invoke its ``def()`` member function:: - - w.def("greet", &World::greet) - -There's nothing special about the location of the dot for member -access in the original example: C++ allows any amount of whitespace on -either side of a token, and placing the dot at the beginning of each -line allows us to chain as many successive calls to member functions -as we like with a uniform syntax. The other key fact that allows -chaining is that ``class_<>`` member functions all return a reference -to ``*this``. - -So the example is equivalent to:: - - class_ w("World"); - w.def("greet", &World::greet); - w.def("set", &World::set); - -It's occasionally useful to be able to break down the components of a -Boost.Python class wrapper in this way, but the rest of this article -will stick to the terse syntax. - -For completeness, here's the wrapped class in use: :: - - >>> import hello - >>> planet = hello.World() - >>> planet.set('howdy') - >>> planet.greet() - 'howdy' - -Constructors -============ - -Since our ``World`` class is just a plain ``struct``, it has an -implicit no-argument (nullary) constructor. Boost.Python exposes the -nullary constructor by default, which is why we were able to write: :: - - >>> planet = hello.World() - -However, well-designed classes in any language may require constructor -arguments in order to establish their invariants. Unlike Python, -where ``__init__`` is just a specially-named method, In C++ -constructors cannot be handled like ordinary member functions. In -particular, we can't take their address: ``&World::World`` is an -error. The library provides a different interface for specifying -constructors. Given:: - - struct World - { - World(std::string msg); // added constructor - ... - -we can modify our wrapping code as follows:: - - class_("World", init()) - ... - -of course, a C++ class may have additional constructors, and we can -expose those as well by passing more instances of ``init<...>`` to -``def()``:: - - class_("World", init()) - .def(init()) - ... - -Boost.Python allows wrapped functions, member functions, and -constructors to be overloaded to mirror C++ overloading. - -Data Members and Properties -=========================== - -Any publicly-accessible data members in a C++ class can be easily -exposed as either ``readonly`` or ``readwrite`` attributes:: - - class_("World", init()) - .def_readonly("msg", &World::msg) - ... - -and can be used directly in Python: :: - - >>> planet = hello.World('howdy') - >>> planet.msg - 'howdy' - -This does *not* result in adding attributes to the ``World`` instance -``__dict__``, which can result in substantial memory savings when -wrapping large data structures. In fact, no instance ``__dict__`` -will be created at all unless attributes are explicitly added from -Python. Boost.Python owes this capability to the new Python 2.2 type -system, in particular the descriptor interface and ``property`` type. - -In C++, publicly-accessible data members are considered a sign of poor -design because they break encapsulation, and style guides usually -dictate the use of "getter" and "setter" functions instead. In -Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, -``property`` mean that attribute access is just one more -well-encapsulated syntactic tool at the programmer's disposal. -Boost.Python bridges this idiomatic gap by making Python ``property`` -creation directly available to users. If ``msg`` were private, we -could still expose it as attribute in Python as follows:: - - class_("World", init()) - .add_property("msg", &World::greet, &World::set) - ... - -The example above mirrors the familiar usage of properties in Python -2.2+: :: - - >>> class World(object): - ... __init__(self, msg): - ... self.__msg = msg - ... def greet(self): - ... return self.__msg - ... def set(self, msg): - ... self.__msg = msg - ... msg = property(greet, set) - -Operator Overloading -==================== - -The ability to write arithmetic operators for user-defined types has -been a major factor in the success of both languages for numerical -computation, and the success of packages like NumPy_ attests to the -power of exposing operators in extension modules. Boost.Python -provides a concise mechanism for wrapping operator overloads. The -example below shows a fragment from a wrapper for the Boost rational -number library:: - - class_ >("rational_int") - .def(init()) // constructor, e.g. rational_int(3,4) - .def("numerator", &rational::numerator) - .def("denominator", &rational::denominator) - .def(-self) // __neg__ (unary minus) - .def(self + self) // __add__ (homogeneous) - .def(self * self) // __mul__ - .def(self + int()) // __add__ (heterogenous) - .def(int() + self) // __radd__ - ... - -The magic is performed using a simplified application of "expression -templates" [VELD1995]_, a technique originally developed for -optimization of high-performance matrix algebra expressions. The -essence is that instead of performing the computation immediately, -operators are overloaded to construct a type *representing* the -computation. In matrix algebra, dramatic optimizations are often -available when the structure of an entire expression can be taken into -account, rather than evaluating each operation "greedily". -Boost.Python uses the same technique to build an appropriate Python -method object based on expressions involving ``self``. - -.. _NumPy: http://www.pfdubois.com/numpy/ - -Inheritance -=========== - -C++ inheritance relationships can be represented to Boost.Python by adding -an optional ``bases<...>`` argument to the ``class_<...>`` template -parameter list as follows:: - - class_ >("Derived") - ... - -This has two effects: - -1. When the ``class_<...>`` is created, Python type objects - corresponding to ``Base1`` and ``Base2`` are looked up in - Boost.Python's registry, and are used as bases for the new Python - ``Derived`` type object, so methods exposed for the Python ``Base1`` - and ``Base2`` types are automatically members of the ``Derived`` - type. Because the registry is global, this works correctly even if - ``Derived`` is exposed in a different module from either of its - bases. - -2. C++ conversions from ``Derived`` to its bases are added to the - Boost.Python registry. Thus wrapped C++ methods expecting (a - pointer or reference to) an object of either base type can be - called with an object wrapping a ``Derived`` instance. Wrapped - member functions of class ``T`` are treated as though they have an - implicit first argument of ``T&``, so these conversions are - neccessary to allow the base class methods to be called for derived - objects. - -Of course it's possible to derive new Python classes from wrapped C++ -class instances. Because Boost.Python uses the new-style class -system, that works very much as for the Python built-in types. There -is one significant detail in which it differs: the built-in types -generally establish their invariants in their ``__new__`` function, so -that derived classes do not need to call ``__init__`` on the base -class before invoking its methods : :: - - >>> class L(list): - ... def __init__(self): - ... pass - ... - >>> L().reverse() - >>> - -Because C++ object construction is a one-step operation, C++ instance -data cannot be constructed until the arguments are available, in the -``__init__`` function: :: - - >>> class D(SomeBoostPythonClass): - ... def __init__(self): - ... pass - ... - >>> D().some_boost_python_method() - Traceback (most recent call last): - File "", line 1, in ? - TypeError: bad argument type for built-in operation - -This happened because Boost.Python couldn't find instance data of type -``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__`` -function masked construction of the base class. It could be corrected -by either removing ``D``'s ``__init__`` function or having it call -``SomeBoostPythonClass.__init__(...)`` explicitly. - -Virtual Functions -================= - -Deriving new types in Python from extension classes is not very -interesting unless they can be used polymorphically from C++. In -other words, Python method implementations should appear to override -the implementation of C++ virtual functions when called *through base -class pointers/references from C++*. Since the only way to alter the -behavior of a virtual function is to override it in a derived class, -the user must build a special derived class to dispatch a polymorphic -class' virtual functions:: - - // - // interface to wrap: - // - class Base - { - public: - virtual int f(std::string x) { return 42; } - virtual ~Base(); - }; - - int calls_f(Base const& b, std::string x) { return b.f(x); } - - // - // Wrapping Code - // - - // Dispatcher class - struct BaseWrap : Base - { - // Store a pointer to the Python object - BaseWrap(PyObject* self_) : self(self_) {} - PyObject* self; - - // Default implementation, for when f is not overridden - int f_default(std::string x) { return this->Base::f(x); } - // Dispatch implementation - int f(std::string x) { return call_method(self, "f", x); } - }; - - ... - def("calls_f", calls_f); - class_("Base") - .def("f", &Base::f, &BaseWrap::f_default) - ; - -Now here's some Python code which demonstrates: :: - - >>> class Derived(Base): - ... def f(self, s): - ... return len(s) - ... - >>> calls_f(Base(), 'foo') - 42 - >>> calls_f(Derived(), 'forty-two') - 9 - -Things to notice about the dispatcher class: - -* The key element which allows overriding in Python is the - ``call_method`` invocation, which uses the same global type - conversion registry as the C++ function wrapping does to convert its - arguments from C++ to Python and its return type from Python to C++. - -* Any constructor signatures you wish to wrap must be replicated with - an initial ``PyObject*`` argument - -* The dispatcher must store this argument so that it can be used to - invoke ``call_method`` - -* The ``f_default`` member function is needed when the function being - exposed is not pure virtual; there's no other way ``Base::f`` can be - called on an object of type ``BaseWrap``, since it overrides ``f``. - -Deeper Reflection on the Horizon? -================================= - -Admittedly, this formula is tedious to repeat, especially on a project -with many polymorphic classes. That it is neccessary reflects some -limitations in C++'s compile-time introspection capabilities: there's -no way to enumerate the members of a class and find out which are -virtual functions. At least one very promising project has been -started to write a front-end which can generate these dispatchers (and -other wrapping code) automatically from C++ headers. - -Pyste builds on GCC_XML_, which generates an XML version of GCC's -internal program representation. Since GCC is a highly-conformant C++ -compiler, this ensures correct handling of the most-sophisticated -template code and full access to the underlying type system. In -keeping with the Boost.Python philosophy, a Pyste interface -description is neither intrusive on the code being wrapped, nor -expressed in some unfamiliar language: instead it is a 100% pure -Python script. If Pyste is successful it will mark a move away from -wrapping everything directly in C++ for many of our users. We expect -that soon, not only our users but the Boost.Python developers -themselves will be "thinking hybrid" about their own code. - -.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html - ---------------- - Serialization ---------------- - -*Serialization* is the process of converting objects in memory to a -form that can be stored on disk or sent over a network connection. The -serialized object (most often a plain string) can be retrieved and -converted back to the original object. A good serialization system will -automatically convert entire object hierarchies. Python's standard -``pickle`` module is just such a system. It leverages the language's strong -runtime introspection facilities for serializing practically arbitrary -user-defined objects. With a few simple and unintrusive provisions this -powerful machinery can be extended to also work for wrapped C++ objects. -Here is an example:: - - #include - - struct World - { - World(std::string a_msg) : msg(a_msg) {} - std::string greet() const { return msg; } - std::string msg; - }; - - #include - using namespace boost::python; - - struct World_picklers : pickle_suite - { - static tuple - getinitargs(World const& w) { return make_tuple(w.greet()); } - }; - - BOOST_PYTHON_MODULE(hello) - { - class_("World", init()) - .def("greet", &World::greet) - .def_pickle(World_picklers()) - ; - } - -Now let's create a ``World`` object and put it to rest on disk:: - - >>> import hello - >>> import pickle - >>> a_world = hello.World("howdy") - >>> pickle.dump(a_world, open("my_world", "w")) - -In a potentially *different script* on a potentially *different -computer* with a potentially *different operating system*:: - - >>> import pickle - >>> resurrected_world = pickle.load(open("my_world", "r")) - >>> resurrected_world.greet() - 'howdy' - -Of course the ``cPickle`` module can also be used for faster -processing. - -Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol -defined in the standard Python documentation. Like a __getinitargs__ -function in Python, the pickle_suite's getinitargs() is responsible for -creating the argument tuple that will be use to reconstruct the pickled -object. The other elements of the Python pickling protocol, -__getstate__ and __setstate__ can be optionally provided via C++ -getstate and setstate functions. C++'s static type system allows the -library to ensure at compile-time that nonsensical combinations of -functions (e.g. getstate without setstate) are not used. - -Enabling serialization of more complex C++ objects requires a little -more work than is shown in the example above. Fortunately the -``object`` interface (see next section) greatly helps in keeping the -code manageable. - ------------------- - Object interface ------------------- - -Experienced 'C' language extension module authors will be familiar -with the ubiquitous ``PyObject*``, manual reference-counting, and the -need to remember which API calls return "new" (owned) references or -"borrowed" (raw) references. These constraints are not just -cumbersome but also a major source of errors, especially in the -presence of exceptions. - -Boost.Python provides a class ``object`` which automates reference -counting and provides conversion to Python from C++ objects of -arbitrary type. This significantly reduces the learning effort for -prospective extension module writers. - -Creating an ``object`` from any other type is extremely simple:: - - object s("hello, world"); // s manages a Python string - -``object`` has templated interactions with all other types, with -automatic to-python conversions. It happens so naturally that it's -easily overlooked:: - - object ten_Os = 10 * s[4]; // -> "oooooooooo" - -In the example above, ``4`` and ``10`` are converted to Python objects -before the indexing and multiplication operations are invoked. - -The ``extract`` class template can be used to convert Python objects -to C++ types:: - - double x = extract(o); - -If a conversion in either direction cannot be performed, an -appropriate exception is thrown at runtime. - -The ``object`` type is accompanied by a set of derived types -that mirror the Python built-in types such as ``list``, ``dict``, -``tuple``, etc. as much as possible. This enables convenient -manipulation of these high-level types from C++:: - - dict d; - d["some"] = "thing"; - d["lucky_number"] = 13; - list l = d.keys(); - -This almost looks and works like regular Python code, but it is pure -C++. Of course we can wrap C++ functions which accept or return -``object`` instances. - -.. ===================== - Development history - ===================== - - XXX Outline of development history to illustrate that the - library is mature. XXX - - This can be postponed for the PyConDC paper - -================= - Thinking hybrid -================= - -Because of the practical and mental difficulties of combining -programming languages, it is common to settle a single language at the -outset of any development effort. For many applications, performance -considerations dictate the use of a compiled language for the core -algorithms. Unfortunately, due to the complexity of the static type -system, the price we pay for runtime performance is often a -significant increase in development time. Experience shows that -writing maintainable C++ code usually takes longer and requires *far* -more hard-earned working experience than developing comparable Python -code. Even when developers are comfortable working exclusively in -compiled languages, they often augment their systems by some type of -ad hoc scripting layer for the benefit of their users without ever -availing themselves of the same advantages. - -Boost.Python enables us to *think hybrid*. Python can be used for -rapidly prototyping a new application; its ease of use and the large -pool of standard libraries give us a head start on the way to a -working system. If necessary, the working code can be used to -discover rate-limiting hotspots. To maximize performance these can -be reimplemented in C++, together with the Boost.Python bindings -needed to tie them back into the existing higher-level procedure. - -Of course, this *top-down* approach is less attractive if it is clear -from the start that many algorithms will eventually have to be -implemented in C++. Fortunately Boost.Python also enables us to -pursue a *bottom-up* approach. We have used this approach very -successfully in the development of a toolbox for scientific -applications. The toolbox started out mainly as a library of C++ -classes with Boost.Python bindings, and for a while the growth was -mainly concentrated on the C++ parts. However, as the toolbox is -becoming more complete, more and more newly added functionality can be -implemented in Python. - -.. image:: python_cpp_mix.png - -This figure shows the estimated ratio of newly added C++ and Python -code over time as new algorithms are implemented. We expect this -ratio to level out near 70% Python. Being able to solve new problems -mostly in Python rather than a more difficult statically typed -language is the return on our investment in Boost.Python. The ability -to access all of our code from Python allows a broader group of -developers to use it in the rapid development of new applications. - -============= - Conclusions -============= - -Boost.Python achieves seamless interoperability between two rich and -complimentary language environments. Because it leverages template -metaprogramming to introspect about types and functions, the user -never has to learn a third syntax: the interface definitions are -written in concise and maintainable C++. Also, the wrapping system -doesn't have to parse C++ headers or represent the type system: the -compiler does that work for us. - -Computationally intensive tasks play to the strengths of C++ and are -often impossible to implement efficiently in pure Python, while jobs -like serialization that are trivial in Python can be very difficult in -pure C++. Given the luxury of building a hybrid software system from -the ground up, we can approach design with new confidence and power. - -=========== - Citations -=========== - -.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report, - Vol. 7 No. 5 June 1995, pp. 26-31. - http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html diff --git a/doc/PyConDC_2003/bpl_mods.txt b/doc/PyConDC_2003/bpl_mods.txt deleted file mode 100644 index e243cda9..00000000 --- a/doc/PyConDC_2003/bpl_mods.txt +++ /dev/null @@ -1,908 +0,0 @@ -.. This is a comment. Note how any initial comments are moved by - transforms to after the document title, subtitle, and docinfo. - -.. Need intro and conclusion -.. Exposing classes - .. Constructors - .. Overloading - .. Properties and data members - .. Inheritance - .. Operators and Special Functions - .. Virtual Functions -.. Call Policies - -++++++++++++++++++++++++++++++++++++++++++++++ - Introducing Boost.Python (Extended Abstract) -++++++++++++++++++++++++++++++++++++++++++++++ - - -.. bibliographic fields (which also require a transform): - -:Author: David Abrahams -:Address: 45 Walnut Street - Somerville, MA 02143 -:Contact: dave@boost-consulting.com -:organization: `Boost Consulting`_ -:date: $Date$ -:status: This is a "work in progress" -:version: 1 -:copyright: Copyright David Abrahams 2002. All rights reserved - -:Dedication: - - For my girlfriend, wife, and partner Luann - -:abstract: - - This paper describes the Boost.Python library, a system for - C++/Python interoperability. - -.. meta:: - :keywords: Boost,python,Boost.Python,C++ - :description lang=en: C++/Python interoperability with Boost.Python - -.. contents:: Table of Contents -.. section-numbering:: - - -.. _`Boost Consulting`: http://www.boost-consulting.com - -============== - Introduction -============== - -Python and C++ are in many ways as different as two languages could -be: while C++ is usually compiled to machine-code, Python is -interpreted. Python's dynamic type system is often cited as the -foundation of its flexibility, while in C++ static typing is the -cornerstone of its efficiency. C++ has an intricate and difficult -meta-language to support compile-time polymorphism, while Python is -a uniform language with convenient runtime polymorphism. - -Yet for many programmers, these very differences mean that Python and -C++ complement one another perfectly. Performance bottlenecks in -Python programs can be rewritten in C++ for maximal speed, and -authors of powerful C++ libraries choose Python as a middleware -language for its flexible system integration capabilities. -Furthermore, the surface differences mask some strong similarities: - -* 'C'-family control structures (if, while, for...) - -* Support for object-orientation, functional programming, and generic - programming (these are both *multi-paradigm* programming languages.) - -* Comprehensive operator overloading facilities, recognizing the - importance of syntactic variability for readability and - expressivity. - -* High-level concepts such as collections and iterators. - -* High-level encapsulation facilities (C++: namespaces, Python: modules) - to support the design of re-usable libraries. - -* Exception-handling for effective management of error conditions. - -* C++ idioms in common use, such as handle/body classes and - reference-counted smart pointers mirror Python reference semantics. - -Python provides a rich 'C' API for writers of 'C' extension modules. -Unfortunately, using this API directly for exposing C++ type and -function interfaces to Python is much more tedious than it should be. -This is mainly due to the limitations of the 'C' language. Compared to -C++ and Python, 'C' has only very rudimentary abstraction facilities. -Support for exception-handling is completely missing. One important -undesirable consequence is that 'C' extension module writers are -required to manually manage Python reference counts. Another unpleasant -consequence is a very high degree of repetition of similar code in 'C' -extension modules. Of course highly redundant code does not only cause -frustration for the module writer, but is also very difficult to -maintain. - -The limitations of the 'C' API have lead to the development of a -variety of wrapping systems. SWIG_ is probably the most popular package -for the integration of C/C++ and Python. A more recent development is -the SIP_ package, which is specifically designed for interfacing Python -with the Qt_ graphical user interface library. Both SWIG and SIP -introduce a new specialized language for defining the inter-language -bindings. Of course being able to use a specialized language has -advantages, but having to deal with three different languages (Python, -C/C++ and the interface language) also introduces practical and mental -difficulties. The CXX_ package demonstrates an interesting alternative. -It shows that at least some parts of Python's 'C' API can be wrapped -and presented through a much more user-friendly C++ interface. However, -unlike SWIG and SIP, CXX does not include support for wrapping C++ -classes as new Python types. CXX is also no longer actively developed. - -In some respects Boost.Python combines ideas from SWIG and SIP with -ideas from CXX. Like SWIG and SIP, Boost.Python is a system for -wrapping C++ classes as new Python "built-in" types, and C/C++ -functions as Python functions. Like CXX, Boost.Python presents Python's -'C' API through a C++ interface. Boost.Python goes beyond the scope of -other systems with the unique support for C++ virtual functions that -are overrideable in Python, support for organizing extensions as Python -packages with a central registry for inter-language type conversions, -and a convenient mechanism for tying into Python's serialization engine -(pickle). Importantly, all this is achieved without introducing a new -syntax. Boost.Python leverages the power of C++ meta-programming -techniques to introspect about the C++ type system, and presents a -simple, IDL-like C++ interface for exposing C/C++ code in extension -modules. Boost.Python is a pure C++ library, the inter-language -bindings are defined in pure C++, and other than a C++ compiler only -Python itself is required to get started with Boost.Python. Last but -not least, Boost.Python is an unrestricted open source library. There -are no strings attached even for commercial applications. - -.. _SWIG: http://www.swig.org/ -.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php -.. _Qt: http://www.trolltech.com/ -.. _CXX: http://cxx.sourceforge.net/ - -=========================== - Boost.Python Design Goals -=========================== - -The primary goal of Boost.Python is to allow users to expose C++ -classes and functions to Python using nothing more than a C++ -compiler. In broad strokes, the user experience should be one of -directly manipulating C++ objects from Python. - -However, it's also important not to translate all interfaces *too* -literally: the idioms of each language must be respected. For -example, though C++ and Python both have an iterator concept, they are -expressed very differently. Boost.Python has to be able to bridge the -interface gap. - -It must be possible to insulate Python users from crashes resulting -from trivial misuses of C++ interfaces, such as accessing -already-deleted objects. By the same token the library should -insulate C++ users from low-level Python 'C' API, replacing -error-prone 'C' interfaces like manual reference-count management and -raw ``PyObject`` pointers with more-robust alternatives. - -Support for component-based development is crucial, so that C++ types -exposed in one extension module can be passed to functions exposed in -another without loss of crucial information like C++ inheritance -relationships. - -Finally, all wrapping must be *non-intrusive*, without modifying or -even seeing the original C++ source code. Existing C++ libraries have -to be wrappable by third parties who only have access to header files -and binaries. - -========================== - Hello Boost.Python World -========================== - -And now for a preview of Boost.Python, and how it improves on the raw -facilities offered by Python. Here's a function we might want to -expose:: - - char const* greet(unsigned x) - { - static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; - - if (x > 2) - throw std::range_error("greet: index out of range"); - - return msgs[x]; - } - -To wrap this function in standard C++ using the Python 'C' API, we'd -need something like this:: - - extern "C" // all Python interactions use 'C' linkage and calling convention - { - // Wrapper to handle argument/result conversion and checking - PyObject* greet_wrap(PyObject* args, PyObject * keywords) - { - int x; - if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments - { - char const* result = greet(x); // invoke wrapped function - return PyString_FromString(result); // convert result to Python - } - return 0; // error occurred - } - - // Table of wrapped functions to be exposed by the module - static PyMethodDef methods[] = { - { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" } - , { NULL, NULL, 0, NULL } // sentinel - }; - - // module initialization function - DL_EXPORT init_hello() - { - (void) Py_InitModule("hello", methods); // add the methods to the module - } - } - -Now here's the wrapping code we'd use to expose it with Boost.Python:: - - #include - using namespace boost::python; - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet, "return one of 3 parts of a greeting"); - } - -and here it is in action:: - - >>> import hello - >>> for x in range(3): - ... print hello.greet(x) - ... - hello - Boost.Python - world! - -Aside from the fact that the 'C' API version is much more verbose than -the BPL one, it's worth noting that it doesn't handle a few things -correctly: - -* The original function accepts an unsigned integer, and the Python - 'C' API only gives us a way of extracting signed integers. The - Boost.Python version will raise a Python exception if we try to pass - a negative number to ``hello.greet``, but the other one will proceed - to do whatever the C++ implementation does when converting an - negative integer to unsigned (usually wrapping to some very large - number), and pass the incorrect translation on to the wrapped - function. - -* That brings us to the second problem: if the C++ ``greet()`` - function is called with a number greater than 2, it will throw an - exception. Typically, if a C++ exception propagates across the - boundary with code generated by a 'C' compiler, it will cause a - crash. As you can see in the first version, there's no C++ - scaffolding there to prevent this from happening. Functions wrapped - by Boost.Python automatically include an exception-handling layer - which protects Python users by translating unhandled C++ exceptions - into a corresponding Python exception. - -* A slightly more-subtle limitation is that the argument conversion - used in the Python 'C' API case can only get that integer ``x`` in - *one way*. PyArg_ParseTuple can't convert Python ``long`` objects - (arbitrary-precision integers) which happen to fit in an ``unsigned - int`` but not in a ``signed long``, nor will it ever handle a - wrapped C++ class with a user-defined implicit ``operator unsigned - int()`` conversion. The BPL's dynamic type conversion registry - allows users to add arbitrary conversion methods. - -================== - Library Overview -================== - -This section outlines some of the library's major features. Except as -neccessary to avoid confusion, details of library implementation are -omitted. - -------------------------------------------- - The fundamental type-conversion mechanism -------------------------------------------- - -XXX This needs to be rewritten. - -Every argument of every wrapped function requires some kind of -extraction code to convert it from Python to C++. Likewise, the -function return value has to be converted from C++ to Python. -Appropriate Python exceptions must be raised if the conversion fails. -Argument and return types are part of the function's type, and much of -this tedium can be relieved if the wrapping system can extract that -information through introspection. - -Passing a wrapped C++ derived class instance to a C++ function -accepting a pointer or reference to a base class requires knowledge of -the inheritance relationship and how to translate the address of a base -class into that of a derived class. - ------------------- - Exposing Classes ------------------- - -C++ classes and structs are exposed with a similarly-terse interface. -Given:: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -The following code will expose it in our extension module:: - - #include - BOOST_PYTHON_MODULE(hello) - { - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -Although this code has a certain pythonic familiarity, people -sometimes find the syntax bit confusing because it doesn't look like -most of the C++ code they're used to. All the same, this is just -standard C++. Because of their flexible syntax and operator -overloading, C++ and Python are great for defining domain-specific -(sub)languages -(DSLs), and that's what we've done in BPL. To break it down:: - - class_("World") - -constructs an unnamed object of type ``class_`` and passes -``"World"`` to its constructor. This creates a new-style Python class -called ``World`` in the extension module, and associates it with the -C++ type ``World`` in the BPL type conversion registry. We might have -also written:: - - class_ w("World"); - -but that would've been more verbose, since we'd have to name ``w`` -again to invoke its ``def()`` member function:: - - w.def("greet", &World::greet) - -There's nothing special about the location of the dot for member -access in the original example: C++ allows any amount of whitespace on -either side of a token, and placing the dot at the beginning of each -line allows us to chain as many successive calls to member functions -as we like with a uniform syntax. The other key fact that allows -chaining is that ``class_<>`` member functions all return a reference -to ``*this``. - -So the example is equivalent to:: - - class_ w("World"); - w.def("greet", &World::greet); - w.def("set", &World::set); - -It's occasionally useful to be able to break down the components of a -Boost.Python class wrapper in this way, but the rest of this paper -will tend to stick to the terse syntax. - -For completeness, here's the wrapped class in use: - ->>> import hello ->>> planet = hello.World() ->>> planet.set('howdy') ->>> planet.greet() -'howdy' - -Constructors -============ - -Since our ``World`` class is just a plain ``struct``, it has an -implicit no-argument (nullary) constructor. Boost.Python exposes the -nullary constructor by default, which is why we were able to write: - ->>> planet = hello.World() - -However, well-designed classes in any language may require constructor -arguments in order to establish their invariants. Unlike Python, -where ``__init__`` is just a specially-named method, In C++ -constructors cannot be handled like ordinary member functions. In -particular, we can't take their address: ``&World::World`` is an -error. The library provides a different interface for specifying -constructors. Given:: - - struct World - { - World(std::string msg); // added constructor - ... - -we can modify our wrapping code as follows:: - - class_("World", init()) - ... - -of course, a C++ class may have additional constructors, and we can -expose those as well by passing more instances of ``init<...>`` to -``def()``:: - - class_("World", init()) - .def(init()) - ... - -Boost.Python allows wrapped functions, member functions, and -constructors to be overloaded to mirror C++ overloading. - -Data Members and Properties -=========================== - -Any publicly-accessible data members in a C++ class can be easily -exposed as either ``readonly`` or ``readwrite`` attributes:: - - class_("World", init()) - .def_readonly("msg", &World::msg) - ... - -and can be used directly in Python: - ->>> planet = hello.World('howdy') ->>> planet.msg -'howdy' - -This does *not* result in adding attributes to the ``World`` instance -``__dict__``, which can result in substantial memory savings when -wrapping large data structures. In fact, no instance ``__dict__`` -will be created at all unless attributes are explicitly added from -Python. BPL owes this capability to the new Python 2.2 type system, -in particular the descriptor interface and ``property`` type. - -In C++, publicly-accessible data members are considered a sign of poor -design because they break encapsulation, and style guides usually -dictate the use of "getter" and "setter" functions instead. In -Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, -``property`` mean that attribute access is just one more -well-encapsulated syntactic tool at the programmer's disposal. BPL -bridges this idiomatic gap by making Python ``property`` creation -directly available to users. So if ``msg`` were private, we could -still expose it as attribute in Python as follows:: - - class_("World", init()) - .add_property("msg", &World::greet, &World::set) - ... - -The example above mirrors the familiar usage of properties in Python -2.2+: - ->>> class World(object): -... __init__(self, msg): -... self.__msg = msg -... def greet(self): -... return self.__msg -... def set(self, msg): -... self.__msg = msg -... msg = property(greet, set) - -Operators and Special Functions -=============================== - -The ability to write arithmetic operators for user-defined types that -C++ and Python both allow the definition of has been a major factor in -the popularity of both languages for scientific computing. The -success of packages like NumPy attests to the power of exposing -operators in extension modules. In this example we'll wrap a class -representing a position in a large file:: - - class FilePos { /*...*/ }; - - // Linear offset - FilePos operator+(FilePos, int); - FilePos operator+(int, FilePos); - FilePos operator-(FilePos, int); - - // Distance between two FilePos objects - int operator-(FilePos, FilePos); - - // Offset with assignment - FilePos& operator+=(FilePos&, int); - FilePos& operator-=(FilePos&, int); - - // Comparison - bool operator<(FilePos, FilePos); - -The wrapping code looks like this:: - - class_("FilePos") - .def(self + int()) // __add__ - .def(int() + self) // __radd__ - .def(self - int()) // __sub__ - - .def(self - self) // __sub__ - - .def(self += int()) // __iadd__ - .def(self -= int()) // __isub__ - - .def(self < self); // __lt__ - ; - -The magic is performed using a simplified application of "expression -templates" [VELD1995]_, a technique originally developed by for -optimization of high-performance matrix algebra expressions. The -essence is that instead of performing the computation immediately, -operators are overloaded to construct a type *representing* the -computation. In matrix algebra, dramatic optimizations are often -available when the structure of an entire expression can be taken into -account, rather than processing each operation "greedily". -Boost.Python uses the same technique to build an appropriate Python -callable object based on an expression involving ``self``, which is -then added to the class. - -Inheritance -=========== - -C++ inheritance relationships can be represented to Boost.Python by adding -an optional ``bases<...>`` argument to the ``class_<...>`` template -parameter list as follows:: - - class_ >("Derived") - ... - -This has two effects: - -1. When the ``class_<...>`` is created, Python type objects - corresponding to ``Base1`` and ``Base2`` are looked up in the BPL - registry, and are used as bases for the new Python ``Derived`` type - object [#mi]_, so methods exposed for the Python ``Base1`` and - ``Base2`` types are automatically members of the ``Derived`` type. - Because the registry is global, this works correctly even if - ``Derived`` is exposed in a different module from either of its - bases. - -2. C++ conversions from ``Derived`` to its bases are added to the - Boost.Python registry. Thus wrapped C++ methods expecting (a - pointer or reference to) an object of either base type can be - called with an object wrapping a ``Derived`` instance. Wrapped - member functions of class ``T`` are treated as though they have an - implicit first argument of ``T&``, so these conversions are - neccessary to allow the base class methods to be called for derived - objects. - -Of course it's possible to derive new Python classes from wrapped C++ -class instances. Because Boost.Python uses the new-style class -system, that works very much as for the Python built-in types. There -is one significant detail in which it differs: the built-in types -generally establish their invariants in their ``__new__`` function, so -that derived classes do not need to call ``__init__`` on the base -class before invoking its methods : - ->>> class L(list): -... def __init__(self): -... pass -... ->>> L().reverse() ->>> - -Because C++ object construction is a one-step operation, C++ instance -data cannot be constructed until the arguments are available, in the -``__init__`` function: - ->>> class D(SomeBPLClass): -... def __init__(self): -... pass -... ->>> D().some_bpl_method() -Traceback (most recent call last): - File "", line 1, in ? -TypeError: bad argument type for built-in operation - -This happened because Boost.Python couldn't find instance data of type -``SomeBPLClass`` within the ``D`` instance; ``D``'s ``__init__`` -function masked construction of the base class. It could be corrected -by either removing ``D``'s ``__init__`` function or having it call -``SomeBPLClass.__init__(...)`` explicitly. - -Virtual Functions -================= - -Deriving new types in Python from extension classes is not very -interesting unless they can be used polymorphically from C++. In -other words, Python method implementations should appear to override -the implementation of C++ virtual functions when called *through base -class pointers/references from C++*. Since the only way to alter the -behavior of a virtual function is to override it in a derived class, -the user must build a special derived class to dispatch a polymorphic -class' virtual functions:: - - // - // interface to wrap: - // - class Base - { - public: - virtual int f(std::string x) { return 42; } - virtual ~Base(); - }; - - int calls_f(Base const& b, std::string x) { return b.f(x); } - - // - // Wrapping Code - // - - // Dispatcher class - struct BaseWrap : Base - { - // Store a pointer to the Python object - BaseWrap(PyObject* self_) : self(self_) {} - PyObject* self; - - // Default implementation, for when f is not overridden - int f_default(std::string x) { return this->Base::f(x); } - // Dispatch implementation - int f(std::string x) { return call_method(self, "f", x); } - }; - - ... - def("calls_f", calls_f); - class_("Base") - .def("f", &Base::f, &BaseWrap::f_default) - ; - -Now here's some Python code which demonstrates: - ->>> class Derived(Base): -... def f(self, s): -... return len(s) -... ->>> calls_f(Base(), 'foo') -42 ->>> calls_f(Derived(), 'forty-two') -9 - -Things to notice about the dispatcher class: - -* The key element which allows overriding in Python is the - ``call_method`` invocation, which uses the same global type - conversion registry as the C++ function wrapping does to convert its - arguments from C++ to Python and its return type from Python to C++. - -* Any constructor signatures you wish to wrap must be replicated with - an initial ``PyObject*`` argument - -* The dispatcher must store this argument so that it can be used to - invoke ``call_method`` - -* The ``f_default`` member function is needed when the function being - exposed is not pure virtual; there's no other way ``Base::f`` can be - called on an object of type ``BaseWrap``, since it overrides ``f``. - -Admittedly, this formula is tedious to repeat, especially on a project -with many polymorphic classes; that it is neccessary reflects -limitations in C++'s compile-time reflection capabilities. Several -efforts are underway to write front-ends for Boost.Python which can -generate these dispatchers (and other wrapping code) automatically. -If these are successful it will mark a move away from wrapping -everything directly in pure C++ for many of our users. - ---------------- - Serialization ---------------- - -*Serialization* is the process of converting objects in memory to a -form that can be stored on disk or sent over a network connection. The -serialized object (most often a plain string) can be retrieved and -converted back to the original object. A good serialization system will -automatically convert entire object hierarchies. Python's standard -``pickle`` module is such a system. It leverages the language's strong -runtime introspection facilities for serializing practically arbitrary -user-defined objects. With a few simple and unintrusive provisions this -powerful machinery can be extended to also work for wrapped C++ objects. -Here is an example:: - - #include - - struct World - { - World(std::string a_msg) : msg(a_msg) {} - std::string greet() const { return msg; } - std::string msg; - }; - - #include - using namespace boost::python; - - struct World_picklers : pickle_suite - { - static tuple - getinitargs(World const& w) { return make_tuple(w.greet()); } - }; - - BOOST_PYTHON_MODULE(hello) - { - class_("World", init()) - .def("greet", &World::greet) - .def_pickle(World_picklers()) - ; - } - -Now let's create a ``World`` object and put it to rest on disk:: - - >>> import hello - >>> import pickle - >>> a_world = hello.World("howdy") - >>> pickle.dump(a_world, open("my_world", "w")) - -In a potentially *different script* on a potentially *different -computer* with a potentially *different operating system*:: - - >>> import pickle - >>> resurrected_world = pickle.load(open("my_world", "r")) - >>> resurrected_world.greet() - 'howdy' - -Of course the ``cPickle`` module can also be used for faster -processing. - -Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol -defined in the standard Python documentation. There is a one-to-one -correspondence between the standard pickling methods (``__getinitargs__``, -``__getstate__``, ``__setstate__``) and the functions defined by the -user in the class derived from ``pickle_suite`` (``getinitargs``, -``getstate``, ``setstate``). The ``class_::def_pickle()`` member function -is used to establish the Python bindings for all user-defined functions -simultaneously. Correct signatures for these functions are enforced at -compile time. Non-sensical combinations of the three pickle functions -are also rejected at compile time. These measures are designed to -help the user in avoiding obvious errors. - -Enabling serialization of more complex C++ objects requires a little -more work than is shown in the example above. Fortunately the -``object`` interface (see next section) greatly helps in keeping the -code manageable. - ------------------- - Object interface ------------------- - -Experienced extension module authors will be familiar with the 'C' view -of Python objects, the ubiquitous ``PyObject*``. Most if not all Python -'C' API functions involve ``PyObject*`` as arguments or return type. A -major complication is the raw reference counting interface presented to -the 'C' programmer. E.g. some API functions return *new references* and -others return *borrowed references*. It is up to the extension module -writer to properly increment and decrement reference counts. This -quickly becomes cumbersome and error prone, especially if there are -multiple execution paths. - -Boost.Python provides a type ``object`` which is essentially a high -level wrapper around ``PyObject*``. ``object`` automates reference -counting as much as possible. It also provides the facilities for -converting arbitrary C++ types to Python objects and vice versa. -This significantly reduces the learning effort for prospective -extension module writers. - -Creating an ``object`` from any other type is extremely simple:: - - object o(3); - -``object`` has templated interactions with all other types, with -automatic to-python conversions. It happens so naturally that it's -easily overlooked. - -The ``extract`` class template can be used to convert Python objects -to C++ types:: - - double x = extract(o); - -All registered user-defined conversions are automatically accessible -through the ``object`` interface. With reference to the ``World`` class -defined in previous examples:: - - object as_python_object(World("howdy")); - World back_as_c_plus_plus_object = extract(as_python_object); - -If a C++ type cannot be converted to a Python object an appropriate -exception is thrown at runtime. Similarly, an appropriate exception is -thrown if a C++ type cannot be extracted from a Python object. -``extract`` provides facilities for avoiding exceptions if this is -desired. - -The ``object::attr()`` member function is available for accessing -and manipulating attributes of Python objects. For example:: - - object planet(World()); - planet.attr("set")("howdy"); - -``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is -converted to a Python string object which is then passed as an argument -to the ``set`` method. - -The ``object`` type is accompanied by a set of derived types -that mirror the Python built-in types such as ``list``, ``dict``, -``tuple``, etc. as much as possible. This enables convenient -manipulation of these high-level types from C++:: - - dict d; - d["some"] = "thing"; - d["lucky_number"] = 13; - list l = d.keys(); - -This almost looks and works like regular Python code, but it is pure C++. - -================= - Thinking hybrid -================= - -For many applications runtime performance considerations are very -important. This is particularly true for most scientific applications. -Often the performance considerations dictate the use of a compiled -language for the core algorithms. Traditionally the decision to use a -particular programming language is an exclusive one. Because of the -practical and mental difficulties of combining different languages many -systems are written in just one language. This is quite unfortunate -because the price payed for runtime performance is typically a -significant overhead due to static typing. For example, our experience -shows that developing maintainable C++ code is typically much more -time-consuming and requires much more hard-earned working experience -than developing useful Python code. A related observation is that many -compiled packages are augmented by some type of rudimentary scripting -layer. These ad hoc solutions clearly show that many times a compiled -language alone does not get the job done. On the other hand it is also -clear that a pure Python implementation is too slow for numerically -intensive production code. - -Boost.Python enables us to *think hybrid* when developing new -applications. Python can be used for rapidly prototyping a -new application. Python's ease of use and the large pool of standard -libraries give us a head start on the way to a first working system. If -necessary, the working procedure can be used to discover the -rate-limiting algorithms. To maximize performance these can be -reimplemented in C++, together with the Boost.Python bindings needed to -tie them back into the existing higher-level procedure. - -Of course, this *top-down* approach is less attractive if it is clear -from the start that many algorithms will eventually have to be -implemented in a compiled language. Fortunately Boost.Python also -enables us to pursue a *bottom-up* approach. We have used this approach -very successfully in the development of a toolbox for scientific -applications (scitbx) that we will describe elsewhere. The toolbox -started out mainly as a library of C++ classes with Boost.Python -bindings, and for a while the growth was mainly concentrated on the C++ -parts. However, as the toolbox is becoming more complete, more and more -newly added functionality can be implemented in Python. We expect this -trend to continue, as illustrated qualitatively in this figure: - -.. image:: python_cpp_mix.png - -This figure shows the ratio of newly added C++ and Python code over -time as new algorithms are implemented. We expect this ratio to level -out near 70% Python. The increasing ability to solve new problems -mostly with the easy-to-use Python language rather than a necessarily -more arcane statically typed language is the return on the investment -of learning how to use Boost.Python. The ability to solve some problems -entirely using only Python will enable a larger group of people to -participate in the rapid development of new applications. - -============= - Conclusions -============= - -The examples in this paper illustrate that Boost.Python enables -seamless interoperability between C++ and Python. Importantly, this is -achieved without introducing a third syntax: the Python/C++ interface -definitions are written in pure C++. This avoids any problems with -parsing the C++ code to be interfaced to Python, yet the interface -definitions are concise and maintainable. Freed from most of the -development-time penalties of crossing a language boundary, software -designers can take full advantage of two rich and complimentary -language environments. In practice it turns out that some things are -very difficult to do with pure Python/C (e.g. an efficient array -library with an intuitive interface in the compiled language) and -others are very difficult to do with pure C++ (e.g. serialization). -If one has the luxury of being able to design a software system as a -hybrid system from the ground up there are many new ways of avoiding -road blocks in one language or the other. - -.. I'm not ready to give up on all of this quite yet - -.. Perhaps one day we'll have a language with the simplicity and - expressive power of Python and the compile-time muscle of C++. Being - able to take advantage of all of these facilities without paying the - mental and development-time penalties of crossing a language barrier - would bring enormous benefits. Until then, interoperability tools - like Boost.Python can help lower the barrier and make the benefits of - both languages more accessible to both communities. - -=========== - Footnotes -=========== - -.. [#mi] For hard-core new-style class/extension module writers it is - worth noting that the normal requirement that all extension classes - with data form a layout-compatible single-inheritance chain is - lifted for Boost.Python extension classes. Clearly, either - ``Base1`` or ``Base2`` has to occupy a different offset in the - ``Derived`` class instance. This is possible because the wrapped - part of BPL extension class instances is never assumed to have a - fixed offset within the wrapper. - -=========== - Citations -=========== - -.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report, - Vol. 7 No. 5 June 1995, pp. 26-31. - http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html diff --git a/doc/PyConDC_2003/default.css b/doc/PyConDC_2003/default.css deleted file mode 100644 index 2e1fddb9..00000000 --- a/doc/PyConDC_2003/default.css +++ /dev/null @@ -1,188 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:date: $Date$ -:version: $Revision$ -:copyright: This stylesheet has been placed in the public domain. - -Default cascading style sheet for the HTML output of Docutils. -*/ - -.first { - margin-top: 0 } - -.last { - margin-bottom: 0 } - -a.toc-backref { - text-decoration: none ; - color: black } - -dd { - margin-bottom: 0.5em } - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { - margin: 2em ; - border: medium outset ; - padding: 1em } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif } - -div.hint p.admonition-title, div.important p.admonition-title, -div.note p.admonition-title, div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif } - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - font-size: smaller } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1.title { - text-align: center } - -h2.subtitle { - text-align: center } - -hr { - width: 75% } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.label { - white-space: nowrap } - -p.topic-title { - font-weight: bold } - -pre.address { - margin-bottom: 0 ; - margin-top: 0 ; - font-family: serif ; - font-size: 100% } - -pre.line-block { - font-family: serif ; - font-size: 100% } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #eeeeee } - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.interpreted { - font-family: sans-serif } - -span.option-argument { - font-style: italic } - -span.pre { - white-space: pre } - -span.problematic { - color: red } - -table { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.citation { - border-left: solid thin gray ; - padding-left: 0.5ex } - -table.docinfo { - margin: 2em 4em } - -table.footnote { - border-left: solid thin black ; - padding-left: 0.5ex } - -td, th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: top } - -th.docinfo-name, th.field-name { - font-weight: bold ; - text-align: left ; - white-space: nowrap } - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - font-size: 100% } - -tt { - background-color: #eeeeee } - -ul.auto-toc { - list-style-type: none } diff --git a/doc/PyConDC_2003/python_cpp_mix.png b/doc/PyConDC_2003/python_cpp_mix.png deleted file mode 100755 index fd74cbb2..00000000 Binary files a/doc/PyConDC_2003/python_cpp_mix.png and /dev/null differ diff --git a/doc/boost.css b/doc/boost.css deleted file mode 100644 index cf5c8a97..00000000 --- a/doc/boost.css +++ /dev/null @@ -1,59 +0,0 @@ -H1 -{ - FONT-SIZE: 200% - COLOR: #00007f -} -H2 -{ - FONT-SIZE: 150%; -} -H3 -{ - FONT-SIZE: 125%; -} -H4 -{ - FONT-SIZE: 108%; -} -BODY -{ - FONT-SIZE: 100%; - BACKGROUND-COLOR: #ffffff -} -PRE -{ - MARGIN-LEFT: 2pc; - FONT-SIZE: 80%; - BACKGROUND-COLOR: #dfffff -} -CODE -{ - FONT-SIZE: 95%; - white-space: pre -} -.index -{ - TEXT-ALIGN: left -} -.page-index -{ - TEXT-ALIGN: left -} -.definition -{ - TEXT-ALIGN: left -} -.footnote -{ - FONT-SIZE: 66%; - VERTICAL-ALIGN: super; - TEXT-DECORATION: none -} -.function-semantics -{ - CLEAR: left -} -.metafunction-semantics -{ - CLEAR: left -} diff --git a/doc/building.html b/doc/building.html deleted file mode 100644 index 2a65a6db..00000000 --- a/doc/building.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - - - - Boost.Python - Building and Testing - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Building and Testing

-
-
- -

Contents

- -
-
Requirements
- -
Building Boost.Python
- -
-
-
Configuration
- -
Results
- -
Notes for Cygwin GCC Users
- -
Testing
-
-
- -
Building your Extension Module
- -
-
-
The Easy Way
- -
Building your module outside the Boost - project tree
-
-
- -
Build Variants
- -
Building Using the Microsoft Visual Studio - IDE
-
-
- -

Requirements

- Boost.Python version 2 requires Python 2.2 or newer. An unsupported archive of - Boost.Python version 1, which works with versions of Python since 1.5.2, - is available here. - -

Building Boost.Python

- -

Normally, Boost.Python extension modules must be linked with the - boost_python shared library. In special circumstances you - may want to link to a static version of the boost_python - library, but if multiple Boost.Pythone extension modules are used - together, it will prevent sharing of types across extension modules, and - consume extra code space. To build boost_python, use Boost.Build in the usual way - from the libs/python/build subdirectory of your boost - installation (if you have already built boost from the top level this may - have no effect, since the work is already done).

- -

Configuration

- You may need to configure the following variables to point Boost.Build at - your Python installation: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variable NameSemanticsDefaultNotes
PYTHON_ROOTThe root directory of your Python installationWindows: c:/tools/python - Unix: /usr/localOn Unix, this is the --with-prefix= directory used - to configure Python
PYTHON_VERSIONThe The 2-part python Major.Minor version number2.2Be sure not to include a third number, e.g. not - "2.2.1", even if that's the version you have.
PYTHON_INCLUDESpath to Python #include directoriesAutoconfigured from PYTHON_ROOT
PYTHON_LIB_PATHpath to Python library object.Autoconfigured from PYTHON_ROOT
CYGWIN_PYTHON_[DEBUG_]VERSIONThe version of python being used under Cygwin. $(PYTHON_VERSION) - - Use only when building with Cygwin GCC. This and the following - settings are useful when building with multiple toolsets on - Windows, since Cygwin GCC requires a different build of - Python.
CYGWIN_PYTHON_[DEBUG_]ROOTunix-style path containing the include/ - directory containing - python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h. $(PYTHON_ROOT) - - Use only when building with Cygwin GCC.
CYGWIN_PYTHON_[DEBUG_]LIB_PATHpath containing the user's Cygwin Python import lib - libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.aAutoconfigured from CYGWIN_PYTHON_ROOTUse only when building with Cygwin GCC.
CYGWIN_PYTHON_[DEBUG_]DLL_PATHpath containing the user's Cygwin Python dll - (libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll)/binUse only when building with Cygwin GCC.
- -

Notes for Cygwin GCC Users

- -

If you are using Cygwin GCC to build extension modules, you must use a - Cygwin build of Python. The regular Win32 Python installation that you - can download from python.org will not - work with your compiler because the dynamic linking conventions are - different (you can use MinGW GCC if - you want to build extension modules which are compatible with a stock - Win32 Python). The Cygwin installer may be able to install an appropriate - version of Python, or you can follow the traditional Unix installation - process to build Python from source.

- -

The special build configuration variables listed above as "Cygwin - only" make it possible to use a regular Win32 build of bjam to build and - test Boost.Python and Boost.Python extensions using Cygwin GCC and - targeting a Cygwin build of Python.

- -

Results

- -

The build process will create a - libs/python/build/bin-stage subdirectory of the boost root - (or of $(ALL_LOCATE_TARGET), if you have set that variable), - containing the built libraries. The libraries are actually built to - unique directories for each toolset and variant elsewhere in the - filesystem, and copied to the bin-stage directory as a - convenience, so if you build with multiple toolsets at once, the product - of later toolsets will overwrite that of earlier toolsets in - bin-stage.

- -

Testing

- -

To build and test Boost.Python, start from the - libs/python/test directory and invoke

- -
-
-bjam -sTOOLS=toolset test
-
-
- This will update all of the Boost.Python v1 test and example targets. The - tests are relatively quiet by default. To get more-verbose output, you - might try - -
-
-bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS=-v test
-
-
- which will print each test's Python code with the expected output as it - passes. - -

Building your Extension Module

- Though there are other approaches, the best way to build an extension - module using Boost.Python is with Boost.Build. If you have to use another - build system, you should use Boost.Build at least once with the - "-n" option so you can see the command-lines it uses, - and replicate them. You are likely to run into compilation or linking - problems otherwise. - -

The Easy Way

- Until Boost.Build v2 is released, cross-project build dependencies are - not supported, so it works most smoothly if you add a new subproject to - your boost installation. The libs/python/example - subdirectory of your boost installation contains a minimal example (along - with many extra sources). To copy the example subproject: - -
    -
  1. Create a new subdirectory in, libs/python, say - libs/python/my_project.
  2. - -
  3. Copy libs/python/example/Jamfile to your new - directory.
  4. - -
  5. Edit the Jamfile as appropriate for your project. You'll want to - change the "subproject" rule invocation at the top, and - the names of some of the source files and/or targets.
  6. -
- The instructions above for testing Boost.Python - apply equally to your new extension modules in this subproject. - -

Building your module outside the Boost project - tree

- If you can't (or don't wish to) modify your boost installation, the - alternative is to create your own Boost.Build project. A similar example - you can use as a starting point is available in this archive. You'll need to edit the - Jamfile and Jamrules files, depending on the relative location of your - Boost installation and the new project. Note that automatic testing of - extension modules is not available in this configuration. - -

Build Variants

- Three variant - configurations of all python-related targets are supported, and can be - selected by setting the BUILD - variable: - -
    -
  • release (optimization, -DNDEBUG)
  • - -
  • debug (no optimization -D_DEBUG)
  • - -
  • debug-python (no optimization, -D_DEBUG - -DBOOST_DEBUG_PYTHON)
  • -
- -

The first two variants of the boost_python library are - built by default, and are compatible with the default Python - distribution. The debug-python variant corresponds to a - specially-built debugging version of Python. On Unix platforms, this - python is built by adding --with-pydebug when configuring - the Python build. On Windows, the debugging version of Python is - generated by the "Win32 Debug" target of the PCBuild.dsw - Visual C++ 6.0 project in the PCBuild subdirectory of your - Python distribution. Extension modules built with Python debugging - enabled are not link-compatible with a non-debug build of Python. - Since few people actually have a debug build of Python (it doesn't come - with the standard distribution), the normal debug variant - builds modules which are compatible with ordinary Python.

- -

On many windows compilers, when extension modules are built with - -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 - unless BOOST_DEBUG_PYTHON is - defined.

- -

If you want the extra runtime checks available with the debugging - version of the library, #define BOOST_DEBUG_PYTHON to re-enable - python debuggin, and link with the debug-python variant of - boost_python.

- -

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

- -

Building Using the Microsoft Visual Studio - IDE

- -

For the those of you who feel more comfortable in the IDE world, a - workspace and project file have been included in the libs/python/build/VisualStudio subdirectory. - It builds release and debug versions of the Boost.Python libraries and - places them and the same directory as Jamfile build does, though the - intermediate object files are placed in a different directory. The files - have been created using Microsoft Visual C++ version 6, but they should - work for later versions as well. You will need to tell the IDE where to - find the Python Include/ and Libs/ directories. - Under Tools>Options>Directories, add an entry for the Python - include dir (i.e. c:/Python22/Include), and one for the Lib - (i.e. c:/Python/Libs. Make sure it is Libs with - an "s" and not just Lib).

- -

Using the IDE for you own projects

- -

Building your own projects using the IDE is slightly more complicated. - Firstly, you need to make sure that the project you create as the right - kind. It should be a "Win32 Dynamic-Link Library". The default one that - Visual Studio 6 creates needs some modifications: turn on RTTI, and - change the debug and release builds to use the respective debug and - release Multithreaded DLL versions. You should probably turn off - incremental linking too -- I believe it a bit flaky. If you do this, then - change the "Debug Info" to "Program Database" to get rid of the Edit and - Continue warning.

- -

You'll need to add the Boost root directory under - Tools>Options>Directories to get your code compiling. To - make it link, add the above boost_python.dsp file to your - workspace, and make your project depend upon it (under - Project>Dependencies). You should be able to build now.

- -

Lastly, go to the Project Settings>Debug Page and add the - Python.exe as the executable for the project. Set a startup - directory, and make sure that your current project's output dll, the - boost_python.dll and the python22.dll are on - the current PATH. If you have a python script that tests - your dll, then add it in the "Program Arguments". Now, if all went well, - you should be able to hit the Run (F5) button, and debug your code.

- -
- The Visual Studio project files are graciously contributed and - maintained by Brett - Calcott. -
-
- -

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

- -

Updated: 29 December, 2002 (David Abrahams)

- - - diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 6e585a44..00000000 --- a/doc/index.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - Boost.Python - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Index

-
-
- -

Synopsis

- Welcome to version 2 of Boost.Python, a C++ library which enables - seamless interoperability between C++ and the Python programming language. The new version - has been rewritten from the ground up, with a more convenient and - flexible interface, and many new capabilities, including support for: - -
    -
  • References and Pointers
  • - -
  • Globally Registered Type Coercions
  • - -
  • Automatic Cross-Module Type Conversions
  • - -
  • Efficient Function Overloading
  • - -
  • C++ to Python Exception Translation
  • - -
  • Default Arguments
  • - -
  • Keyword Arguments
  • - -
  • Manipulating Python objects in C++
  • - -
  • Exporting C++ Iterators as Python Iterators
  • - -
  • Documentation Strings
  • -
- The development of these features was funded in part by grants to Boost Consulting from the Lawrence Livermore National Laboratories - and by the Computational Crystallography - Initiative at Lawrence Berkeley National Laboratories. -
- -

Contents

- -
-
Tutorial Introduction
- -
Building and Testing
- -
Reference Manual
- -
Configuration Information
- -
Known Working Platforms and - Compilers
- -
Definitions
- -
Projects using Boost.Python
- -
Support Resources
- -
Frequently Asked Questions (FAQs)
- -
Pyste (Boost.Python code generator)
- -
News/Change Log
- -
LLNL Progress Reports
- -
Acknowledgments
-
-
- -

Revised - - 17 November, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/new-conversions.html b/doc/new-conversions.html deleted file mode 100644 index a5fe0c73..00000000 --- a/doc/new-conversions.html +++ /dev/null @@ -1,328 +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 - 13 November, 2002 -

-

© 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/news.html b/doc/news.html deleted file mode 100644 index 8ab97245..00000000 --- a/doc/news.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - Boost.Python - News/Change Log - - - - - - - - - -
-

-

-
-

Boost.Python

- -

News/Change Log

-
-
- -
-
24 February 2003
- -
Finished improved support - for boost::shared_ptr. Now any wrapped object of - C++ class X can be converted automatically - to shared_ptr<X>, regardless of how it was - wrapped. The shared_ptr will manage the lifetime - of the Python object which supplied the X, rather - than just the X object itself, and when such - a shared_ptr is converted back to Python, the - original Python object will be returned.
- -
19 January 2003
- -
Integrated staticmethod support from Nikolay Mladenov. Thanks, - Nikolay!
- -
29 December 2002
- -
Added Visual Studio project file and instructions from Brett - Calcott. Thanks, Brett!
- -
20 December 2002
- -
Added automatic downcasting for pointers, references, and smart - pointers to polymorphic class types upon conversion to python
- -
18 December 2002
- -
Optimized from_python conversions for wrapped classes by putting - the conversion logic in the shared library instead of registering - separate converters for each class in each extension module
- -
19 November 2002
- -
Removed the need for users to cast base class member function - pointers when used as arguments to add_property
- -
13 December 2002
- -
Allow exporting of enum_ values into enclosing - scope.
- Fixed unsigned integer conversions to deal correctly with numbers that - are out-of-range of signed long.
- -
14 November 2002
- -
Auto-detection of class data members wrapped with make_getter
- -
13 November 2002
- -
Full Support for std::auto_ptr<> added.
- -
October 2002
- -
Ongoing updates and improvements to tutorial documentation
- -
10 October 2002
- -
Boost.Python V2 is released!
-
-
- -

Revised - - 20 December, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt deleted file mode 100644 index c6f89416..00000000 --- a/doc/polymorphism.txt +++ /dev/null @@ -1,217 +0,0 @@ -How Runtime Polymorphism is expressed in Boost.Python: ------------------------------------------------------ - - struct A { virtual std::string f(); virtual ~A(); }; - - std::string call_f(A& x) { return x.f(); } - - struct B { virtual std::string f() { return "B"; } }; - - struct Bcb : B - { - Bcb(PyObject* self) : m_self(self) {} - - virtual std::string f() { return call_method(m_sef, "f"); } - static std::string f_default(B& b) { return b.B::f(); } - - PyObject* m_self; - }; - - struct C : B - { - virtual std::string f() { return "C"; } - }; - - >>> class D(B): - ... def f(): - ... return 'D' - ... - >>> class E(B): pass - ... - - -When we write, "invokes B::f non-virtually", we mean: - - void g(B& x) { x.B::f(); } - -This will call B::f() regardless of the dynamic type of x. Any other -way of invoking B::f, including through a function pointer, is a -"virtual invocation", and will call the most-derived override of f(). - -Case studies - - C++\Python class - \___A_____B_____C_____D____E___ - | - A | 1 - | - B | 2 3 - | - Bcb | 4 5 6 - | - C | 7 8 - | - - -1. Simple case - -2. Python A holds a B*. Probably won't happen once we have forced - downcasting. - - Requires: - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: A.f invokes A::f() (virtually or otherwise) - -3. Python B holds a B*. - - Requires: - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f (virtually or otherwise) - - -4. B constructed from Python - - Requires: - - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f non-virtually. Bcb::f invokes B::f - non-virtually. - - Question: Does it help if we arrange for Python B construction to - build a true B object? Then this case doesn't arise. - - -5. D is a Python class derived from B - - Requires: - - x.f() -> 'D' - call_f(x) -> 'D' - - Implies: Bcb::f must invoke call_method to look up the Python - method override, otherwise call_f wouldn't work. - -6. E is like D, but doesn't override f - - Requires: - - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f non-virtually. If it were virtual, x.f() - would cause infinite recursion, because we've already - determined that Bcb::f must invoke call_method to look up - the Python method override. - -7. Python B object holds a C* - - Requires: - - x.f() -> 'C' - call_f(x) -> 'C' - - Implies: B.f invokes B::f virtually. - -8. C object constructed from Python - - Requires: - - x.f() -> 'C' - call_f(x) -> 'C' - - Implies: nothing new. - ------- - -Total implications: - -2: A.f invokes A::f() (virtually or otherwise) -3: B.f invokes B::f (virtually or otherwise) -4: B.f invokes B::f non-virtually. Bcb::f invokes B::f non-virtually -6: B.f invokes B::f non-virtually. -7: B.f invokes B::f virtually. - -5: Bcb::f invokes call_method to look up the Python method - -Though (4) is avoidable, clearly 6 and 7 are not, and they -conflict. The implication is that B.f must choose its behavior -according to the type of the contained C++ object. If it is Bcb, a -non-virtual call to B::f must occur. Otherwise, a virtual call to B::f -must occur. This is essentially the same scheme we had with -Boost.Python v1. - -Note: in early versions of Boost.Python v1, we solved this problem by -introducing a new Python class in the hierarchy, so that D and E -actually derive from a B', and B'.f invokes B::f non-virtually, while -B.f invokes B::f virtually. However, people complained about the -artificial class in the hierarchy, which was revealed when they tried -to do normal kinds of Python introspection. - -------- - -Assumption: we will have a function which builds a virtual function -dispatch callable Python object. - - make_virtual_function(pvmf, default_impl, call_policies, dispatch_type) - -Pseudocode: - - Get first argument from Python arg tuple - if it contains dispatch_type - call default_impl - else - call through pvmf - - -Open questions: - - 1. What about Python multiple inheritance? Do we have the right - check in the if clause above? - - A: Not quite. The correct test looks like: - - Deduce target type of pvmf, i.e. T in R(T::*)(A1...AN). - Find holder in first argument which holds T - if it holds dispatch_type... - - 2. Can we make this more efficient? - - The current "returning" mechanism will look up a holder for T - again. I don't know if we know how to avoid that. - - - OK, the solution involves reworking the call mechanism. This is - neccesary anyway in order to enable wrapping of function objects. - - It can result in a reduction in the overall amount of source code, - because returning<> won't need to be specialized for every - combination of function and member function... though it will still - need a void specialization. We will still need a way to dispatch to - member functions through a regular function interface. mem_fn is - almost the right tool, but it only goes up to 8 - arguments. Forwarding is tricky if you don't want to incur copies. - I think the trick is to use arg_from_python::result_type for each - argument to the forwarder. - - Another option would be to use separate function, function object, - and member function dispatchers. Once you know you have a member - function, you don't need cv-qualified overloads to call it. - - Hmm, while we're at this, maybe we should solve the write-back - converter problem. Can we do it? Maybe not. Ralf doesn't want to - write special write-back functions here, does he? He wants the - converter to do the work automatically. We could add - cleanup/destructor registration. That would relieve the client from - having accessible destructors for types which are being converted by - rvalue. I'm not sure that this will really save any code, - however. It rather depends on the linker, doesn't it? I wonder if - this can be done in a backwards-compatible fashion by generating the - delete function when it's not supplied? - - diff --git a/doc/projects.html b/doc/projects.html deleted file mode 100644 index 5db7ec27..00000000 --- a/doc/projects.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - Boost.Python - Projects using Boost.Python - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Projects using Boost.Python

-
-
- -

Introduction

- -

This is a partial list of projects using Boost.Python. If you are - using Boost.Python as your Python/C++ binding solution, we'd be proud to - list your project on this page. Just post a short description of your project - and how Boost.Python helps you get the job done, and we'll add it to this - page .

-
- -

Enterprise Software

- -
-
OpenWBEM
- -
- The OpenWBEM project is an effort to develop an open-source - implementation of Web Based Enterprise Management suitable for - commercial and non-commercial application - -

Dan Nuffer writes:

- -
- I'm using Boost.Python to wrap the client API of OpenWBEM.This will - make it easier to do rapid prototyping, testing, and scripting when - developing management solutions that use WBEM. -
-
-
- -

Financial Analysis

- -
-
TSLib - Fortress - Investment Group LLC
- -
- Fortress Investment Group has contracted Boost Consulting to develop - core internal financial analysis tools in C++ and to prepare Python - bindings for them using Boost.Python. - -

Tom Barket of Fortress writes:

- -
- We have a large C++ analytical library specialized for research in - finance and economics, built for speed and mission critical - stability. Yet Python offers us the flexibility to test out new - ideas quickly and increase the productivity of our time versus - working in C++. There are several key features which make Python - stand out. Its elegance, stability, and breadth of resources on the - web are all valuable, but the most important is its extensibility, - due to its open source transparency. Boost.Python makes Python - extensibility extremely simple and straightforward, yet preserves a - great deal of power and control. -
-
-
- -

Graphics

- -
-
OpenSceneGraph
- -
Gideon May has created a - set of bindings for OpenSceneGraph, a cross-platform C++/OpenGL library - for the real-time visualization. You can read the release announcement - at www.hypereyes.com. Contact Gideon for more - information.
-  
- -
PythonMagick
- -
PythonMagick binds the ImageMagick image manipulation library - to Python.
-  
- -
HippoDraw - Stanford - Linear Accelerator Center
- -
- HippoDraw is a data analysis environment consisting of a canvas upon - which graphs such as histograms, scattter plots, etc, are prsented. - It has a highly interactive GUI interface, but some things you need - to do with scripts. HippoDraw can be run as Python extension module - so that all the manipulation can be done from either Python or the - GUI. - -

Paul F. Kunz - writes:

- -
- Don't have a web page for the project, but the organization's is http://www.slac.stanford.edu - (the first web server site in America, I installed it). -
- Which was just too cool a piece of trivia to omit.
-   -
-
- -

Scientific Computing

- -
-
CAMFR
- -
- CAMFR is a photonics and electromagnetics modelling tool. Python is - used for computational steering. - -

Peter Bienstman - writes:

- -
- Thanks for providing such a great tool! -
-
- -
cctbx - Computational - Crystallography Toolbox
- -
- Computational Crystallography is concerned with the derivation of - atomic models of crystal structures, given experimental X-ray - diffraction data. The cctbx is an open-source library of fundamental - algorithms for crystallographic computations. The core algorithms are - implemented in C++ and accessed through higher-level Python - interfaces. - -

The cctbx grew together with Boost.Python and is designed from the - ground up as a hybrid Python/C++ system. With one minor exception, - run-time polymorphism is completely handled by Python. C++ - compile-time polymorphism is used to implement performance critical - algorithms. The Python and C++ layers are seamlessly integrated using - Boost.Python.

- -

The SourceForge cctbx project is organized in modules to - facilitate use in non-crystallographic applications. The scitbx - module implements a general purpose array family for scientific - applications and pure C++ ports of FFTPACK and the LBFGS conjugate - gradient minimizer.

-
- -
EMSolve
- -
EMSolve is a provably stable, charge conserving, and energy - conserving solver for Maxwell's equations.
-  
- -
Gaudi and RootPython
- -
- Gaudi is a framework for particle physics collision data processing - applications developed in the context of the LHCb and ATLAS - experiments at CERN. - -

Pere Mato Vila writes:

- -
- We are using Boost.Python to provide scripting/interactive - capability to our framework. We have a module called "GaudiPython" - implemented using Boost.Python that allows the interaction with any - framework service or algorithm from python. RootPython also uses - Boost.Python to provide a generic "gateway" between the ROOT framework and python - -

Boost.Python is great. We managed very quickly to interface our - framework to python, which is great language. We are trying to - facilitate to our physicists (end-users) a rapid analysis - application development environment based on python. For that, - Boost.Python plays and essential role.

-
-
-
-
- -

Revised - - 16 November, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/support.html b/doc/support.html deleted file mode 100644 index 1f0e932c..00000000 --- a/doc/support.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - Boost.Python - Support Resources - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Support Resources

-
-
- -

Synopsis

- -

This is a list of available resources for support with Boost.Python - problems and feature requests.

-
- -
-
Boost - Consulting - Commercial support, development, training, and - distribution for all the Boost libraries, from the people who brought - you Boost.Python.
-  
- -
The Python - C++-sig mailing list is a forum for discussing Python/C++ - interoperability, and Boost.Python in particular.
-  
- -
The Boost.Python Wiki - Pages established by Mike Rovner as part of the PythonInfo Wiki serves as - a forum to gather peoples' experience and as a cookbook.
-  
-
-
- -

Revised - - 17 November, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/tutorial/doc/auto_overloading.html b/doc/tutorial/doc/auto_overloading.html deleted file mode 100644 index d478eeae..00000000 --- a/doc/tutorial/doc/auto_overloading.html +++ /dev/null @@ -1,112 +0,0 @@ - - - -Auto-Overloading - - - - - - - - - - -
- - Auto-Overloading -
-
- - - - - - -
-

-It was mentioned in passing in the previous section that -BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_FUNCTION_OVERLOADS -can also be used for overloaded functions and member functions with a -common sequence of initial arguments. Here is an example:

-
-     void foo()
-     {
-        /*...*/
-     }
-
-     void foo(bool a)
-     {
-        /*...*/
-     }
-
-     void foo(bool a, int b)
-     {
-        /*...*/
-     }
-
-     void foo(bool a, int b, char c)
-     {
-        /*...*/
-     }
-
-

-Like in the previous section, we can generate thin wrappers for these -overloaded functions in one-shot:

-
-    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
-
-

-Then...

-
-    .def("foo", foo, foo_overloads());
-
-

-Notice though that we have a situation now where we have a minimum of zero -(0) arguments and a maximum of 3 arguments.

-

Manual Wrapping

-It is important to emphasize however that the overloaded functions must -have a common sequence of initial arguments. Otherwise, our scheme above -will not work. If this is not the case, we have to wrap our functions - -manually.

-

-Actually, we can mix and match manual wrapping of overloaded functions and -automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS and -its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Following up on our example -presented in the section -on overloading, since the -first 4 overload functins have a common sequence of initial arguments, we -can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS to automatically wrap the -first three of the defs and manually wrap just the last. Here's -how we'll do this:

-
-    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
-
-

-Create a member function pointers as above for both X::f overloads:

-
-    bool    (X::*fx1)(int, double, char)    = &X::f;
-    int     (X::*fx2)(int, int, int)        = &X::f;
-
-

-Then...

-
-    .def("f", fx1, xf_overloads());
-    .def("f", fx2)
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/basic_interface.html b/doc/tutorial/doc/basic_interface.html deleted file mode 100644 index 8165b121..00000000 --- a/doc/tutorial/doc/basic_interface.html +++ /dev/null @@ -1,77 +0,0 @@ - - - -Basic Interface - - - - - - - - - - -
- - Basic Interface -
-
- - - - - - -
-

-Class object wraps PyObject*. All the intricacies of dealing with -PyObjects such as managing reference counting are handled by the -object class. C++ object interoperability is seamless. Boost.Python C++ -objects can in fact be explicitly constructed from any C++ object.

-

-To illustrate, this Python code snippet:

-
-    def f(x, y):
-         if (y == 'foo'):
-             x[3:7] = 'bar'
-         else:
-             x.items += y(3, x)
-         return x
-
-    def getfunc():
-       return f;
-
-

-Can be rewritten in C++ using Boost.Python facilities this way:

-
-    object f(object x, object y) {
-         if (y == "foo")
-             x.slice(3,7) = "bar";
-         else
-             x.attr("items") += y(3, x);
-         return x;
-    }
-    object getfunc() {
-        return object(f);
-    }
-
-

-Apart from cosmetic differences due to the fact that we are writing the -code in C++, the look and feel should be immediately apparent to the Python -coder.

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/building_hello_world.html b/doc/tutorial/doc/building_hello_world.html deleted file mode 100644 index 09b7ba93..00000000 --- a/doc/tutorial/doc/building_hello_world.html +++ /dev/null @@ -1,191 +0,0 @@ - - - -Building Hello World - - - - - - - - - - -
- - Building Hello World -
-
- - - - - - -
-

From Start To Finish

-Now the first thing you'd want to do is to build the Hello World module and -try it for yourself in Python. In this section, we shall outline the steps -necessary to achieve that. We shall use the build tool that comes bundled -with every boost distribution: bjam.

- - - - -
- Building without bjam

- -Besides bjam, there are of course other ways to get your module built. -What's written here should not be taken as "the one and only way". -There are of course other build tools apart from bjam. -
-

-We shall skip over the details. Our objective will be to simply create the -hello world module and run it in Python. For a complete reference to -building Boost.Python, check out: -building.html. -After this brief bjam tutorial, we should have built two DLLs:

-
  • boost_python.dll
  • hello.pyd

-if you are on Windows, and

-
  • libboost_python.so
  • hello.so

-if you are on Unix.

-

-The tutorial example can be found in the directory: -libs/python/example/tutorial. There, you can find:

-
  • hello.cpp
  • Jamfile

-The hello.cpp file is our C++ hello world example. The Jamfile is a -minimalist bjam script that builds the DLLs for us.

-

-Before anything else, you should have the bjam executable in your boost -directory or somewhere in your path such that bjam can be executed in -the command line. Pre-built Boost.Jam executables are available for most -platforms. For example, a pre-built Microsoft Windows bjam executable can -be downloaded -here. -The complete list of bjam pre-built -executables can be found -here.

-

Lets Jam!

-

-

-Here is our minimalist Jamfile:

-
-    subproject libs/python/example/tutorial ;
-
-    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
-    include python.jam ;
-
-    extension hello                     # Declare a Python extension called hello
-    :   hello.cpp                       # source
-        <dll>../../build/boost_python   # dependencies
-        ;
-

-First, we need to specify our location in the boost project hierarchy. -It so happens that the tutorial example is located in /libs/python/example/tutorial. -Thus:

-
-    subproject libs/python/example/tutorial ;
-

-Then we will include the definitions needed by Python modules:

-
-    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
-    include python.jam ;
-

-Finally we declare our hello extension:

-
-    extension hello                     # Declare a Python extension called hello
-    :   hello.cpp                       # source
-        <dll>../../build/boost_python   # dependencies
-        ;
-

Running bjam

-bjam is run using your operating system's command line interpreter.

-

Start it up.

-Make sure that the environment is set so that we can invoke the C++ -compiler. With MSVC, that would mean running the Vcvars32.bat batch -file. For instance:

-
-    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
-
-

-Some environment variables will have to be setup for proper building of our -Python modules. Example:

-
-    set PYTHON_ROOT=c:/dev/tools/python
-    set PYTHON_VERSION=2.2
-
-

-The above assumes that the Python installation is in c:/dev/tools/python -and that we are using Python version 2.2. You'll have to tweak this path -appropriately. Be sure not to include a third number, e.g. not "2.2.1", -even if that's the version you have.

-

-Now we are ready... Be sure to cd to libs/python/example/tutorial -where the tutorial "hello.cpp" and the "Jamfile" is situated.

-

-Finally:

-
-    bjam -sTOOLS=msvc
-
-

-We are again assuming that we are using Microsoft Visual C++ version 6. If -not, then you will have to specify the appropriate tool. See - -Building Boost Libraries for -further details.

-

-It should be building now:

-
-    cd C:\dev\boost\libs\python\example\tutorial
-    bjam -sTOOLS=msvc
-    ...patience...
-    ...found 1703 targets...
-    ...updating 40 targets...
-

-And so on... Finally:

-
-    vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
-    runtime-link-dynamic\hello.obj
-    hello.cpp
-    vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
-    runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\
-    hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
-       Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\
-       msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\
-       example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
-    ...updated 40 targets...
-

-If all is well, you should now have:

-
  • boost_python.dll
  • hello.pyd

-if you are on Windows, and

-
  • libboost_python.so
  • hello.so

-if you are on Unix.

-

-boost_python.dll can be found somewhere in libs\python\build\bin -while hello.pyd can be found somewhere in -libs\python\example\tutorial\bin. After a successful build, you can just -link in these DLLs with the Python interpreter. In Windows for example, you -can simply put these libraries inside the directory where the Python -executable is.

-

-You may now fire up Python and run our hello module:

-
-    >>> import hello
-    >>> print hello.greet()
-    hello, world
-
-

There you go... Have fun!

- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/call_policies.html b/doc/tutorial/doc/call_policies.html deleted file mode 100644 index dc94ea5b..00000000 --- a/doc/tutorial/doc/call_policies.html +++ /dev/null @@ -1,169 +0,0 @@ - - - -Call Policies - - - - - - - - - - -
- - Call Policies -
-
- - - - - - -
-

-In C++, we often deal with arguments and return types such as pointers -and references. Such primitive types are rather, ummmm, low level and -they really don't tell us much. At the very least, we don't know the -owner of the pointer or the referenced object. No wonder languages -such as Java and Python never deal with such low level entities. In -C++, it's usually considered a good practice to use smart pointers -which exactly describe ownership semantics. Still, even good C++ -interfaces use raw references and pointers sometimes, so Boost.Python -must deal with them. To do this, it may need your help. Consider the -following C++ function:

-
-    X& f(Y& y, Z* z);
-
-

-How should the library wrap this function? A naive approach builds a -Python X object around result reference. This strategy might or might -not work out. Here's an example where it didn't

-
-    >>> x = f(y, z) ##x refers to some C++ X
-    >>> del y
-    >>> x.some_method() ##CRASH!
-
-

-What's the problem?

-

-Well, what if f() was implemented as shown below:

-
-    X& f(Y& y, Z* z)
-    {
-        y.z = z;
-        return y.x;
-    }
-
-

-The problem is that the lifetime of result X& is tied to the lifetime -of y, because the f() returns a reference to a member of the y -object. This idiom is is not uncommon and perfectly acceptable in the -context of C++. However, Python users should not be able to crash the -system just by using our C++ interface. In this case deleting y will -invalidate the reference to X. We have a dangling reference.

-

-Here's what's happening:

-
  1. f is called passing in a reference to y and a pointer to z
  2. A reference to y.x is returned
  3. y is deleted. x is a dangling reference
  4. x.some_method() is called
  5. BOOM!

-We could copy result into a new object:

-
-    >>> f(y, z).set(42) ##Result disappears
-    >>> y.x.get()       ##No crash, but still bad
-    3.14
-
-

-This is not really our intent of our C++ interface. We've broken our -promise that the Python interface should reflect the C++ interface as -closely as possible.

-

-Our problems do not end there. Suppose Y is implemented as follows:

-
-    struct Y
-    {
-        X x; Z* z;
-        int z_value() { return z->value(); }
-    };
-
-

-Notice that the data member z is held by class Y using a raw -pointer. Now we have a potential dangling pointer problem inside Y:

-
-    >>> x = f(y, z) ##y refers to z
-    >>> del z       ##Kill the z object
-    >>> y.z_value() ##CRASH!
-
-

-For reference, here's the implementation of f again:

-
-    X& f(Y& y, Z* z)
-    {
-        y.z = z;
-        return y.x;
-    }
-
-

-Here's what's happening:

-
  1. f is called passing in a reference to y and a pointer to z
  2. A pointer to z is held by y
  3. A reference to y.x is returned
  4. z is deleted. y.z is a dangling pointer
  5. y.z_value() is called
  6. z->value() is called
  7. BOOM!

Call Policies

-Call Policies may be used in situations such as the example detailed above. -In our example, return_internal_reference and with_custodian_and_ward -are our friends:

-
-    def("f", f,
-        return_internal_reference<1,
-            with_custodian_and_ward<1, 2> >());
-
-

-What are the 1 and 2 parameters, you ask?

-
-    return_internal_reference<1
-
-

-Informs Boost.Python that the first argument, in our case Y& y, is the -owner of the returned reference: X&. The "1" simply specifies the -first argument. In short: "return an internal reference X& owned by the -1st argument Y& y".

-
-    with_custodian_and_ward<1, 2>
-
-

-Informs Boost.Python that the lifetime of the argument indicated by ward -(i.e. the 2nd argument: Z* z) is dependent on the lifetime of the -argument indicated by custodian (i.e. the 1st argument: Y& y).

-

-It is also important to note that we have defined two policies above. Two -or more policies can be composed by chaining. Here's the general syntax:

-
-    policy1<args...,
-        policy2<args...,
-            policy3<args...> > >
-
-

-Here is the list of predefined call policies. A complete reference detailing -these can be found -here.

-
  • with_custodian_and_ward
    Ties lifetimes of the arguments
  • with_custodian_and_ward_postcall
    Ties lifetimes of the arguments and results
  • return_internal_reference
    Ties lifetime of one argument to that of result
  • return_value_policy<T> with T one of:
  • reference_existing_object
    naïve (dangerous) approach
  • copy_const_reference
    Boost.Python v1 approach
  • copy_non_const_reference
  • manage_new_object
    Adopt a pointer and hold the instance
- - - -
- Remember the Zen, Luke:

-"Explicit is better than implicit"
-"In the face of ambiguity, refuse the temptation to guess"
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_data_members.html b/doc/tutorial/doc/class_data_members.html deleted file mode 100644 index b43bf83c..00000000 --- a/doc/tutorial/doc/class_data_members.html +++ /dev/null @@ -1,78 +0,0 @@ - - - -Class Data Members - - - - - - - - - - -
- - Class Data Members -
-
- - - - - - -
-

-Data members may also be exposed to Python so that they can be -accessed as attributes of the corresponding Python class. Each data -member that we wish to be exposed may be regarded as read-only or -read-write. Consider this class Var:

-
-    struct Var
-    {
-        Var(std::string name) : name(name), value() {}
-        std::string const name;
-        float value;
-    };
-
-

-Our C++ Var class and its data members can be exposed to Python:

-
-    class_<Var>("Var", init<std::string>())
-        .def_readonly("name", &Var::name)
-        .def_readwrite("value", &Var::value);
-
-

-Then, in Python, assuming we have placed our Var class inside the namespace -hello as we did before:

-
-    >>> x = hello.Var('pi')
-    >>> x.value = 3.14
-    >>> print x.name, 'is around', x.value
-    pi is around 3.14
-
-

-Note that name is exposed as read-only while value is exposed -as read-write.

-
-    >>> x.name = 'e' # can't change name
-    Traceback (most recent call last):
-      File "<stdin>", line 1, in ?
-    AttributeError: can't set attribute
-
- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_operators_special_functions.html b/doc/tutorial/doc/class_operators_special_functions.html deleted file mode 100644 index ce7aab66..00000000 --- a/doc/tutorial/doc/class_operators_special_functions.html +++ /dev/null @@ -1,109 +0,0 @@ - - - -Class Operators/Special Functions - - - - - - - - - - -
- - Class Operators/Special Functions -
-
- - - - - - -
-

Python Operators

-C is well known for the abundance of operators. C++ extends this to the -extremes by allowing operator overloading. Boost.Python takes advantage of -this and makes it easy to wrap C++ operator-powered classes.

-

-Consider a file position class FilePos and a set of operators that take -on FilePos instances:

-
-    class FilePos { /*...*/ };
-
-    FilePos     operator+(FilePos, int);
-    FilePos     operator+(int, FilePos);
-    int         operator-(FilePos, FilePos);
-    FilePos     operator-(FilePos, int);
-    FilePos&    operator+=(FilePos&, int);
-    FilePos&    operator-=(FilePos&, int);
-    bool        operator<(FilePos, FilePos);
-
-

-The class and the various operators can be mapped to Python rather easily -and intuitively:

-
-    class_<FilePos>("FilePos")
-        .def(self + int())          // __add__
-        .def(int() + self)          // __radd__
-        .def(self - self)           // __sub__
-        .def(self - int())          // __sub__
-        .def(self += int())         // __iadd__
-        .def(self -= other<int>())
-        .def(self < self);          // __lt__
-
-

-The code snippet above is very clear and needs almost no explanation at -all. It is virtually the same as the operators' signatures. Just take -note that self refers to FilePos object. Also, not every class T that -you might need to interact with in an operator expression is (cheaply) -default-constructible. You can use other<T>() in place of an actual -T instance when writing "self expressions".

-

Special Methods

-Python has a few more Special Methods. Boost.Python supports all of the -standard special method names supported by real Python class instances. A -similar set of intuitive interfaces can also be used to wrap C++ functions -that correspond to these Python special functions. Example:

-
-    class Rational
-    { operator double() const; };
-
-    Rational pow(Rational, Rational);
-    Rational abs(Rational);
-    ostream& operator<<(ostream&,Rational);
-
-    class_<Rational>()
-        .def(float_(self))                  // __float__
-        .def(pow(self, other<Rational>))    // __pow__
-        .def(abs(self))                     // __abs__
-        .def(str(self))                     // __str__
-        ;
-
-

-Need we say more?

- - - - -
- What is the business of operator<< .def(str(self))? -Well, the method str requires the operator<< to do its work (i.e. -operator<< is used by the method defined by def(str(self)).
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_properties.html b/doc/tutorial/doc/class_properties.html deleted file mode 100644 index 99f340c4..00000000 --- a/doc/tutorial/doc/class_properties.html +++ /dev/null @@ -1,81 +0,0 @@ - - - -Class Properties - - - - - - - - - - -
- - Class Properties -
-
- - - - - - -
-

-In C++, classes with public data members are usually frowned -upon. Well designed classes that take advantage of encapsulation hide -the class' data members. The only way to access the class' data is -through access (getter/setter) functions. Access functions expose class -properties. Here's an example:

-
-    struct Num
-    {
-        Num();
-        float get() const;
-        void set(float value);
-        ...
-    };
-
-

-However, in Python attribute access is fine; it doesn't neccessarily break -encapsulation to let users handle attributes directly, because the -attributes can just be a different syntax for a method call. Wrapping our -Num class using Boost.Python:

-
-    class_<Num>("Num")
-        .add_property("rovalue", &Num::get)
-        .add_property("value", &Num::get, &Num::set);
-
-

-And at last, in Python:

-
-    >>> x = Num()
-    >>> x.value = 3.14
-    >>> x.value, x.rovalue
-    (3.14, 3.14)
-    >>> x.rovalue = 2.17 ##error!
-
-

-Take note that the class property rovalue is exposed as read-only -since the rovalue setter member function is not passed in:

-
-    .add_property("rovalue", &Num::get)
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html deleted file mode 100644 index 37ce60ce..00000000 --- a/doc/tutorial/doc/class_virtual_functions.html +++ /dev/null @@ -1,129 +0,0 @@ - - - -Class Virtual Functions - - - - - - - - - - -
- - Class Virtual Functions -
-
- - - - - - -
-

-In this section, we shall learn how to make functions behave -polymorphically through virtual functions. Continuing our example, let us -add a virtual function to our Base class:

-
-    struct Base
-    {
-        virtual int f() = 0;
-    };
-
-

-Since f is a pure virtual function, Base is now an abstract -class. Given an instance of our class, the free function call_f -calls some implementation of this virtual function in a concrete -derived class:

-
-    int call_f(Base& b) { return b.f(); }
-
-

-To allow this function to be implemented in a Python derived class, we -need to create a class wrapper:

-
-    struct BaseWrap : Base
-    {
-        BaseWrap(PyObject* self_)
-            : self(self_) {}
-        int f() { return call_method<int>(self, "f"); }
-        PyObject* self;
-    };
-
- - - - -
- member function and methods

Python, like -many object oriented languages uses the term methods. Methods -correspond roughly to C++'s member functions
-

-Our class wrapper BaseWrap is derived from Base. Its overridden -virtual member function f in effect calls the corresponding method -of the Python object self, which is a pointer back to the Python -Base object holding our BaseWrap instance.

- - - - -
- Why do we need BaseWrap?

- -You may ask, "Why do we need the BaseWrap derived class? This could -have been designed so that everything gets done right inside of -Base."

- -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.

- -Note however that you don't need to do this to get methods overridden -in Python to behave virtually when called from Python. The only -time you need to do the BaseWrap dance is when you have a virtual -function that's going to be overridden in Python and called -polymorphically from C++.
-

-Wrapping Base and the free function call_f:

-
-    class_<Base, BaseWrap, boost::noncopyable>("Base", no_init)
-        ;
-    def("call_f", call_f);
-
-

-Notice that we parameterized the class_ template with BaseWrap as the -second parameter. What is noncopyable? Without it, the library will try -to create code for converting Base return values of wrapped functions to -Python. To do that, it needs Base's copy constructor... which isn't -available, since Base is an abstract class.

-

-In Python, let us try to instantiate our Base class:

-
-    >>> base = Base()
-    RuntimeError: This class cannot be instantiated from Python
-
-

-Why is it an error? Base is an abstract class. As such it is advisable -to define the Python wrapper with no_init as we have done above. Doing -so will disallow abstract base classes such as Base to be instantiated.

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/constructors.html b/doc/tutorial/doc/constructors.html deleted file mode 100644 index 809bfee3..00000000 --- a/doc/tutorial/doc/constructors.html +++ /dev/null @@ -1,102 +0,0 @@ - - - -Constructors - - - - - - - - - - -
- - Constructors -
-
- - - - - - -
-

-Our previous example didn't have any explicit constructors. -Since World is declared as a plain struct, it has an implicit default -constructor. Boost.Python exposes the default constructor by default, -which is why we were able to write

-
-    >>> planet = hello.World()
-
-

-We may wish to wrap a class with a non-default constructor. Let us -build on our previous example:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} // added constructor
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-

-This time World has no default constructor; our previous -wrapping code would fail to compile when the library tried to expose -it. We have to tell class_<World> about the constructor we want to -expose instead.

-
-    #include <boost/python.hpp>
-    using namespace boost::python;
-
-    BOOST_PYTHON_MODULE(hello)
-    {
-        class_<World>("World", init<std::string>())
-            .def("greet", &World::greet)
-            .def("set", &World::set)
-        ;
-    }
-
-

-init<std::string>() exposes the constructor taking in a -std::string (in Python, constructors are spelled -""__init__"").

-

-We can expose additional constructors by passing more init<...>s to -the def() member function. Say for example we have another World -constructor taking in two doubles:

-
-    class_<World>("World", init<std::string>())
-        .def(init<double, double>())
-        .def("greet", &World::greet)
-        .def("set", &World::set)
-    ;
-
-

-On the other hand, if we do not wish to expose any constructors at -all, we may use no_init instead:

-
-    class_<Abstract>("Abstract", no_init)
-
-

-This actually adds an __init__ method which always raises a -Python RuntimeError exception.

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/default_arguments.html b/doc/tutorial/doc/default_arguments.html deleted file mode 100644 index d0c1f426..00000000 --- a/doc/tutorial/doc/default_arguments.html +++ /dev/null @@ -1,158 +0,0 @@ - - - -Default Arguments - - - - - - - - - - -
- - Default Arguments -
-
- - - - - - -
-

-Boost.Python wraps (member) function pointers. Unfortunately, C++ function -pointers carry no default argument info. Take a function f with default -arguments:

-
-    int f(int, double = 3.14, char const* = "hello");
-
-

-But the type of a pointer to the function f has no information -about its default arguments:

-
-    int(*g)(int,double,char const*) = f;    // defaults lost!
-
-

-When we pass this function pointer to the def function, there is no way -to retrieve the default arguments:

-
-    def("f", f);                            // defaults lost!
-
-

-Because of this, when wrapping C++ code, we had to resort to manual -wrapping as outlined in the -previous section, or -writing thin wrappers:

-
-    // write "thin wrappers"
-    int f1(int x) { f(x); }
-    int f2(int x, double y) { f(x,y); }
-
-    /*...*/
-
-        // in module init
-        def("f", f);  // all arguments
-        def("f", f2); // two arguments
-        def("f", f1); // one argument
-
-

-When you want to wrap functions (or member functions) that either:

-
  • have default arguments, or
  • are overloaded with a common sequence of initial arguments

BOOST_PYTHON_FUNCTION_OVERLOADS

-Boost.Python now has a way to make it easier. For instance, given a function:

-
-    int foo(int a, char b = 1, unsigned c = 2, double d = 3)
-    {
-        /*...*/
-    }
-
-

-The macro invocation:

-
-    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)
-
-

-will automatically create the thin wrappers for us. This macro will create -a class foo_overloads that can be passed on to def(...). The third -and fourth macro argument are the minimum arguments and maximum arguments, -respectively. In our foo function the minimum number of arguments is 1 -and the maximum number of arguments is 4. The def(...) function will -automatically add all the foo variants for us:

-
-    .def("foo", foo, foo_overloads());
-
-

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS

-Objects here, objects there, objects here there everywhere. More frequently -than anything else, we need to expose member functions of our classes to -Python. Then again, we have the same inconveniences as before when default -arguments or overloads with a common sequence of initial arguments come -into play. Another macro is provided to make this a breeze.

-

-Like BOOST_PYTHON_FUNCTION_OVERLOADS, -BOOST_PYTHON_FUNCTION_OVERLOADS may be used to automatically create -the thin wrappers for wrapping member functions. Let's have an example:

-
-    struct george
-    {
-        void
-        wack_em(int a, int b = 0, char c = 'x')
-        {
-            /*...*/
-        }
-    };
-
-

-The macro invocation:

-
-    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
-
-

-will generate a set of thin wrappers for george's wack_em member function -accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and -fourth macro argument). The thin wrappers are all enclosed in a class named -george_overloads that can then be used as an argument to def(...):

-
-    .def("wack_em", &george::wack_em, george_overloads());
-
-

-See the -overloads reference -for details.

-

init and optional

-A similar facility is provided for class constructors, again, with -default arguments or a sequence of overloads. Remember init<...>? For example, -given a class X with a constructor:

-
-    struct X
-    {
-        X(int a, char b = 'D', std::string c = "constructor", double d = 0.0);
-        /*...*/
-    }
-
-

-You can easily add this constructor to Boost.Python in one shot:

-
-    .def(init<int, optional<char, std::string, double> >())
-
-

-Notice the use of init<...> and optional<...> to signify the default -(optional arguments).

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/derived_object_types.html b/doc/tutorial/doc/derived_object_types.html deleted file mode 100644 index fbe44584..00000000 --- a/doc/tutorial/doc/derived_object_types.html +++ /dev/null @@ -1,117 +0,0 @@ - - - -Derived Object types - - - - - - - - - - -
- - Derived Object types -
-
- - - - - - -
-

-Boost.Python comes with a set of derived object types corresponding to -that of Python's:

-
  • list
  • dict
  • tuple
  • str
  • long_
  • enum

-These derived object types act like real Python types. For instance:

-
-    str(1) ==> "1"
-
-

-Wherever appropriate, a particular derived object has corresponding -Python type's methods. For instance, dict has a keys() method:

-
-    d.keys()
-
-

-make_tuple is provided for declaring tuple literals. Example:

-
-    make_tuple(123, 'D', "Hello, World", 0.0);
-
-

-In C++, when Boost.Python objects are used as arguments to functions, -subtype matching is required. For example, when a function f, as -declared below, is wrapped, it will only accept instances of Python's -str type and subtypes.

-
-    void f(str name)
-    {
-        object n2 = name.attr("upper")();   // NAME = name.upper()
-        str NAME = name.upper();            // better
-        object msg = "%s is bigger than %s" % make_tuple(NAME,name);
-    }
-
-

-In finer detail:

-
-    str NAME = name.upper();
-
-

-Illustrates that we provide versions of the str type's methods as C++ -member functions.

-
-    object msg = "%s is bigger than %s" % make_tuple(NAME,name);
-
-

-Demonstrates that you can write the C++ equivalent of "format" % x,y,z -in Python, which is useful since there's no easy way to do that in std C++.

-

- Beware the common pitfall of forgetting that the constructors -of most of Python's mutable types make copies, just as in Python.

-

-Python:

-
-    >>> d = dict(x.__dict__)     ##copies x.__dict__
-    >>> d['whatever']            ##modifies the copy
-
-

-C++:

-
-    dict d(x.attr("__dict__"));  ##copies x.__dict__
-    d['whatever'] = 3;           ##modifies the copy
-
-

class_<T> as objects

-Due to the dynamic nature of Boost.Python objects, any class_<T> may -also be one of these types! The following code snippet wraps the class -(type) object.

-

-We can use this to create wrapped instances. Example:

-
-    object vec345 = (
-        class_<Vec2>("Vec2", init<double, double>())
-            .def_readonly("length", &Point::length)
-            .def_readonly("angle", &Point::angle)
-        )(3.0, 4.0);
-
-    assert(vec345.attr("length") == 5.0);
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/deriving_a_python_class.html b/doc/tutorial/doc/deriving_a_python_class.html deleted file mode 100644 index 5c268371..00000000 --- a/doc/tutorial/doc/deriving_a_python_class.html +++ /dev/null @@ -1,83 +0,0 @@ - - - -Deriving a Python Class - - - - - - - - - - -
- - Deriving a Python Class -
-
- - - - - - -
-

-Continuing, we can derive from our base class Base in Python and override -the virtual function in Python. Before we can do that, we have to set up -our class_ wrapper as:

-
-    class_<Base, BaseWrap, boost::noncopyable>("Base")
-        ;
-
-

-Otherwise, we have to suppress the Base class' no_init by adding an -__init__() method to all our derived classes. no_init actually adds -an __init__ method that raises a Python RuntimeError exception.

-
-    >>> class Derived(Base):
-    ...     def f(self):
-    ...         return 42
-    ...
-
-

-Cool eh? A Python class deriving from a C++ class!

-

-Let's now make an instance of our Python class Derived:

-
-    >>> derived = Derived()
-
-

-Calling derived.f():

-
-    >>> derived.f()
-    42
-
-

-Will yield the expected result. Finally, calling calling the free function -call_f with derived as argument:

-
-    >>> call_f(derived)
-    42
-
-

-Will also yield the expected result.

-

-Here's what's happening:

-
  1. call_f(derived) is called in Python
  2. This corresponds to def("call_f", call_f);. Boost.Python dispatches this call.
  3. int call_f(Base& b) { return b.f(); } accepts the call.
  4. The overridden virtual function f of BaseWrap is called.
  5. call_method<int>(self, "f"); dispatches the call back to Python.
  6. def f(self): return 42 is finally called.
- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/embedding.html b/doc/tutorial/doc/embedding.html deleted file mode 100644 index 8cd1c725..00000000 --- a/doc/tutorial/doc/embedding.html +++ /dev/null @@ -1,97 +0,0 @@ - - - -Embedding - - - - - - - - - - -
- - Embedding -
-
- - - - - - -
-

-By now you should know how to use Boost.Python to call your C++ code from -Python. However, sometimes you may need to do the reverse: call Python code -from the C++-side. This requires you to embed the Python interpreter -into your C++ program.

-

-Currently, Boost.Python does not directly support everything you'll need -when embedding. Therefore you'll need to use the - -Python/C API to fill in -the gaps. However, Boost.Python already makes embedding a lot easier and, -in a future version, it may become unnecessary to touch the Python/C API at -all. So stay tuned...

-

Building embedded programs

-To be able to use embedding in your programs, they have to be linked to -both Boost.Python's and Python's static link library.

-

-Boost.Python's static link library comes in two variants. Both are located -in Boost's /libs/python/build/bin-stage subdirectory. On Windows, the -variants are called boost_python.lib (for release builds) and -boost_python_debug.lib (for debugging). If you can't find the -libraries, you probably haven't built Boost.Python yet. See Building and Testing on how to do -this.

-

-Python's static link library can be found in the /libs subdirectory of -your Python directory. On Windows it is called pythonXY.lib where X.Y is -your major Python version number.

-

-Additionally, Python's /include subdirectory has to be added to your -include path.

-

-In a Jamfile, all the above boils down to:

-
-    projectroot c:\projects\embedded_program ; # location of the program
-
-    # bring in the rules for python
-    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
-    include python.jam ;
-
-    exe embedded_program # name of the executable
-      : #sources
-         embedded_program.cpp
-      : # requirements
-         <find-library>boost_python <library-path>c:\boost\libs\python
-      $(PYTHON_PROPERTIES)
-        <library-path>$(PYTHON_LIB_PATH)
-        <find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
-

Getting started

-Being able to build is nice, but there is nothing to build yet. Embedding -the Python interpreter into one of your C++ programs requires these 4 -steps:

-
  1. #include <boost/python.hpp>

  2. Call -Py_Initialize() to start the interpreter and create the __main__ module.

  3. Call other Python C API routines to use the interpreter.

  4. Call -Py_Finalize() to stop the interpreter and release its resources.

-(Of course, there can be other C++ code between all of these steps.)

-

Now that we can embed the interpreter in our programs, lets see how to put it to use...

- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html deleted file mode 100644 index 09632e31..00000000 --- a/doc/tutorial/doc/enums.html +++ /dev/null @@ -1,95 +0,0 @@ - - - -Enums - - - - - - - - - - -
- - Enums -
-
- - - - - - -
-

-Boost.Python has a nifty facility to capture and wrap C++ enums. While -Python has no enum type, we'll often want to expose our C++ enums to -Python as an int. Boost.Python's enum facility makes this easy while -taking care of the proper conversions from Python's dynamic typing to C++'s -strong static typing (in C++, ints cannot be implicitly converted to -enums). To illustrate, given a C++ enum:

-
-    enum choice { red, blue };
-
-

-the construct:

-
-    enum_<choice>("choice")
-        .value("red", red)
-        .value("blue", blue)
-        ;
-
-

-can be used to expose to Python. The new enum type is created in the -current scope(), which is usually the current module. The snippet above -creates a Python class derived from Python's int type which is -associated with the C++ type passed as its first parameter.

- - - - -
- what is a scope?

The scope is a class that has an -associated global Python object which controls the Python namespace in -which new extension classes and wrapped functions will be defined as -attributes. Details can be found -here.
-

-You can access those values in Python as

-
-    >>> my_module.choice.red
-    my_module.choice.red
-
-

-where my_module is the module where the enum is declared. You can also -create a new scope around a class:

-
-    scope in_X = class_<X>("X")
-                    .def( ... )
-                    .def( ... )
-                ;
-
-    // Expose X::nested as X.nested
-    enum_<X::nested>("nested")
-        .value("red", red)
-        .value("blue", blue)
-        ;
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/exception_translation.html b/doc/tutorial/doc/exception_translation.html deleted file mode 100644 index 51c73560..00000000 --- a/doc/tutorial/doc/exception_translation.html +++ /dev/null @@ -1,60 +0,0 @@ - - - -Exception Translation - - - - - - - - - -
- - Exception Translation -
-
- - - - - - -
-

-All C++ exceptions must be caught at the boundary with Python code. This -boundary is the point where C++ meets Python. Boost.Python provides a -default exception handler that translates selected standard exceptions, -then gives up:

-
-    raise RuntimeError, 'unidentifiable C++ Exception'
-
-

-Users may provide custom translation. Here's an example:

-
-    struct PodBayDoorException;
-    void translator(PodBayDoorException const& x) {
-        PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
-    }
-    BOOST_PYTHON_MODULE(kubrick) {
-         register_exception_translator<
-              PodBayDoorException>(translator);
-         ...
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/exposing_classes.html b/doc/tutorial/doc/exposing_classes.html deleted file mode 100644 index 18f2e8d0..00000000 --- a/doc/tutorial/doc/exposing_classes.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Exposing Classes - - - - - - - - - - -
- - Exposing Classes -
-
- - - - - - -
-

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

-

-Consider a C++ class/struct that we want to expose to Python:

-
-    struct World
-    {
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-

-We can expose this to Python by writing a corresponding Boost.Python -C++ Wrapper:

-
-    #include <boost/python.hpp>
-    using namespace boost::python;
-
-    BOOST_PYTHON_MODULE(hello)
-    {
-        class_<World>("World")
-            .def("greet", &World::greet)
-            .def("set", &World::set)
-        ;
-    }
-
-

-Here, we wrote a C++ class wrapper that exposes the member functions -greet and set. Now, after building our module as a shared library, we -may use our class World in Python. Here's a sample Python session:

-
-    >>> import hello
-    >>> planet = hello.World()
-    >>> planet.set('howdy')
-    >>> planet.greet()
-    'howdy'
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/extracting_c___objects.html b/doc/tutorial/doc/extracting_c___objects.html deleted file mode 100644 index 82096e6d..00000000 --- a/doc/tutorial/doc/extracting_c___objects.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Extracting C++ objects - - - - - - - - - - -
- - Extracting C++ objects -
-
- - - - - - -
-

-At some point, we will need to get C++ values out of object instances. This -can be achieved with the extract<T> function. Consider the following:

-
-    double x = o.attr("length"); // compile error
-
-

-In the code above, we got a compiler error because Boost.Python -object can't be implicitly converted to doubles. Instead, what -we wanted to do above can be achieved by writing:

-
-    double l = extract<double>(o.attr("length"));
-    Vec2& v = extract<Vec2&>(o);
-    assert(l == v.length());
-
-

-The first line attempts to extract the "length" attribute of the -Boost.Python object o. The second line attempts to extract the -Vec2 object from held by the Boost.Python object o.

-

-Take note that we said "attempt to" above. What if the Boost.Python -object o does not really hold a Vec2 type? This is certainly -a possibility considering the dynamic nature of Python objects. To -be on the safe side, if the C++ type can't be extracted, an -appropriate exception is thrown. To avoid an exception, we need to -test for extractibility:

-
-    extract<Vec2&> x(o);
-    if (x.check()) {
-        Vec2& v = x(); ...
-
-

- The astute reader might have noticed that the extract<T> -facility in fact solves the mutable copying problem:

-
-    dict d = extract<dict>(x.attr("__dict__"));
-    d['whatever'] = 3;          ##modifies x.__dict__ !
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/functions.html b/doc/tutorial/doc/functions.html deleted file mode 100644 index 6a29d89b..00000000 --- a/doc/tutorial/doc/functions.html +++ /dev/null @@ -1,73 +0,0 @@ - - - -Functions - - - - - - - - - - -
- - Functions -
-
- - - - - - -
-

-In this chapter, we'll look at Boost.Python powered functions in closer -detail. We shall see some facilities to make exposing C++ functions to -Python safe from potential pifalls such as dangling pointers and -references. We shall also see facilities that will make it even easier for -us to expose C++ functions that take advantage of C++ features such as -overloading and default arguments.

-

Read on...

-But before you do, you might want to fire up Python 2.2 or later and type ->>> import this.

-
-    >>> import this
-    The Zen of Python, by Tim Peters
-    Beautiful is better than ugly.
-    Explicit is better than implicit.
-    Simple is better than complex.
-    Complex is better than complicated.
-    Flat is better than nested.
-    Sparse is better than dense.
-    Readability counts.
-    Special cases aren't special enough to break the rules.
-    Although practicality beats purity.
-    Errors should never pass silently.
-    Unless explicitly silenced.
-    In the face of ambiguity, refuse the temptation to guess.
-    There should be one-- and preferably only one --obvious way to do it
-    Although that way may not be obvious at first unless you're Dutch.
-    Now is better than never.
-    Although never is often better than *right* now.
-    If the implementation is hard to explain, it's a bad idea.
-    If the implementation is easy to explain, it may be a good idea.
-    Namespaces are one honking great idea -- let's do more of those!
-
- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/inheritance.html b/doc/tutorial/doc/inheritance.html deleted file mode 100644 index acd18942..00000000 --- a/doc/tutorial/doc/inheritance.html +++ /dev/null @@ -1,98 +0,0 @@ - - - -Inheritance - - - - - - - - - - -
- - Inheritance -
-
- - - - - - -
-

-In the previous examples, we dealt with classes that are not polymorphic. -This is not often the case. Much of the time, we will be wrapping -polymorphic classes and class hierarchies related by inheritance. We will -often have to write Boost.Python wrappers for classes that are derived from -abstract base classes.

-

-Consider this trivial inheritance structure:

-
-    struct Base { virtual ~Base(); };
-    struct Derived : Base {};
-
-

-And a set of C++ functions operating on Base and Derived object -instances:

-
-    void b(Base*);
-    void d(Derived*);
-    Base* factory() { return new Derived; }
-
-

-We've seen how we can wrap the base class Base:

-
-    class_<Base>("Base")
-        /*...*/
-        ;
-
-

-Now we can inform Boost.Python of the inheritance relationship between -Derived and its base class Base. Thus:

-
-    class_<Derived, bases<Base> >("Derived")
-        /*...*/
-        ;
-
-

-Doing so, we get some things for free:

-
  1. Derived automatically inherits all of Base's Python methods (wrapped C++ member functions)
  2. If Base is polymorphic, Derived objects which have been passed to Python via a pointer or reference to Base can be passed where a pointer or reference to Derived is expected.

-Now, we shall expose the C++ free functions b and d and factory:

-
-    def("b", b);
-    def("d", d);
-    def("factory", factory);
-
-

-Note that free function factory is being used to generate new -instances of class Derived. In such cases, we use -return_value_policy<manage_new_object> to instruct Python to adopt -the pointer to Base and hold the instance in a new Python Base -object until the the Python object is destroyed. We shall see more of -Boost.Python -call policies later.

-
-    // Tell Python to take ownership of factory's result
-    def("factory", factory,
-        return_value_policy<manage_new_object>());
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/iterators.html b/doc/tutorial/doc/iterators.html deleted file mode 100644 index 585f89b1..00000000 --- a/doc/tutorial/doc/iterators.html +++ /dev/null @@ -1,101 +0,0 @@ - - - -Iterators - - - - - - - - - - -
- - Iterators -
-
- - - - - - -
-

-In C++, and STL in particular, we see iterators everywhere. Python also has -iterators, but these are two very different beasts.

-

-C++ iterators:

-
  • C++ has 5 type categories (random-access, bidirectional, forward, input, output)
  • There are 2 Operation categories: reposition, access
  • A pair of iterators is needed to represent a (first/last) range.

-Python Iterators:

-
  • 1 category (forward)
  • 1 operation category (next())
  • Raises StopIteration exception at end

-The typical Python iteration protocol: for y in x... is as follows:

-
-    iter = x.__iter__()         ##get iterator
-    try:
-        while 1:
-        y = iter.next()         ##get each item
-        ...                     ##process y
-    except StopIteration: pass  ##iterator exhausted
-
-

-Boost.Python provides some mechanisms to make C++ iterators play along -nicely as Python iterators. What we need to do is to produce -appropriate __iter__ function from C++ iterators that is compatible -with the Python iteration protocol. For example:

-
-    object get_iterator = iterator<vector<int> >();
-    object iter = get_iterator(v);
-    object first = iter.next();
-
-

-Or for use in class_<>:

-
-    .def("__iter__", iterator<vector<int> >())
-
-

-range

-

-We can create a Python savvy iterator using the range function:

-
  • range(start, finish)
  • range<Policies,Target>(start, finish)

-Here, start/finish may be one of:

-
  • member data pointers
  • member function pointers
  • adaptable function object (use Target parameter)

-iterator

-
  • iterator<T, Policies>()

-Given a container T, iterator is a shortcut that simply calls range -with &T::begin, &T::end.

-

-Let's put this into action... Here's an example from some hypothetical -bogon Particle accelerator code:

-
-    f = Field()
-    for x in f.pions:
-        smash(x)
-    for y in f.bogons:
-        count(y)
-
-

-Now, our C++ Wrapper:

-
-    class_<F>("Field")
-        .property("pions", range(&F::p_begin, &F::p_end))
-        .property("bogons", range(&F::b_begin, &F::b_end));
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/object_interface.html b/doc/tutorial/doc/object_interface.html deleted file mode 100644 index 1988dcd7..00000000 --- a/doc/tutorial/doc/object_interface.html +++ /dev/null @@ -1,54 +0,0 @@ - - - -Object Interface - - - - - - - - - - -
- - Object Interface -
-
- - - - - - -
-

-Python is dynamically typed, unlike C++ which is statically typed. Python -variables may hold an integer, a float, list, dict, tuple, str, long etc., -among other things. In the viewpoint of Boost.Python and C++, these -Pythonic variables are just instances of class object. We shall see in -this chapter how to deal with Python objects.

-

-As mentioned, one of the goals of Boost.Python is to provide a -bidirectional mapping between C++ and Python while maintaining the Python -feel. Boost.Python C++ objects are as close as possible to Python. This -should minimize the learning curve significantly.

-

-

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/overloading.html b/doc/tutorial/doc/overloading.html deleted file mode 100644 index f93edcac..00000000 --- a/doc/tutorial/doc/overloading.html +++ /dev/null @@ -1,88 +0,0 @@ - - - -Overloading - - - - - - - - - - -
- - Overloading -
-
- - - - - - -
-

-The following illustrates a scheme for manually wrapping an overloaded -member functions. Of course, the same technique can be applied to wrapping -overloaded non-member functions.

-

-We have here our C++ class:

-
-    struct X
-    {
-        bool f(int a)
-        {
-            return true;
-        }
-
-        bool f(int a, double b)
-        {
-            return true;
-        }
-
-        bool f(int a, double b, char c)
-        {
-            return true;
-        }
-
-        int f(int a, int b, int c)
-        {
-            return a + b + c;
-        };
-    };
-
-

-Class X has 4 overloaded functions. We shall start by introducing some -member function pointer variables:

-
-    bool    (X::*fx1)(int)              = &X::f;
-    bool    (X::*fx2)(int, double)      = &X::f;
-    bool    (X::*fx3)(int, double, char)= &X::f;
-    int     (X::*fx4)(int, int, int)    = &X::f;
-
-

-With these in hand, we can proceed to define and wrap this for Python:

-
-    .def("f", fx1)
-    .def("f", fx2)
-    .def("f", fx3)
-    .def("f", fx4)
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/quickstart.html b/doc/tutorial/doc/quickstart.html deleted file mode 100644 index 02ba7a1a..00000000 --- a/doc/tutorial/doc/quickstart.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -QuickStart - - - - - - - - - -
- - QuickStart -
-
- - - - - - -
-

-The Boost Python Library is a framework for interfacing Python and -C++. It allows you to quickly and seamlessly expose C++ classes -functions and objects to Python, and vice-versa, using no special -tools -- just your C++ compiler. It is designed to wrap C++ interfaces -non-intrusively, so that you should not have to change the C++ code at -all in order to wrap it, making Boost.Python ideal for exposing -3rd-party libraries to Python. The library's use of advanced -metaprogramming techniques simplifies its syntax for users, so that -wrapping code takes on the look of a kind of declarative interface -definition language (IDL).

-

Hello World

-Following C/C++ tradition, let's start with the "hello, world". A C++ -Function:

-
-    char const* greet()
-    {
-       return "hello, world";
-    }
-
-

-can be exposed to Python by writing a Boost.Python wrapper:

-
-    #include <boost/python.hpp>
-    using namespace boost::python;
-
-    BOOST_PYTHON_MODULE(hello)
-    {
-        def("greet", greet);
-    }
-
-

-That's it. We're done. We can now build this as a shared library. The -resulting DLL is now visible to Python. Here's a sample Python session:

-
-    >>> import hello
-    >>> print hello.greet()
-    hello, world
-
-

Next stop... Building your Hello World module from start to finish...

- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt deleted file mode 100644 index 7efc63bf..00000000 --- a/doc/tutorial/doc/quickstart.txt +++ /dev/null @@ -1,1426 +0,0 @@ -[doc Boost Python Tutorial] - -[def __note__ [$theme/note.gif]] -[def __alert__ [$theme/alert.gif]] -[def __detail__ [$theme/lens.gif]] -[def __tip__ [$theme/bulb.gif]] -[def :-) [$theme/smiley.gif]] - -[page QuickStart] - -The Boost Python Library is a framework for interfacing Python and -C++. It allows you to quickly and seamlessly expose C++ classes -functions and objects to Python, and vice-versa, using no special -tools -- just your C++ compiler. It is designed to wrap C++ interfaces -non-intrusively, so that you should not have to change the C++ code at -all in order to wrap it, making Boost.Python ideal for exposing -3rd-party libraries to Python. The library's use of advanced -metaprogramming techniques simplifies its syntax for users, so that -wrapping code takes on the look of a kind of declarative interface -definition language (IDL). - -[h2 Hello World] - -Following C/C++ tradition, let's start with the "hello, world". A C++ -Function: - - char const* greet() - { - return "hello, world"; - } - -can be exposed to Python by writing a Boost.Python wrapper: - - #include - using namespace boost::python; - - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet); - } - -That's it. We're done. We can now build this as a shared library. The -resulting DLL is now visible to Python. Here's a sample Python session: - - >>> import hello - >>> print hello.greet() - hello, world - -[:['[*Next stop... Building your Hello World module from start to finish...]]] - -[page Building Hello World] - -[h2 From Start To Finish] - -Now the first thing you'd want to do is to build the Hello World module and -try it for yourself in Python. In this section, we shall outline the steps -necessary to achieve that. We shall use the build tool that comes bundled -with every boost distribution: [*bjam]. - -[blurb __detail__ [*Building without bjam][br][br] - -Besides bjam, there are of course other ways to get your module built. -What's written here should not be taken as "the one and only way". -There are of course other build tools apart from [^bjam]. -] - -We shall skip over the details. Our objective will be to simply create the -hello world module and run it in Python. For a complete reference to -building Boost.Python, check out: [@../../building.html building.html]. -After this brief ['bjam] tutorial, we should have built two DLLs: - -* boost_python.dll -* hello.pyd - -if you are on Windows, and - -* libboost_python.so -* hello.so - -if you are on Unix. - -The tutorial example can be found in the directory: -[^libs/python/example/tutorial]. There, you can find: - -* hello.cpp -* Jamfile - -The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a -minimalist ['bjam] script that builds the DLLs for us. - -Before anything else, you should have the bjam executable in your boost -directory or somewhere in your path such that [^bjam] can be executed in -the command line. Pre-built Boost.Jam executables are available for most -platforms. For example, a pre-built Microsoft Windows bjam executable can -be downloaded [@http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip here]. -The complete list of bjam pre-built -executables can be found [@../../../../../tools/build/index.html#Jam here]. - -[h2 Lets Jam!] -[$theme/jam.png] - -Here is our minimalist Jamfile: - -[pre - subproject libs/python/example/tutorial ; - - SEARCH on python.jam = $(BOOST_BUILD_PATH) ; - include python.jam ; - - extension hello # Declare a Python extension called hello - : hello.cpp # source - ../../build/boost_python # dependencies - ; -] - -First, we need to specify our location in the boost project hierarchy. -It so happens that the tutorial example is located in [^/libs/python/example/tutorial]. -Thus: - -[pre - subproject libs/python/example/tutorial ; -] - -Then we will include the definitions needed by Python modules: - -[pre - SEARCH on python.jam = $(BOOST_BUILD_PATH) ; - include python.jam ; -] - -Finally we declare our [^hello] extension: - -[pre - extension hello # Declare a Python extension called hello - : hello.cpp # source - ../../build/boost_python # dependencies - ; -] - -[h2 Running bjam] - -['bjam] is run using your operating system's command line interpreter. - -[:Start it up.] - -Make sure that the environment is set so that we can invoke the C++ -compiler. With MSVC, that would mean running the [^Vcvars32.bat] batch -file. For instance: - - C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat - -Some environment variables will have to be setup for proper building of our -Python modules. Example: - - set PYTHON_ROOT=c:/dev/tools/python - set PYTHON_VERSION=2.2 - -The above assumes that the Python installation is in [^c:/dev/tools/python] -and that we are using Python version 2.2. You'll have to tweak this path -appropriately. __note__ Be sure not to include a third number, e.g. [*not] "2.2.1", -even if that's the version you have. - -Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial] -where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated. - -Finally: - - bjam -sTOOLS=msvc - -We are again assuming that we are using Microsoft Visual C++ version 6. If -not, then you will have to specify the appropriate tool. See -[@../../../../../tools/build/index.html Building Boost Libraries] for -further details. - -It should be building now: - -[pre - cd C:\dev\boost\libs\python\example\tutorial - bjam -sTOOLS=msvc - ...patience... - ...found 1703 targets... - ...updating 40 targets... -] - -And so on... Finally: - -[pre - vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\ - runtime-link-dynamic\hello.obj - hello.cpp - vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\ - runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\ - hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib - Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\ - msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\ - example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp - ...updated 40 targets... -] - -If all is well, you should now have: - -* boost_python.dll -* hello.pyd - -if you are on Windows, and - -* libboost_python.so -* hello.so - -if you are on Unix. - -[^boost_python.dll] can be found somewhere in [^libs\python\build\bin] -while [^hello.pyd] can be found somewhere in -[^libs\python\example\tutorial\bin]. After a successful build, you can just -link in these DLLs with the Python interpreter. In Windows for example, you -can simply put these libraries inside the directory where the Python -executable is. - -You may now fire up Python and run our hello module: - - >>> import hello - >>> print hello.greet() - hello, world - -[:[*There you go... Have fun!]] - -[page Exposing Classes] - -Now let's expose a C++ class to Python. - -Consider a C++ class/struct that we want to expose to Python: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -We can expose this to Python by writing a corresponding Boost.Python -C++ Wrapper: - - #include - using namespace boost::python; - - BOOST_PYTHON_MODULE(hello) - { - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -Here, we wrote a C++ class wrapper that exposes the member functions -[^greet] and [^set]. Now, after building our module as a shared library, we -may use our class [^World] in Python. Here's a sample Python session: - - >>> import hello - >>> planet = hello.World() - >>> planet.set('howdy') - >>> planet.greet() - 'howdy' - -[page:1 Constructors] - -Our previous example didn't have any explicit constructors. -Since [^World] is declared as a plain struct, it has an implicit default -constructor. Boost.Python exposes the default constructor by default, -which is why we were able to write - - >>> planet = hello.World() - -We may wish to wrap a class with a non-default constructor. Let us -build on our previous example: - - struct World - { - World(std::string msg): msg(msg) {} // added constructor - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -This time [^World] has no default constructor; our previous -wrapping code would fail to compile when the library tried to expose -it. We have to tell [^class_] about the constructor we want to -expose instead. - - #include - using namespace boost::python; - - BOOST_PYTHON_MODULE(hello) - { - class_("World", init()) - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -[^init()] exposes the constructor taking in a -[^std::string] (in Python, constructors are spelled -"[^"__init__"]"). - -We can expose additional constructors by passing more [^init<...>]s to -the [^def()] member function. Say for example we have another World -constructor taking in two doubles: - - class_("World", init()) - .def(init()) - .def("greet", &World::greet) - .def("set", &World::set) - ; - -On the other hand, if we do not wish to expose any constructors at -all, we may use [^no_init] instead: - - class_("Abstract", no_init) - -This actually adds an [^__init__] method which always raises a -Python RuntimeError exception. - -[page:1 Class Data Members] - -Data members may also be exposed to Python so that they can be -accessed as attributes of the corresponding Python class. Each data -member that we wish to be exposed may be regarded as [*read-only] or -[*read-write]. Consider this class [^Var]: - - struct Var - { - Var(std::string name) : name(name), value() {} - std::string const name; - float value; - }; - -Our C++ [^Var] class and its data members can be exposed to Python: - - class_("Var", init()) - .def_readonly("name", &Var::name) - .def_readwrite("value", &Var::value); - -Then, in Python, assuming we have placed our Var class inside the namespace -hello as we did before: - - >>> x = hello.Var('pi') - >>> x.value = 3.14 - >>> print x.name, 'is around', x.value - pi is around 3.14 - -Note that [^name] is exposed as [*read-only] while [^value] is exposed -as [*read-write]. - -[pre - >>> x.name = 'e' # can't change name - Traceback (most recent call last): - File "", line 1, in ? - AttributeError: can't set attribute -] - -[page:1 Class Properties] - -In C++, classes with public data members are usually frowned -upon. Well designed classes that take advantage of encapsulation hide -the class' data members. The only way to access the class' data is -through access (getter/setter) functions. Access functions expose class -properties. Here's an example: - - struct Num - { - Num(); - float get() const; - void set(float value); - ... - }; - -However, in Python attribute access is fine; it doesn't neccessarily break -encapsulation to let users handle attributes directly, because the -attributes can just be a different syntax for a method call. Wrapping our -[^Num] class using Boost.Python: - - class_("Num") - .add_property("rovalue", &Num::get) - .add_property("value", &Num::get, &Num::set); - -And at last, in Python: - - >>> x = Num() - >>> x.value = 3.14 - >>> x.value, x.rovalue - (3.14, 3.14) - >>> x.rovalue = 2.17 # error! - -Take note that the class property [^rovalue] is exposed as [*read-only] -since the [^rovalue] setter member function is not passed in: - - .add_property("rovalue", &Num::get) - -[page:1 Inheritance] - -In the previous examples, we dealt with classes that are not polymorphic. -This is not often the case. Much of the time, we will be wrapping -polymorphic classes and class hierarchies related by inheritance. We will -often have to write Boost.Python wrappers for classes that are derived from -abstract base classes. - -Consider this trivial inheritance structure: - - struct Base { virtual ~Base(); }; - struct Derived : Base {}; - -And a set of C++ functions operating on [^Base] and [^Derived] object -instances: - - void b(Base*); - void d(Derived*); - Base* factory() { return new Derived; } - -We've seen how we can wrap the base class [^Base]: - - class_("Base") - /*...*/ - ; - -Now we can inform Boost.Python of the inheritance relationship between -[^Derived] and its base class [^Base]. Thus: - - class_ >("Derived") - /*...*/ - ; - -Doing so, we get some things for free: - -# Derived automatically inherits all of Base's Python methods (wrapped C++ member functions) -# [*If] Base is polymorphic, [^Derived] objects which have been passed to Python via a pointer or reference to [^Base] can be passed where a pointer or reference to [^Derived] is expected. - -Now, we shall expose the C++ free functions [^b] and [^d] and [^factory]: - - def("b", b); - def("d", d); - def("factory", factory); - -Note that free function [^factory] is being used to generate new -instances of class [^Derived]. In such cases, we use -[^return_value_policy] to instruct Python to adopt -the pointer to [^Base] and hold the instance in a new Python [^Base] -object until the the Python object is destroyed. We shall see more of -Boost.Python [@call_policies.html call policies] later. - - // Tell Python to take ownership of factory's result - def("factory", factory, - return_value_policy()); - -[page:1 Class Virtual Functions] - -In this section, we shall learn how to make functions behave -polymorphically through virtual functions. Continuing our example, let us -add a virtual function to our [^Base] class: - - struct Base - { - virtual int f() = 0; - }; - -Since [^f] is a pure virtual function, [^Base] is now an abstract -class. Given an instance of our class, the free function [^call_f] -calls some implementation of this virtual function in a concrete -derived class: - - int call_f(Base& b) { return b.f(); } - -To allow this function to be implemented in a Python derived class, we -need to create a class wrapper: - - struct BaseWrap : Base - { - BaseWrap(PyObject* self_) - : self(self_) {} - int f() { return call_method(self, "f"); } - PyObject* self; - }; - -[blurb __detail__ [*member function and methods][br][br] Python, like -many object oriented languages uses the term [*methods]. Methods -correspond roughly to C++'s [*member functions]] - -Our class wrapper [^BaseWrap] is derived from [^Base]. Its overridden -virtual member function [^f] in effect calls the corresponding method -of the Python object [^self], which is a pointer back to the Python -[^Base] object holding our [^BaseWrap] instance. - -[blurb __note__ [*Why do we need BaseWrap?][br][br] - -['You may ask], "Why do we need the [^BaseWrap] derived class? This could -have been designed so that everything gets done right inside of -Base."[br][br] - -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.[br][br] - -Note however that you don't need to do this to get methods overridden -in Python to behave virtually when called ['from] [*Python]. The only -time you need to do the [^BaseWrap] dance is when you have a virtual -function that's going to be overridden in Python and called -polymorphically ['from] [*C++].] - -Wrapping [^Base] and the free function [^call_f]: - - class_("Base", no_init) - ; - def("call_f", call_f); - -Notice that we parameterized the [^class_] template with [^BaseWrap] as the -second parameter. What is [^noncopyable]? Without it, the library will try -to create code for converting Base return values of wrapped functions to -Python. To do that, it needs Base's copy constructor... which isn't -available, since Base is an abstract class. - -In Python, let us try to instantiate our [^Base] class: - - >>> base = Base() - RuntimeError: This class cannot be instantiated from Python - -Why is it an error? [^Base] is an abstract class. As such it is advisable -to define the Python wrapper with [^no_init] as we have done above. Doing -so will disallow abstract base classes such as [^Base] to be instantiated. - -[page:1 Deriving a Python Class] - -Continuing, we can derive from our base class Base in Python and override -the virtual function in Python. Before we can do that, we have to set up -our [^class_] wrapper as: - - class_("Base") - ; - -Otherwise, we have to suppress the Base class' [^no_init] by adding an -[^__init__()] method to all our derived classes. [^no_init] actually adds -an [^__init__] method that raises a Python RuntimeError exception. - - >>> class Derived(Base): - ... def f(self): - ... return 42 - ... - -Cool eh? A Python class deriving from a C++ class! - -Let's now make an instance of our Python class [^Derived]: - - >>> derived = Derived() - -Calling [^derived.f()]: - - >>> derived.f() - 42 - -Will yield the expected result. Finally, calling calling the free function -[^call_f] with [^derived] as argument: - - >>> call_f(derived) - 42 - -Will also yield the expected result. - -Here's what's happening: - -# [^call_f(derived)] is called in Python -# This corresponds to [^def("call_f", call_f);]. Boost.Python dispatches this call. -# [^int call_f(Base& b) { return b.f(); }] accepts the call. -# The overridden virtual function [^f] of [^BaseWrap] is called. -# [^call_method(self, "f");] dispatches the call back to Python. -# [^def f(self): return 42] is finally called. - -[page:1 Virtual Functions with Default Implementations] - -Recall that in the [@class_virtual_functions.html previous section], we -wrapped a class with a pure virtual function that we then implemented in -C++ or Python classes derived from it. Our base class: - - struct Base - { - virtual int f() = 0; - }; - -had a pure virtual function [^f]. If, however, its member function [^f] was -not declared as pure virtual: - - struct Base - { - virtual int f() { return 0; } - }; - -and instead had a default implementation that returns [^0], as shown above, -we need to add a forwarding function that calls the [^Base] default virtual -function [^f] implementation: - - struct BaseWrap : Base - { - BaseWrap(PyObject* self_) - : self(self_) {} - int f() { return call_method(self, "f"); } - int default_f() { return Base::f(); } // <<=== ***ADDED*** - PyObject* self; - }; - -Then, Boost.Python needs to keep track of 1) the dispatch function [^f] and -2) the forwarding function to its default implementation [^default_f]. -There's a special [^def] function for this purpose. Here's how it is -applied to our example above: - - class_("Base") - .def("f", &Base::f, &BaseWrap::default_f) - -Note that we are allowing [^Base] objects to be instantiated this time, -unlike before where we specifically defined the [^class_] with -[^no_init]. - -In Python, the results would be as expected: - - >>> base = Base() - >>> class Derived(Base): - ... def f(self): - ... return 42 - ... - >>> derived = Derived() - -Calling [^base.f()]: - - >>> base.f() - 0 - -Calling [^derived.f()]: - - >>> derived.f() - 42 - -Calling [^call_f], passing in a [^base] object: - - >>> call_f(base) - 0 - -Calling [^call_f], passing in a [^derived] object: - - >>> call_f(derived) - 42 - -[page:1 Class Operators/Special Functions] - -[h2 Python Operators] - -C is well known for the abundance of operators. C++ extends this to the -extremes by allowing operator overloading. Boost.Python takes advantage of -this and makes it easy to wrap C++ operator-powered classes. - -Consider a file position class [^FilePos] and a set of operators that take -on FilePos instances: - - class FilePos { /*...*/ }; - - FilePos operator+(FilePos, int); - FilePos operator+(int, FilePos); - int operator-(FilePos, FilePos); - FilePos operator-(FilePos, int); - FilePos& operator+=(FilePos&, int); - FilePos& operator-=(FilePos&, int); - bool operator<(FilePos, FilePos); - -The class and the various operators can be mapped to Python rather easily -and intuitively: - - class_("FilePos") - .def(self + int()) // __add__ - .def(int() + self) // __radd__ - .def(self - self) // __sub__ - .def(self - int()) // __sub__ - .def(self += int()) // __iadd__ - .def(self -= other()) - .def(self < self); // __lt__ - -The code snippet above is very clear and needs almost no explanation at -all. It is virtually the same as the operators' signatures. Just take -note that [^self] refers to FilePos object. Also, not every class [^T] that -you might need to interact with in an operator expression is (cheaply) -default-constructible. You can use [^other()] in place of an actual -[^T] instance when writing "self expressions". - -[h2 Special Methods] - -Python has a few more ['Special Methods]. Boost.Python supports all of the -standard special method names supported by real Python class instances. A -similar set of intuitive interfaces can also be used to wrap C++ functions -that correspond to these Python ['special functions]. Example: - - class Rational - { operator double() const; }; - - Rational pow(Rational, Rational); - Rational abs(Rational); - ostream& operator<<(ostream&,Rational); - - class_() - .def(float_(self)) // __float__ - .def(pow(self, other)) // __pow__ - .def(abs(self)) // __abs__ - .def(str(self)) // __str__ - ; - -Need we say more? - -[blurb __detail__ What is the business of [^operator<<] [^.def(str(self))]? -Well, the method [^str] requires the [^operator<<] to do its work (i.e. -[^operator<<] is used by the method defined by def(str(self)).] - -[page Functions] - -In this chapter, we'll look at Boost.Python powered functions in closer -detail. We shall see some facilities to make exposing C++ functions to -Python safe from potential pifalls such as dangling pointers and -references. We shall also see facilities that will make it even easier for -us to expose C++ functions that take advantage of C++ features such as -overloading and default arguments. - -[:['Read on...]] - -But before you do, you might want to fire up Python 2.2 or later and type -[^>>> import this]. - -[pre - >>> import this - The Zen of Python, by Tim Peters - Beautiful is better than ugly. - Explicit is better than implicit. - Simple is better than complex. - Complex is better than complicated. - Flat is better than nested. - Sparse is better than dense. - Readability counts. - Special cases aren't special enough to break the rules. - Although practicality beats purity. - Errors should never pass silently. - Unless explicitly silenced. - In the face of ambiguity, refuse the temptation to guess. - There should be one-- and preferably only one --obvious way to do it - Although that way may not be obvious at first unless you're Dutch. - Now is better than never. - Although never is often better than *right* now. - If the implementation is hard to explain, it's a bad idea. - If the implementation is easy to explain, it may be a good idea. - Namespaces are one honking great idea -- let's do more of those! -] - -[page:1 Call Policies] - -In C++, we often deal with arguments and return types such as pointers -and references. Such primitive types are rather, ummmm, low level and -they really don't tell us much. At the very least, we don't know the -owner of the pointer or the referenced object. No wonder languages -such as Java and Python never deal with such low level entities. In -C++, it's usually considered a good practice to use smart pointers -which exactly describe ownership semantics. Still, even good C++ -interfaces use raw references and pointers sometimes, so Boost.Python -must deal with them. To do this, it may need your help. Consider the -following C++ function: - - X& f(Y& y, Z* z); - -How should the library wrap this function? A naive approach builds a -Python X object around result reference. This strategy might or might -not work out. Here's an example where it didn't - - >>> x = f(y, z) # x refers to some C++ X - >>> del y - >>> x.some_method() # CRASH! - -What's the problem? - -Well, what if f() was implemented as shown below: - - X& f(Y& y, Z* z) - { - y.z = z; - return y.x; - } - -The problem is that the lifetime of result X& is tied to the lifetime -of y, because the f() returns a reference to a member of the y -object. This idiom is is not uncommon and perfectly acceptable in the -context of C++. However, Python users should not be able to crash the -system just by using our C++ interface. In this case deleting y will -invalidate the reference to X. We have a dangling reference. - -Here's what's happening: - -# [^f] is called passing in a reference to [^y] and a pointer to [^z] -# A reference to [^y.x] is returned -# [^y] is deleted. [^x] is a dangling reference -# [^x.some_method()] is called -# [*BOOM!] - -We could copy result into a new object: - - >>> f(y, z).set(42) # Result disappears - >>> y.x.get() # No crash, but still bad - 3.14 - -This is not really our intent of our C++ interface. We've broken our -promise that the Python interface should reflect the C++ interface as -closely as possible. - -Our problems do not end there. Suppose Y is implemented as follows: - - struct Y - { - X x; Z* z; - int z_value() { return z->value(); } - }; - -Notice that the data member [^z] is held by class Y using a raw -pointer. Now we have a potential dangling pointer problem inside Y: - - >>> x = f(y, z) # y refers to z - >>> del z # Kill the z object - >>> y.z_value() # CRASH! - -For reference, here's the implementation of [^f] again: - - X& f(Y& y, Z* z) - { - y.z = z; - return y.x; - } - -Here's what's happening: - -# [^f] is called passing in a reference to [^y] and a pointer to [^z] -# A pointer to [^z] is held by [^y] -# A reference to [^y.x] is returned -# [^z] is deleted. [^y.z] is a dangling pointer -# [^y.z_value()] is called -# [^z->value()] is called -# [*BOOM!] - -[h2 Call Policies] - -Call Policies may be used in situations such as the example detailed above. -In our example, [^return_internal_reference] and [^with_custodian_and_ward] -are our friends: - - def("f", f, - return_internal_reference<1, - with_custodian_and_ward<1, 2> >()); - -What are the [^1] and [^2] parameters, you ask? - - return_internal_reference<1 - -Informs Boost.Python that the first argument, in our case [^Y& y], is the -owner of the returned reference: [^X&]. The "[^1]" simply specifies the -first argument. In short: "return an internal reference [^X&] owned by the -1st argument [^Y& y]". - - with_custodian_and_ward<1, 2> - -Informs Boost.Python that the lifetime of the argument indicated by ward -(i.e. the 2nd argument: [^Z* z]) is dependent on the lifetime of the -argument indicated by custodian (i.e. the 1st argument: [^Y& y]). - -It is also important to note that we have defined two policies above. Two -or more policies can be composed by chaining. Here's the general syntax: - - policy1 > > - -Here is the list of predefined call policies. A complete reference detailing -these can be found [@../../v2/reference.html#models_of_call_policies here]. - -* [*with_custodian_and_ward][br] Ties lifetimes of the arguments -* [*with_custodian_and_ward_postcall][br] Ties lifetimes of the arguments and results -* [*return_internal_reference][br] Ties lifetime of one argument to that of result -* [*return_value_policy with T one of:][br] -* [*reference_existing_object][br]naïve (dangerous) approach -* [*copy_const_reference][br]Boost.Python v1 approach -* [*copy_non_const_reference][br] -* [*manage_new_object][br] Adopt a pointer and hold the instance - -[blurb :-) [*Remember the Zen, Luke:][br][br] -"Explicit is better than implicit"[br] -"In the face of ambiguity, refuse the temptation to guess"[br]] - -[page:1 Overloading] - -The following illustrates a scheme for manually wrapping an overloaded -member functions. Of course, the same technique can be applied to wrapping -overloaded non-member functions. - -We have here our C++ class: - - struct X - { - bool f(int a) - { - return true; - } - - bool f(int a, double b) - { - return true; - } - - bool f(int a, double b, char c) - { - return true; - } - - int f(int a, int b, int c) - { - return a + b + c; - }; - }; - -Class X has 4 overloaded functions. We shall start by introducing some -member function pointer variables: - - bool (X::*fx1)(int) = &X::f; - bool (X::*fx2)(int, double) = &X::f; - bool (X::*fx3)(int, double, char)= &X::f; - int (X::*fx4)(int, int, int) = &X::f; - -With these in hand, we can proceed to define and wrap this for Python: - - .def("f", fx1) - .def("f", fx2) - .def("f", fx3) - .def("f", fx4) - -[page:1 Default Arguments] - -Boost.Python wraps (member) function pointers. Unfortunately, C++ function -pointers carry no default argument info. Take a function [^f] with default -arguments: - - int f(int, double = 3.14, char const* = "hello"); - -But the type of a pointer to the function [^f] has no information -about its default arguments: - - int(*g)(int,double,char const*) = f; // defaults lost! - -When we pass this function pointer to the [^def] function, there is no way -to retrieve the default arguments: - - def("f", f); // defaults lost! - -Because of this, when wrapping C++ code, we had to resort to manual -wrapping as outlined in the [@overloading.html previous section], or -writing thin wrappers: - - // write "thin wrappers" - int f1(int x) { f(x); } - int f2(int x, double y) { f(x,y); } - - /*...*/ - - // in module init - def("f", f); // all arguments - def("f", f2); // two arguments - def("f", f1); // one argument - -When you want to wrap functions (or member functions) that either: - -* have default arguments, or -* are overloaded with a common sequence of initial arguments - -[h2 BOOST_PYTHON_FUNCTION_OVERLOADS] - -Boost.Python now has a way to make it easier. For instance, given a function: - - int foo(int a, char b = 1, unsigned c = 2, double d = 3) - { - /*...*/ - } - -The macro invocation: - - BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4) - -will automatically create the thin wrappers for us. This macro will create -a class [^foo_overloads] that can be passed on to [^def(...)]. The third -and fourth macro argument are the minimum arguments and maximum arguments, -respectively. In our [^foo] function the minimum number of arguments is 1 -and the maximum number of arguments is 4. The [^def(...)] function will -automatically add all the foo variants for us: - - .def("foo", foo, foo_overloads()); - -[h2 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] - -Objects here, objects there, objects here there everywhere. More frequently -than anything else, we need to expose member functions of our classes to -Python. Then again, we have the same inconveniences as before when default -arguments or overloads with a common sequence of initial arguments come -into play. Another macro is provided to make this a breeze. - -Like [^BOOST_PYTHON_FUNCTION_OVERLOADS], -[^BOOST_PYTHON_FUNCTION_OVERLOADS] may be used to automatically create -the thin wrappers for wrapping member functions. Let's have an example: - - struct george - { - void - wack_em(int a, int b = 0, char c = 'x') - { - /*...*/ - } - }; - -The macro invocation: - - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3) - -will generate a set of thin wrappers for george's [^wack_em] member function -accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and -fourth macro argument). The thin wrappers are all enclosed in a class named -[^george_overloads] that can then be used as an argument to [^def(...)]: - - .def("wack_em", &george::wack_em, george_overloads()); - -See the [@../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec overloads reference] -for details. - -[h2 init and optional] - -A similar facility is provided for class constructors, again, with -default arguments or a sequence of overloads. Remember [^init<...>]? For example, -given a class X with a constructor: - - struct X - { - X(int a, char b = 'D', std::string c = "constructor", double d = 0.0); - /*...*/ - } - -You can easily add this constructor to Boost.Python in one shot: - - .def(init >()) - -Notice the use of [^init<...>] and [^optional<...>] to signify the default -(optional arguments). - -[page:1 Auto-Overloading] - -It was mentioned in passing in the previous section that -[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_FUNCTION_OVERLOADS] -can also be used for overloaded functions and member functions with a -common sequence of initial arguments. Here is an example: - - void foo() - { - /*...*/ - } - - void foo(bool a) - { - /*...*/ - } - - void foo(bool a, int b) - { - /*...*/ - } - - void foo(bool a, int b, char c) - { - /*...*/ - } - -Like in the previous section, we can generate thin wrappers for these -overloaded functions in one-shot: - - BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3) - -Then... - - .def("foo", foo, foo_overloads()); - -Notice though that we have a situation now where we have a minimum of zero -(0) arguments and a maximum of 3 arguments. - -[h2 Manual Wrapping] - -It is important to emphasize however that [*the overloaded functions must -have a common sequence of initial arguments]. Otherwise, our scheme above -will not work. If this is not the case, we have to wrap our functions -[@overloading.html manually]. - -Actually, we can mix and match manual wrapping of overloaded functions and -automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and -its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Following up on our example -presented in the section [@overloading.html on overloading], since the -first 4 overload functins have a common sequence of initial arguments, we -can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the -first three of the [^def]s and manually wrap just the last. Here's -how we'll do this: - - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4) - -Create a member function pointers as above for both X::f overloads: - - bool (X::*fx1)(int, double, char) = &X::f; - int (X::*fx2)(int, int, int) = &X::f; - -Then... - - .def("f", fx1, xf_overloads()); - .def("f", fx2) - -[page Object Interface] - -Python is dynamically typed, unlike C++ which is statically typed. Python -variables may hold an integer, a float, list, dict, tuple, str, long etc., -among other things. In the viewpoint of Boost.Python and C++, these -Pythonic variables are just instances of class [^object]. We shall see in -this chapter how to deal with Python objects. - -As mentioned, one of the goals of Boost.Python is to provide a -bidirectional mapping between C++ and Python while maintaining the Python -feel. Boost.Python C++ [^object]s are as close as possible to Python. This -should minimize the learning curve significantly. - -[$theme/python.png] - -[page:1 Basic Interface] - -Class [^object] wraps [^PyObject*]. All the intricacies of dealing with -[^PyObject]s such as managing reference counting are handled by the -[^object] class. C++ object interoperability is seamless. Boost.Python C++ -[^object]s can in fact be explicitly constructed from any C++ object. - -To illustrate, this Python code snippet: - - def f(x, y): - if (y == 'foo'): - x[3:7] = 'bar' - else: - x.items += y(3, x) - return x - - def getfunc(): - return f; - -Can be rewritten in C++ using Boost.Python facilities this way: - - object f(object x, object y) { - if (y == "foo") - x.slice(3,7) = "bar"; - else - x.attr("items") += y(3, x); - return x; - } - object getfunc() { - return object(f); - } - -Apart from cosmetic differences due to the fact that we are writing the -code in C++, the look and feel should be immediately apparent to the Python -coder. - -[page:1 Derived Object types] - -Boost.Python comes with a set of derived [^object] types corresponding to -that of Python's: - -* list -* dict -* tuple -* str -* long_ -* enum - -These derived [^object] types act like real Python types. For instance: - - str(1) ==> "1" - -Wherever appropriate, a particular derived [^object] has corresponding -Python type's methods. For instance, [^dict] has a [^keys()] method: - - d.keys() - -[^make_tuple] is provided for declaring ['tuple literals]. Example: - - make_tuple(123, 'D', "Hello, World", 0.0); - -In C++, when Boost.Python [^object]s are used as arguments to functions, -subtype matching is required. For example, when a function [^f], as -declared below, is wrapped, it will only accept instances of Python's -[^str] type and subtypes. - - void f(str name) - { - object n2 = name.attr("upper")(); // NAME = name.upper() - str NAME = name.upper(); // better - object msg = "%s is bigger than %s" % make_tuple(NAME,name); - } - -In finer detail: - - str NAME = name.upper(); - -Illustrates that we provide versions of the str type's methods as C++ -member functions. - - object msg = "%s is bigger than %s" % make_tuple(NAME,name); - -Demonstrates that you can write the C++ equivalent of [^"format" % x,y,z] -in Python, which is useful since there's no easy way to do that in std C++. - -__alert__ [*Beware] the common pitfall of forgetting that the constructors -of most of Python's mutable types make copies, just as in Python. - -Python: - - >>> d = dict(x.__dict__) # copies x.__dict__ - >>> d['whatever'] # modifies the copy - -C++: - - dict d(x.attr("__dict__")); # copies x.__dict__ - d['whatever'] = 3; # modifies the copy - -[h2 class_ as objects] - -Due to the dynamic nature of Boost.Python objects, any [^class_] may -also be one of these types! The following code snippet wraps the class -(type) object. - -We can use this to create wrapped instances. Example: - - object vec345 = ( - class_("Vec2", init()) - .def_readonly("length", &Point::length) - .def_readonly("angle", &Point::angle) - )(3.0, 4.0); - - assert(vec345.attr("length") == 5.0); - -[page:1 Extracting C++ objects] - -At some point, we will need to get C++ values out of object instances. This -can be achieved with the [^extract] function. Consider the following: - - double x = o.attr("length"); // compile error - -In the code above, we got a compiler error because Boost.Python -[^object] can't be implicitly converted to [^double]s. Instead, what -we wanted to do above can be achieved by writing: - - double l = extract(o.attr("length")); - Vec2& v = extract(o); - assert(l == v.length()); - -The first line attempts to extract the "length" attribute of the -Boost.Python [^object] [^o]. The second line attempts to ['extract] the -[^Vec2] object from held by the Boost.Python [^object] [^o]. - -Take note that we said "attempt to" above. What if the Boost.Python -[^object] [^o] does not really hold a [^Vec2] type? This is certainly -a possibility considering the dynamic nature of Python [^object]s. To -be on the safe side, if the C++ type can't be extracted, an -appropriate exception is thrown. To avoid an exception, we need to -test for extractibility: - - extract x(o); - if (x.check()) { - Vec2& v = x(); ... - -__tip__ The astute reader might have noticed that the [^extract] -facility in fact solves the mutable copying problem: - - dict d = extract(x.attr("__dict__")); - d['whatever'] = 3; # modifies x.__dict__ ! - - -[page:1 Enums] - -Boost.Python has a nifty facility to capture and wrap C++ enums. While -Python has no [^enum] type, we'll often want to expose our C++ enums to -Python as an [^int]. Boost.Python's enum facility makes this easy while -taking care of the proper conversions from Python's dynamic typing to C++'s -strong static typing (in C++, ints cannot be implicitly converted to -enums). To illustrate, given a C++ enum: - - enum choice { red, blue }; - -the construct: - - enum_("choice") - .value("red", red) - .value("blue", blue) - ; - -can be used to expose to Python. The new enum type is created in the -current [^scope()], which is usually the current module. The snippet above -creates a Python class derived from Python's [^int] type which is -associated with the C++ type passed as its first parameter. - -[blurb __detail__ [*what is a scope?][br][br] The scope is a class that has an -associated global Python object which controls the Python namespace in -which new extension classes and wrapped functions will be defined as -attributes. Details can be found [@../../v2/scope.html here].] - -You can access those values in Python as - - >>> my_module.choice.red - my_module.choice.red - -where my_module is the module where the enum is declared. You can also -create a new scope around a class: - - scope in_X = class_("X") - .def( ... ) - .def( ... ) - ; - - // Expose X::nested as X.nested - enum_("nested") - .value("red", red) - .value("blue", blue) - ; - -[page Iterators] - -In C++, and STL in particular, we see iterators everywhere. Python also has -iterators, but these are two very different beasts. - -[*C++ iterators:] - -* C++ has 5 type categories (random-access, bidirectional, forward, input, output) -* There are 2 Operation categories: reposition, access -* A pair of iterators is needed to represent a (first/last) range. - -[*Python Iterators:] - -* 1 category (forward) -* 1 operation category (next()) -* Raises StopIteration exception at end - -The typical Python iteration protocol: [^[*for y in x...]] is as follows: - - iter = x.__iter__() # get iterator - try: - while 1: - y = iter.next() # get each item - ... # process y - except StopIteration: pass # iterator exhausted - -Boost.Python provides some mechanisms to make C++ iterators play along -nicely as Python iterators. What we need to do is to produce -appropriate __iter__ function from C++ iterators that is compatible -with the Python iteration protocol. For example: - - object get_iterator = iterator >(); - object iter = get_iterator(v); - object first = iter.next(); - -Or for use in class_<>: - - .def("__iter__", iterator >()) - -[*range] - -We can create a Python savvy iterator using the range function: - -* range(start, finish) -* range(start, finish) - -Here, start/finish may be one of: - -* member data pointers -* member function pointers -* adaptable function object (use Target parameter) - -[*iterator] - -* iterator() - -Given a container [^T], iterator is a shortcut that simply calls [^range] -with &T::begin, &T::end. - -Let's put this into action... Here's an example from some hypothetical -bogon Particle accelerator code: - - f = Field() - for x in f.pions: - smash(x) - for y in f.bogons: - count(y) - -Now, our C++ Wrapper: - - class_("Field") - .property("pions", range(&F::p_begin, &F::p_end)) - .property("bogons", range(&F::b_begin, &F::b_end)); - -[page Exception Translation] - -All C++ exceptions must be caught at the boundary with Python code. This -boundary is the point where C++ meets Python. Boost.Python provides a -default exception handler that translates selected standard exceptions, -then gives up: - - raise RuntimeError, 'unidentifiable C++ Exception' - -Users may provide custom translation. Here's an example: - - struct PodBayDoorException; - void translator(PodBayDoorException const& x) { - PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave..."); - } - BOOST_PYTHON_MODULE(kubrick) { - register_exception_translator< - PodBayDoorException>(translator); - ... - diff --git a/doc/tutorial/doc/theme/alert.gif b/doc/tutorial/doc/theme/alert.gif deleted file mode 100644 index 270764cc..00000000 Binary files a/doc/tutorial/doc/theme/alert.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/arrow.gif b/doc/tutorial/doc/theme/arrow.gif deleted file mode 100644 index e33db0fb..00000000 Binary files a/doc/tutorial/doc/theme/arrow.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/bkd.gif b/doc/tutorial/doc/theme/bkd.gif deleted file mode 100644 index dcabcb80..00000000 Binary files a/doc/tutorial/doc/theme/bkd.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/bkd2.gif b/doc/tutorial/doc/theme/bkd2.gif deleted file mode 100644 index b03d9ba9..00000000 Binary files a/doc/tutorial/doc/theme/bkd2.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/bulb.gif b/doc/tutorial/doc/theme/bulb.gif deleted file mode 100644 index 74f3baac..00000000 Binary files a/doc/tutorial/doc/theme/bulb.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/bullet.gif b/doc/tutorial/doc/theme/bullet.gif deleted file mode 100644 index da787e2e..00000000 Binary files a/doc/tutorial/doc/theme/bullet.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/c++boost.gif b/doc/tutorial/doc/theme/c++boost.gif deleted file mode 100644 index 58be431a..00000000 Binary files a/doc/tutorial/doc/theme/c++boost.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/jam.png b/doc/tutorial/doc/theme/jam.png deleted file mode 100644 index 224ed791..00000000 Binary files a/doc/tutorial/doc/theme/jam.png and /dev/null differ diff --git a/doc/tutorial/doc/theme/l_arr.gif b/doc/tutorial/doc/theme/l_arr.gif deleted file mode 100644 index 5b3cb1cb..00000000 Binary files a/doc/tutorial/doc/theme/l_arr.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/l_arr_disabled.gif b/doc/tutorial/doc/theme/l_arr_disabled.gif deleted file mode 100644 index ed58a605..00000000 Binary files a/doc/tutorial/doc/theme/l_arr_disabled.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/lens.gif b/doc/tutorial/doc/theme/lens.gif deleted file mode 100644 index c7901819..00000000 Binary files a/doc/tutorial/doc/theme/lens.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/note.gif b/doc/tutorial/doc/theme/note.gif deleted file mode 100644 index bd92f075..00000000 Binary files a/doc/tutorial/doc/theme/note.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/python.png b/doc/tutorial/doc/theme/python.png deleted file mode 100644 index cc2ff1d5..00000000 Binary files a/doc/tutorial/doc/theme/python.png and /dev/null differ diff --git a/doc/tutorial/doc/theme/r_arr.gif b/doc/tutorial/doc/theme/r_arr.gif deleted file mode 100644 index 2dcdad11..00000000 Binary files a/doc/tutorial/doc/theme/r_arr.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/r_arr_disabled.gif b/doc/tutorial/doc/theme/r_arr_disabled.gif deleted file mode 100644 index 2100f78b..00000000 Binary files a/doc/tutorial/doc/theme/r_arr_disabled.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/smiley.gif b/doc/tutorial/doc/theme/smiley.gif deleted file mode 100644 index 4c848f8f..00000000 Binary files a/doc/tutorial/doc/theme/smiley.gif and /dev/null differ diff --git a/doc/tutorial/doc/theme/style.css b/doc/tutorial/doc/theme/style.css deleted file mode 100644 index 53a6205e..00000000 --- a/doc/tutorial/doc/theme/style.css +++ /dev/null @@ -1,170 +0,0 @@ -body -{ - background-image: url(bkd.gif); - background-color: #FFFFFF; - margin: 1em 2em 1em 2em; -} - -h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; } -h2 { font: 140% sans-serif; font-weight: bold; text-align: left; } -h3 { font: 120% sans-serif; font-weight: bold; text-align: left; } -h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; } -h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; } -h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; } - -pre -{ - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-top: 2pt; - padding-right: 2pt; - padding-left: 2pt; - padding-bottom: 2pt; - - display: block; - font-family: "courier new", courier, mono; - background-color: #eeeeee; font-size: small -} - -code -{ - font-family: "Courier New", Courier, mono; - font-size: small -} - -tt -{ - display: inline; - font-family: "Courier New", Courier, mono; - color: #000099; - font-size: small -} - -p -{ - text-align: justify; - font-family: Georgia, "Times New Roman", Times, serif -} - -ul -{ - list-style-image: url(bullet.gif); - font-family: Georgia, "Times New Roman", Times, serif -} - -ol -{ - font-family: Georgia, "Times New Roman", Times, serif -} - -a -{ - font-weight: bold; - color: #003366; - text-decoration: none; -} - -a:hover { color: #8080FF; } - -.literal { color: #666666; font-style: italic} -.keyword { color: #000099} -.identifier {} -.comment { font-style: italic; color: #990000} -.special { color: #800040} -.preprocessor { color: #FF0000} -.string { font-style: italic; color: #666666} -.copyright { color: #666666; font-size: small} -.white_bkd { background-color: #FFFFFF} -.dk_grey_bkd { background-color: #999999} -.quotes { color: #666666; font-style: italic; font-weight: bold} - -.note_box -{ - display: block; - - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-right: 12pt; - padding-left: 12pt; - padding-bottom: 12pt; - padding-top: 12pt; - - font-family: Arial, Helvetica, sans-serif; - background-color: #E2E9EF; - font-size: small; text-align: justify -} - -.table_title -{ - background-color: #648CCA; - - font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; - font-weight: bold -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.table_cells -{ - background-color: #E2E9EF; - - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.toc -{ - DISPLAY: block; - background-color: #E2E9EF - font-family: Arial, Helvetica, sans-serif; - - border-top: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - border-right: gray 1pt solid; - - padding-top: 24pt; - padding-right: 24pt; - padding-left: 24pt; - padding-bottom: 24pt; -} - -.toc_title -{ - background-color: #648CCA; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - color: #FFFFFF; - font-weight: bold -} - -.toc_cells -{ - background-color: #E2E9EF; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -} - -div.logo -{ - float: right; -} - -.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } diff --git a/doc/tutorial/doc/theme/u_arr.gif b/doc/tutorial/doc/theme/u_arr.gif deleted file mode 100644 index ada3d6e0..00000000 Binary files a/doc/tutorial/doc/theme/u_arr.gif and /dev/null differ diff --git a/doc/tutorial/doc/using_the_interpreter.html b/doc/tutorial/doc/using_the_interpreter.html deleted file mode 100644 index 4c0e4de9..00000000 --- a/doc/tutorial/doc/using_the_interpreter.html +++ /dev/null @@ -1,236 +0,0 @@ - - - -Using the interpreter - - - - - - - - - - -
- - Using the interpreter -
-
- - - - - - -
-

-As you probably already know, objects in Python are reference-counted. -Naturally, the PyObjects of the Python/C API are also reference-counted. -There is a difference however. While the reference-counting is fully -automatic in Python, the Python/C API requires you to do it - -by hand. This is -messy and especially hard to get right in the presence of C++ exceptions. -Fortunately Boost.Python provides the -handle class -template to automate the process.

-

Reference-counting handles

-There are two ways in which a function in the Python/C API can return a -PyObject*: as a borrowed reference or as a new reference. Which of -these a function uses, is listed in that function's documentation. The two -require slightely different approaches to reference-counting but both can -be 'handled' by Boost.Python.

-

-For a function returning a borrowed reference we'll have to tell the -handle that the PyObject* is borrowed with the aptly named - -borrowed function. Two functions -returning borrowed references are -PyImport_AddModule and -PyModule_GetDict. -The former returns a reference to an already imported module, the latter -retrieves a module's namespace dictionary. Let's use them to retrieve the -namespace of the __main__ module:

-
-    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
-    handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
-
-

-Because the Python/C API doesn't know anything about handles, we used -the -get member function to -retrieve the PyObject* from which the handle was constructed.

-

-For a function returning a new reference we can just create a handle -out of the raw PyObject* without wrapping it in a call to borrowed. One -such function that returns a new reference is -PyRun_String which we'll -discuss in the next section.

- - - - -
- Handle is a class template, so why haven't we been using any template parameters?
-
-handle has a single template parameter specifying the type of the managed object. This type is PyObject 99% of the time, so the parameter was defaulted to PyObject for convenience. Therefore we can use the shorthand handle<> instead of the longer, but equivalent, handle<PyObject>. -
-

Running Python code

-To run Python code from C++ there is a family of functions in the API -starting with the PyRun prefix. You can find the full list of these -functions -here. They -all work similarly so we will look at only one of them, namely:

-
-    PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
-
-

- -PyRun_String takes the code to execute as a null-terminated (C-style) -string in its str parameter. The function returns a new reference to a -Python object. Which object is returned depends on the start paramater.

-

-The start parameter is the start symbol from the Python grammar to use -for interpreting the code. The possible values are:

- - - -
-Start symbols
-Py_eval_inputfor interpreting isolated expressions
-Py_file_inputfor interpreting sequences of statements
-Py_single_inputfor interpreting a single statement
-

-When using -Py_eval_input, the input string must contain a single expression -and its result is returned. When using -Py_file_input, the string can -contain an abitrary number of statements and None is returned. - -Py_single_input works in the same way as -Py_file_input but only accepts a -single statement.

-

-Lastly, the globals and locals parameters are Python dictionaries -containing the globals and locals of the context in which to run the code. -For most intents and purposes you can use the namespace dictionary of the -__main__ module for both parameters.

-

-We have already seen how to get the __main__ module's namespace so let's -run some Python code in it:

-
-    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
-    handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
-    handle<>( PyRun_String("hello = file('hello.txt', 'w')\n"
-                           "hello.write('Hello world!')\n"
-                           "hello.close()", Py_file_input,
-                           main_namespace.get(), main_namespace.get()) );
-
-

-This should create a file called 'hello.txt' in the current directory -containing a phrase that is well-known in programming circles.

-

- Note that we wrap the return value of -PyRun_String in a -(nameless) handle even though we are not interested in it. If we didn't -do this, the the returned object would be kept alive unnecessarily. Unless -you want to be a Dr. Frankenstein, always wrap PyObject*s in handles.

-

Beyond handles

-It's nice that handle manages the reference counting details for us, but -other than that it doesn't do much. Often we'd like to have a more useful -class to manipulate Python objects. But we have already seen such a class -in the -previous section: the aptly named object -class and it's derivatives. What we haven't seen, is that they can be -constructed from a handle. The following examples should illustrate this -fact:

-
-    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
-    main_namespace dict(handle<>(borrowed( PyModule_GetDict(main_module.get()) )));
-    handle<>( PyRun_String("result = 5 ** 2", Py_file_input,
-                           main_namespace.ptr(), main_namespace.ptr()) );
-    int five_squared = extract<int>( main_namespace["result"] );
-
-

-Here we create a dictionary object for the __main__ module's namespace. -Then we assign 5 squared to the result variable and read this variable from -the dictionary. Another way to achieve the same result is to let - -PyRun_String return the result directly with -Py_eval_input:

-
-    object result(handle<>( PyRun_String("5 ** 2", Py_eval_input,
-                                         main_namespace.ptr(), main_namespace.ptr()) ));
-    int five_squared = extract<int>(result);
-
-

- Note that object's member function to return the wrapped -PyObject* is called ptr instead of get. This makes sense if you -take into account the different functions that object and handle -perform.

-

Exception handling

-If an exception occurs in the execution of some Python code, the -PyRun_String function returns a null pointer. Constructing a handle out of this null pointer throws -error_already_set, so basically, the Python exception is automatically translated into a C++ exception when using handle:

-
-    try
-    {
-        object result(handle<>( PyRun_String("5/0", Py_eval_input,
-                                             main_namespace.ptr(), main_namespace.ptr()) ));
-        // execution will never get here:
-        int five_divided_by_zero = extract<int>(result);
-    }
-    catch(error_already_set)
-    {
-        // handle the exception in some way
-    }
-
-

-The error_already_set exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the -exception handling functions of the Python/C API in your catch-statement. This can be as simple as calling -PyErr_Print() to print the exception's traceback to the console, or comparing the type of the exception with those of the -standard exceptions:

-
-    catch(error_already_set)
-    {
-        if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
-        {
-            // handle ZeroDivisionError specially
-        }
-        else
-        {
-            // print all other errors to stderr
-            PyErr_Print();
-        }
-    }
-
-

-(To retrieve even more information from the exception you can use some of the other exception handling functions listed -here.)

-

-If you'd rather not have handle throw a C++ exception when it is constructed, you can use the -allow_null function in the same way you'd use borrowed:

-
-    handle<> result(allow_null( PyRun_String("5/0", Py_eval_input,
-                                             main_namespace.ptr(), main_namespace.ptr()) ));
-    if (!result)
-        // Python exception occurred
-    else
-        // everything went okay, it's safe to use the result
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/virtual_functions_with_default_implementations.html b/doc/tutorial/doc/virtual_functions_with_default_implementations.html deleted file mode 100644 index f7b15115..00000000 --- a/doc/tutorial/doc/virtual_functions_with_default_implementations.html +++ /dev/null @@ -1,122 +0,0 @@ - - - -Virtual Functions with Default Implementations - - - - - - - - - - -
- - Virtual Functions with Default Implementations -
-
- - - - - - -
-

-Recall that in the -previous section, we -wrapped a class with a pure virtual function that we then implemented in -C++ or Python classes derived from it. Our base class:

-
-    struct Base
-    {
-        virtual int f() = 0;
-    };
-
-

-had a pure virtual function f. If, however, its member function f was -not declared as pure virtual:

-
-    struct Base
-    {
-        virtual int f() { return 0; }
-    };
-
-

-and instead had a default implementation that returns 0, as shown above, -we need to add a forwarding function that calls the Base default virtual -function f implementation:

-
-    struct BaseWrap : Base
-    {
-        BaseWrap(PyObject* self_)
-            : self(self_) {}
-        int f() { return call_method<int>(self, "f"); }
-        int default_f() { return Base::f(); } // <<=== ***ADDED***
-        PyObject* self;
-    };
-
-

-Then, Boost.Python needs to keep track of 1) the dispatch function f and -2) the forwarding function to its default implementation default_f. -There's a special def function for this purpose. Here's how it is -applied to our example above:

-
-    class_<Base, BaseWrap>("Base")
-        .def("f", &Base::f, &BaseWrap::default_f)
-
-

-Note that we are allowing Base objects to be instantiated this time, -unlike before where we specifically defined the class_<Base> with -no_init.

-

-In Python, the results would be as expected:

-
-    >>> base = Base()
-    >>> class Derived(Base):
-    ...     def f(self):
-    ...         return 42
-    ...
-    >>> derived = Derived()
-
-

-Calling base.f():

-
-    >>> base.f()
-    0
-
-

-Calling derived.f():

-
-    >>> derived.f()
-    42
-
-

-Calling call_f, passing in a base object:

-
-    >>> call_f(base)
-    0
-
-

-Calling call_f, passing in a derived object:

-
-    >>> call_f(derived)
-    42
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html deleted file mode 100644 index eaeffa03..00000000 --- a/doc/tutorial/index.html +++ /dev/null @@ -1,156 +0,0 @@ - - - -Boost Python Tutorial - - - - - - - - - -
- - Boost Python Tutorial -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table of contents
- QuickStart -
- Building Hello World -
- Exposing Classes -
- Constructors -
- Class Data Members -
- Class Properties -
- Inheritance -
- Class Virtual Functions -
- Deriving a Python Class -
- Virtual Functions with Default Implementations -
- Class Operators/Special Functions -
- Functions -
- Call Policies -
- Overloading -
- Default Arguments -
- Auto-Overloading -
- Object Interface -
- Basic Interface -
- Derived Object types -
- Extracting C++ objects -
- Enums -
- Embedding -
- Using the interpreter -
- Iterators -
- Exception Translation -
-
-
- - diff --git a/doc/v2/Apr2002.html b/doc/v2/Apr2002.html deleted file mode 100644 index 1f2853c0..00000000 --- a/doc/v2/Apr2002.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - -Boost.Python - April 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

April 2002 Progress Report

-
-
-

Contents

-
-
Accomplishments
-
-
Arbitrary Arity Support
-
New Callback Interface
-
Call Policies for Construtors
-
Real Users, Real Bugs
-
New Insights
-
Boost.Python V1 Maintenance
-
- -
What's Missing
- -
- -

Accomplishments

- -April was a short month as far as Boost.Python was concerned, since -the spring ISO C++ Committee Meeting (and associated vacation) -occupied me for the 2nd half of the month. However, a suprising amount -of work got done... - -

Arbitrary Arity Support

- -I began using the Boost.Preprocessor -metaprogramming library to generate support for functions and member -functions of arbitrary arity, which was, to say the least, quite an -adventure. The feedback cycle resulting from my foray into -Boost.Preprocessor resulted in several improvements to the library, -most notably in its documentation. - -

- -Boost.Python now supports calls of up to 17 arguments on most -compilers. Because most EDG-based compilers have dismal preprocessor -performance, I had to "manually" expand the metaprograms for -arities from zero to fifteen arguments, and EDG-based compilers with -__EDG_VERSION__ <= 245 only support 15 -arguments by default. If some crazy program finds a need for more than -the default arity support, users can increase the base support by -setting the BOOST_PYTHON_MAX_ARITY preprocessor symbol. - -

New Callback Interface

- -I mentioned in last month's report that I -wasn't pleased with the interface for the interface for calling into -Python, so now it has been redesigned. The new interface is outlined -in this -message (though the GCC 2.95.3 bugs have been fixed). - -

Call Policies for Constructors

- -On April 2nd, I announced -support for the use of call policies with constructors. - -

Real Users, Real Bugs

- -At least two people outside of Kull began actually using Boost.Python -v2 in earnest this month. Peter Bienstman and Pearu Pearson both -provided valuable real-world bug reports that helped me to improve the -library's robustness. - -

New Insights

- -Answering some of Pearu's questions about explicitly converting -objects between Python and C++ actually led me to a new understanding -of the role of the current conversion facilities. In Boost.Python v1, -all conversions between Python and C++ were handled by a single family -of functions, called to_python() and -from_python(). Since the primary role of Boost.Python is -to wrap C++ functions in Python, I used these names for the first kind -of converters I needed: those that extract C++ objects to be used as -function arguments and which C++ function return values to -Python. The better-considered approach in Boost.Python v2 uses a -completely different mechanism for conversions used when calling -Python from C++, as in wrapped virtual function implementations. I -usually think of this as a "callback", as in "calling -back into Python", and I named the converters used in callbacks -accordingly: to_python_callback and -from_python_callback. However, as it turns out, the -behavior of the "callback" converters is the appropriate one -for users who want to explicitly extract a C++ value from a Python -object, or create a Python object from a C++ value. The upshot is that -it probably makes sense to change the name of the existing to_python and -from_python so those names are available for the -user-friendly explicit converters. - -

-Another -of Pearu's questions pushes momentum further in the direction of a -more-sophisticated overloading mechanism than the current -simple-minded "first match" approach, as I suggested last month. - -

Boost.Python V1 Maintenance

- -As much as I'm looking forward to retiring Boost.Python v1, a -significant amount of effort has been being spent dealing with support -problems; the saying that code rots when left alone is true, and -Boost.Python is no exception. Eventually it became obvious to me that -we were going to have to invest some effort in keeping V1 healthy -while working on V2. Ralf and I have expanded support for various -compilers and stabilized the V1 codebase considerably. We discarded -the obsolete Visual Studio projects which were causing so much -confusion. Still to do before the next Boost release: -
    -
  1. Update the build/test documentation with detailed instructions for -configuring various toolsets. -
  2. Provide some links to Boost.Python v2 to let people know what's -coming. -
- - -

What's Missing

- -Last month I announced that I would implement the following which are -not yet complete: -
    -
  1. Document all implemented features -
  2. Implement conversions for char types. This is -implemented but not tested, so we have to assume it doesn't work. -
- -These are my first priority for this month (especially the -documentation). - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/CallPolicies.html b/doc/v2/CallPolicies.html deleted file mode 100644 index 09877c5d..00000000 --- a/doc/v2/CallPolicies.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - Boost.Python - CallPolicies Concept - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

CallPolicies Concept

-
-
- -
-
Introduction
- -
CallPolicies Composition
- -
Concept Requirements
- -
-
-
CallPolicies Concept
-
-
-
- -

Introduction

- -

Models of the CallPolicies concept are used to specialize the behavior - of Python callable objects generated by Boost.Python to wrapped C++ - objects like function and member function pointers, providing three - behaviors:

- -
    -
  1. precall - Python argument tuple management before the - wrapped object is invoked
  2. - -
  3. result_converter - C++ return value handling
  4. - -
  5. postcall - Python argument tuple and result management - after the wrapped object is invoked
  6. -
- -

CallPolicies Composition

- In order to allow the use of multiple models of CallPolicies in the same - callable object, Boost.Python's CallPolicies class templates provide a - chaining interface which allows them to be recursively composed. This - interface takes the form of an optional template parameter, - Base which defaults to default_call_policies. - By convention, the precall function of the Base - is invoked after the precall function supplied by the - outer template, and the postcall function of the - Base is invoked before the postcall - function of the outer template. If a result_converter is - supplied by the outer template, it replaces any - result_converter supplied by the Base. For an - example, see return_internal_reference. - - -

Concept Requirements

- -

CallPolicies Concept

- -

In the table below, x denotes an object whose type - P is a model of CallPolicies, a - denotes a PyObject* pointing to a Python argument tuple - object, and r denotes a PyObject* - referring to a "preliminary" result object.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ExpressionTypeResult/Semantics
x.precall(a)convertible to boolreturns false and PyErr_Occurred() != 0 - upon failure, true otherwise.
P::result_converterA model of ResultConverterGenerator.An MPL unary Metafunction - Class used produce the "preliminary" result object.
x.postcall(a, r)convertible to PyObject*0 0 and PyErr_Occurred() != 0 - upon failure. Must "conserve references" even in the event of an - exception. In other words, if r is not returned, its - reference count must be decremented; if another existing object is - returned, its reference count must be incremented.
- Models of CallPolicies are required to be CopyConstructible. -
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- -

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

- - - diff --git a/doc/v2/Dereferenceable.html b/doc/v2/Dereferenceable.html deleted file mode 100644 index fdea0fc0..00000000 --- a/doc/v2/Dereferenceable.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -Boost.Python - Dereferenceable Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

Dereferenceable Concept

-
-
-
-
Introduction
-
Concept Requirements
-
-
Dereferenceable Concept
-
-
- -

Introduction

- -

Instances of a dereferenceable type can be used like a pointer to access an lvalue. - -

Concept Requirements

-

Dereferenceable Concept

- -

In the table below, x denotes an object whose -type is a model of Dereferenceable. - - - - - - - - - - - -
ExpressionRequirements
*xAn lvalue -
- -If x is not a pointer type, it also must satsify the following expression: - - - - - - - - - - - -
ExpressionOperational Semantics
x.get()&*x, or a null pointer -
- -


-

Revised - - 29 November, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/Extractor.html b/doc/v2/Extractor.html deleted file mode 100755 index c28f5f58..00000000 --- a/doc/v2/Extractor.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - -Boost.Python - Extractor Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

Extractor Concept

-
-


-
-
Introduction
-
Concept Requirements
-
-
Extractor Concept
-
-
Notes
-
- -

Introduction

- -

An Extractor is a class which Boost.Python can use to extract C++ -objects from Python objects, and is typically used by facilities that -define from_python conversions for -"traditional" Python extension types. - -

Concept Requirements

-

Extractor Concept

- -

In the table below, X denotes a model of -Extractor and a denotes an instance of a Python -object type. - - - - - - - - - - - - - - - - - - -
ExpressionTypeSemantics
X::execute(a)non-void - Returns the C++ object being extracted. The - execute function must not be overloaded. -
&a.ob_type - PyTypeObject** - Points to the ob_type field of an object which is - layout-compatible with PyObject -
- -

Notes

- -Informally, an Extractor's execute member must be a -non-overloaded static function whose single argument is a Python -object type. Acceptable Python object types include those publicly (and -unambiguously) derived from PyObject, and POD types which -are layout-compatible with PyObject. - -
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/HolderGenerator.html b/doc/v2/HolderGenerator.html deleted file mode 100755 index 34634798..00000000 --- a/doc/v2/HolderGenerator.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - -Boost.Python - Holder Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

HolderGenerator Concept

-
-


-
-
Introduction
-
Concept Requirements
-
-
HolderGenerator Concept
-
-
- -

Introduction

- -

A HolderGenerator is a unary metafunction class which returns types -suitable for holding instances of its argument in a wrapped C++ class -instance. - -

Concept Requirements

-

HolderGenerator Concept

- -

In the table below, G denotes an type which -models HolderGenerator, and X denotes a class -type. - - - - - - - - - - - -
ExpressionRequirements
G::apply<X>::typeA concrete subclass of instance_holder - which can hold objects of type X. -
- -


-

Revised - - 13 November, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/Jun2002.html b/doc/v2/Jun2002.html deleted file mode 100644 index 9c396ed7..00000000 --- a/doc/v2/Jun2002.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - -Boost.Python - June 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

June 2002 Progress Report

-
-


-

Contents

-
-
Introduction
-
handle<T>
-
object
-
-
object operators
-
object conversions
-
-
list
-
Numerics
-
Community
-
What's Next
-
- -

Introduction

- -July was mostly focused on allowing expressive manipulation of -individual Python objects, or what Ralf Grosse-Kunstleve calls -"Writing Python in C++". The work began with this posting, -which outlines the issues and intention. - -

handle<T>

- -The most basic element needed was a replacement for the -reference<> class template and the -ref typedef from Boost.Python v1, a simple smart -pointer to a Python object. The old v1 typedef -"ref" (for -reference<PyObject>) had to be retired because I -thought it would be too confusing given the importance of boost::ref() to this -library. I began a discussionof -possible names, and it was eventually decided -to rename reference to handle and supply a -default argument so that ref could be spelled -handle<> without an additional typedef. There -were also some interface changes to make it safer and more-efficient -to interface with the raw -PyObject*s forced on us by Python's 'C' API. A -discussion of those protocols can be found here. - -

object

- -It is intended that users will seldom need or want to work with -handle<>; its major distinguishing features are -that it gives direct access to the underlying object representation -through operator* and operator->, and -that can be NULL, both sources of danger. Instead the -library provides a class called object, which -encapsulates a valid Python object and provides a similar interface to -Python's. - -

object operators

- -The first challenge was to provide support for object manipulations -using a Python-like syntax, mostly in the form of operator overloads: - - - - - - - - - - - - - -
Python C++ - -
y = x.foo y = x.attr("foo"); -
x.foo = 1 x.attr("foo") = 1; - -
y = x[z] y = x[z]; -
x[z] = 1 x[z] = 1; - -
y = x[3:-1] y = x.slice(3,-1); - -
y = x[3:] y = x.slice(3,_); - -
y = x[:-2] y = x.slice(_,-2); - -
z = x(1, y) z = x(1, y); -
z = x.f(1, y) z = x.attr("f")(1, y); - -
not x !x - -
x and y x and y -
- -I'm still a unsatisfied with the interface for attribute access. There -original proposal used a syntax like this one: -
-y = x._("foo"); 
-x._("foo") = 1; 
-
- -which was only marginally better than what we've got. Niki Spahiev -then pointed -out a potential conflict with the macro which GNU Gettext suggests -people define. This unfortunate state of affairs forced us into using -attr instead. I'd still like to find a better interface, -but the lack of overloadable C++ operators which aren't already used -in Python is an obstacle. The comma operator is still a possibility, -but it has the wrong precedence: -
-y = x,"foo"    // error
-x,"foo" = 1;   // error
-
-y = (x,"foo"); // ok
-(x,"foo") = 1; // ok
-
- -Well, I guess we could consider adding that to the interface without -removing attr(), to see how it plays out... - -

object conversions

- -The object class also provided an opportunity to replace -Boost.Python v1's to_python() as a user-level -interface. Instead, object has a templated constructor -which can be used to convert any C++ object to Python using the same -underlying mechanisms used for the arguments to call<>. - -

Incidentally, the implementation of operator and conversion support -for object uncovered an inordinate number of compiler bugs in our -targeted platforms. It was a lot more "interesting" than it -should have been. - -

list

- -With object implemented, it was time to begin replacing -the ad-hoc implementations of list, string, -and dictionary supplied by Boost.Python v1 with something -more robust. I started with list as an example. Because -object already provides all of the requisite operators, -publicly deriving list from object seemed like a good -choice. The remaining issues were what do do about the one-argument -list constructor (which in Python attempts to convert its argument to -a list), and how to deal converting with list arguments -to wrapped functions. Some of the issues are laid out in this -thread. Ultimately, it was decided that list(x) -should do the same thing in C++ as in Python (conversion), while -list arguments should only match Python -lists (and list subclasses). The -implementation worked well, and provided a roadmap -for the protocol to be used for implementation of the other built-in -types. - -

Numerics

- -Support for C++ long long and unsigned long -long -(and __int64 on MSVC) to/from python conversions was -added this month. We also improved handling of numeric overflows when -converting, e.g., a Python int to a type with a more limited range of -representation. - -

Community

- - - -Deep thanks to all the Boost.Python contributors! This project -wouldn't be possible without your participation. - -

What's Next

- -As I write this we are already well into the month of July, so I -suggest you consult the Mailing -List Archive if you want to know what's been happening. Otherwise -you'll just have to wait till next month (hopefully the beginning). - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/Mar2002.html b/doc/v2/Mar2002.html deleted file mode 100644 index a8a165d8..00000000 --- a/doc/v2/Mar2002.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - -Boost.Python - March 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

March 2002 Progress Report

-
-
-

Contents

-
-
Accomplishments
-
-
Calling Python from C++
-
Virtual Functions
-
Abstract Classes
-
C++ Implicit Conversions
-
C++ Data Members
-
Miscellaneous
-
- -
The Near future
- -
Notes
- -
- -

Accomplishments

- -March was mostly devoted to the reimplementation of features from -Boost.Python v1, and some new features. Re-examination of the features -from Boost.Python v1 allowed me to make significant improvements. - -

Calling Python from C++

- -The ability to call Python from C++ is crucial for virtual function -support. Implementing this feature well for V2 proved to be more -interesting than I expected. You can review most of the relevant -design decisions -here. - -

-One point which isn't emphasized in that document is that there -are subtle differences in the way from_python conversions -work when used for C++ function arguments and Python function return -values. In particular, while T const& arguments may -invoke rvalue converters, a reference-to-const return value requires -an lvalue converter, since a temporary conversion result would leave -the returned reference dangling. - -

I'm not particularly pleased with the current callback interface, -since it usually results in constructs like: -

-return returning<X&>::call(f, obj);
-
-However, I think the following may be possible and I plan to investigate: -
-return apply<X&>(f, obj);
-
-I'm open to suggestion for better names (and syntaxes)! - -

Virtual Functions

- -Once Python callbacks were implemented, it was just a short step to -implementing virtual functions. Python extension class exposing a C++ -class whose virtual functions are overridable in Python must actually -hold a C++ instance of a class derived from the one exposed to -Python. Needing some way for users to specify that class, I added an -optional template argument to value_holder_generator and -pointer_holder_generator<> to specify the class -actually held. This move began to put pressure on the -class_<> interface, since the need for the user to -produce complicated instantations of -class_<> was increased: - -
-class<Foo, bases<>, value_holder_generator<Foo_callback> >("Foo")
-.def("hello", &Foo::hello)
-...
-
- -

Abstract Classes

- -Normally when a C++ class is exposed to Python, the library registers -a conversion function which allows users to wrap functions returning -values of that type. Naturally, these return values are temporaries, -so the conversion function must make a copy in some -dynamically-allocated storage (a "holder") which is managed -by the corresponding Python object. - -

Unfortunately, in the case of abstract classes (and other types -without a publicly-accessible copy constructor), instantiating this -conversion function causes a compilation error. In order to support -non-copyable classes, there had to be some way to prevent the library -from trying to instantiate the conversion function. The only practical -approach I could think of was to add an additional template parameter -to the class_<> interface. When the number of -template parameters with useful defaults begins to grow, it is often -hard to choose an order which allows users to take advantage of the -defaults. - -

- -This was the straw that broke the -class_<> interface's back and caused the redesign -whose outcome is detailed here. -The approach allows the user to supply the optional parameters in an -arbitrary order. It was inspired by the use of named -template parameters in the Boost Iterator Adaptor -Library, though in this case it is possible to deduce the meaning -of the template parameters entirely from their type properties, -resulting in a simpler interface. Although the move from a -policy-based design to what resembles a configuration DSL usually -implies a loss of flexibility, in this case I think any costs are far -outweighed by the advantages. - -

Note: working around the limitations of the various compilers I'm -supporting was non-trivial, and resulted in a few messy implementation -details. It might be a good idea to switch to a more-straightforward -approach once Metrowerks CodeWarrior Pro8 is released. - -

C++ Implicit Conversions

- -Support for C++ implicit conversion involves creating -from_python converters for a type U which in -turn use from_python converters registered for a type -T where there exists a implicit conversion from -T to U. The current implementation is -subject to two inefficiencies: -
    - -
  1. Because an rvalue from_python converter produces two -pieces of data (a function and a void*) from its -convertible() function, we end up calling the function -for T twice: once when the converter is looked up in the -registry, and again when the conversion is actually performed. - -
  2. A vector is used to mark the "visited" converters, preventing -infinite recursion as T to -U and U to T converters -continually search through one-another. - -
- -I consider the former to be a minor issue. The second may or may not -prove to be computationally significant, but I believe that -architecturally, it points toward a need for more sophisticated -overload resolution. It may be that we want CLOS-style multimethod -dispatching along with C++ style rules that prevent more than one -implicit conversion per argument. - -

C++ Data Members

- -To supply the ability to directly access data members, I was able to -hijack the new Python property -type. I had hoped that I would also be able to re-use the work of make_function to create callable python -objects from C++ functions which access a data member of a given -class. C++ facilities for specifying data member pointer non-type -template arguments require the user to explicitly specify the type of -the data member and this under-utilized feature is also not -well-implemented on all compilers, so passing the member pointer as a -runtime value is the only practical approach. The upshot is that any -such entity would actually have to be a function object, and I -haven't implemented automatic wrapping of C++ callable function -objects yet, so there is less re-use in the implementation than I'd -like. I hope to implement callable object wrapping and refactor this -code one day. I also hope to implement static data member support, -for which Python's property will not be an appropriate descriptor. - -

Miscellaneous

-
    -
  • Moved args<> and bases<> from unnamed namespace to boost::python in their own header files. -
  • Convert NULL pointers returned from wrapped C++ functions to None. -
  • Improved some compile-time error checks. -
  • Eliminated boost/python/detail/eval.hpp in favor of -more-general boost/mpl/apply.hpp. -
  • General code cleanup and refactoring. -
  • Works with Microsoft Visual C++ 7.0 -
  • Warning suppression for many compilers -
  • Elegant interface design for exporting enum types. -
-
- -

The Near Future

- -Before April 15th I plan to -
    -
  1. Document all implemented features -
  2. Implement a CallPolicy interface for constructors of wrapped -classes -
  3. Implement conversions for char types. -
  4. Implement automated code generation for all headers containing -families of overloaded functions to handle arbitrary arity. -
- -I also hope to implement a mechanism for generating conversions -between arbitrary Python sequences and C++ containers, if time permits -(and others haven't already done it)! - -

Notes

- -The older version of KCC used by Kull is generating lots of warnings -about a construct I use to instantiate static members of various class -templates. I'm thinking of moving to an idiom which uses a function -template to suppress it, but worry about bloating the size of debug -builds. Since KCC users may be moving to GCC, I'm not sure that it's -worth doing anything about it. - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/May2002.html b/doc/v2/May2002.html deleted file mode 100644 index b5eb4e4f..00000000 --- a/doc/v2/May2002.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - -Boost.Python - May 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

May 2002 Progress Report

-
-
-

Contents

-
-
Introduction
-
New Features
-
-
Shared Library Support for AIX
-
Class Enhancements
-
-
Operators
-
Iterators
-
Properties
-
setattr
-
__module__ Attribute
-
-
back_reference
-
- -
Documentation
-
Miscellaneous
-
-
Converters
-
Checkins Mailing List
-
Shared Libraries
-
- -
What's Next
-
- -

Introduction

- -Aside from library development, work on Boost.Python in May was -focused on reducing the support burden. In recent weeks, responding to -requests for support, espcially surrounding building the library, had -begun to impede progress on development. There was a major push to -release a stable 1.28.0 of Boost, including documentation of Boost.Build and specific -instructions for building Boost.Python -v1. The documentation for Boost.Python v2 was also updated as -described here. - -

New Features

- -

Shared Library Support for AIX

- - The Kull group required the ability to build and test Boost.Python - extensions on AIX, a platform with "creatively designed" - shared library semantics. Making this work was a multi-pronged - effort, involving changes to Boost.Build and some great research by - Martin Casado which uncovered the key mechanism required to allow - shared libraries to use functions from the Python executable. The - current solution used in Boost.Build relies on a Python - Script as part of the build process. This is not a problem for - Boost.Python, as Python will be available. However, the commands - issued by the script are so simple that a 100%-pure-Boost.Jam - solution is surely possible. Linking on AIX is sufficiently - interesting to have skewed the Boost.Python development schedule a - bit. - -

Class Enhancements

- -

Operators

- -Support for exposing C++ operators and functions as the corresponding -Python special methods was added. Thinking that the Boost.Python -v1 interface was a little too -esoteric (especially the use of -left_operand<...>/right_operand<...> for -asymmetric operands), I introduced a simple form of expression -templates which allow users to simply write the expressions that -should be wrapped, as in this example. - -

Iterators

- -Python iterator support as required by the Kull project resulted in a -highly flexible interface allowing: - -
- -
Direct exposure of a class' begin() and -end() functions: - -
-    ...
-    .def("__iter__", iterator<list_int>())
-
-
- -
Creation of iterators from member functions... -
-    ...
-    .def("__iter__"
-         , range(&my_class::x_begin, &my_class::x_end))
-    )
-
-
- -
...and member data: -
-    ...
-    .def("__iter__"
-         , range(&std::pair<char*,char*>::first, &std::pair<char*,char*>::second))
-    )
-
-
- -
The ability to specify CallPolicies, e.g. to prevent copying of -heavyweight values: - -
-    ...
-    .def("__iter__", 
-         , range<return_value_policy<copy_non_const_reference> >(
-               &my_sequence<heavy>::begin
-             , &my_sequence<heavy>::end))
-
-
- -
- -

Properties

- -The Kull iteration interfaces also required the ability to iterate -over a sequence specified by an instance's attribute: -
->>> f = field()
->>> for e in f.elements:
-...     print e,
-
- -This forced the exposure of the property - interface used internally to implement the data member exposure - facility described in March. Properties are an - incredibly useful idiom, so it's good to be able to provide them - at little new development cost. - -

setattr

- -class_<> acquired a setattr member -function which allows users to easily add new Python objects as class -attributes. - -

__module__ Attribute

- -Ralf Grosse-Kunstleve has been working on pickling support for v2. To -make it work correctly, he had to make sure that a class' -__module__ attribute was set correctly. - -

back_reference

- -The new back_reference<T> template can be used as a -function parameter when the user needs access to both a T -argument and to the Python object which manages it. The function will -only match in the overload resolution process if it would match the -same function signature with T substituted for -back_reference<T>. This feature is not yet -documented. - -

Documentation

- -In a major effort to prepare Boost.Python v2 to replace v1, many pages -of new reference documentation were added: - -
- -
-
CallPolicies.html
-
Dereferenceable.html
-
Extractor.html
-
HolderGenerator.html
-
ResultConverter.html
-
call_method.html
-
callbacks.html
-
data_members.html
-
has_back_reference.html
-
implicit.html
-
instance_holder.html
-
operators.html
-
ptr.html
-
type_id.html
-
with_custodian_and_ward.html
-
- -
-Major updates were made to the following pages: - - -
-
-
call.html
updated
-
class.html
-
reference.html
-
-
- - As usual, careful documentation forces one to consider the - interface again, and there were many interface changes - associated with this effort, including the elevation of the - following components from implementation detail to - first-class library citizen: - -
-
-
type_id.hpp
-
pointee.hpp
-
lvalue_from_pytype.hpp
- -
- -

Miscellaneous

- -

Converters

- -It appears that the world of C++ <==> Python conversion rules is -an endlessly-rich area of exploration. Completing the conversions for -char and char const* types, as described at -the end of April's report, -uncovered some interesting new shades to the problem. It turns out to -be worth distinguishing mutable and immutable lvalue conversions, -because despite the fact that Python doesn't understand -const, it does understand immutability (c.f. Python -strings, which expose an immutable char pointer). It is -also worth recognizing types which represent lvalue sequences, -to prevent Python "foobar" from being silently -truncated to C++ 'f'. More details on this insight can be -found in the mailing list -archive. I don't plan to do anything about this immediately, but I -do think it's the right direction to go in the long run. - -

Checkins Mailing List

- -In order to better coordinate changes made by multiple developers, I -enabled syncmail -for the Boost.Python CVS trees, and established an associated mailing -list. Subscribe to this list to receive notices of each new -checkin. - -

Shared Libraries

- -Beyond the vagaries of dynamic linking on AIX, I have been -participating in a more-general discussion of dynamic linking for -C++. Needless to say, C++ dynamic linking is of critical importance to -Boost.Python: all extension modules are normally built as shared -libraries, and Boost.Python extension modules share a common library -as well. - -In fact, there are at least two separate conversations. One -in the C++ standard extensions mailing list concerns what can be -standardized for C++ and shared libraries; the other, mostly on the gcc mailing list, concerns the -behavior of GCC on Posix/ELF platforms. - -Some of the GCC threads are here: - -
-http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html
-http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html
-http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html -
- -

What's Next

- -Development is focused on what's needed to be able to retire -Boost.Python v1. At the moment, that means deciding the user-friendly -interfaces for to_/from_python conversion, and formally exposing the -Python object smart pointers and object wrapper classes. Quite a few -questions have also been showing up recently about how to embed Python -with Boost.Python, and how to link with it statically; the solutions -to these issues will probably have to be formalized before long. - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/ObjectWrapper.html b/doc/v2/ObjectWrapper.html deleted file mode 100644 index 82a940e3..00000000 --- a/doc/v2/ObjectWrapper.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - Boost.Python - ObjectWrapper Concept - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

ObjectWrapper and TypeWrapper Concepts

-
-
- -
-
Introduction
- -
Concept Requirements
- -
-
-
ObjectWrapper Concept
- -
TypeWrapper Concept
-
-
- -
Caveat
-
- -

Introduction

- -

This page defines two concepts used to describe classes which manage a - Python objects, and which are intended to support usage with a - Python-like syntax.

- -

Concept Requirements

- -

ObjectWrapper Concept

- Models of the ObjectWrapper concept have object as a publicly-accessible base class, - and are used to supply special construction behavior and/or additional - convenient functionality through (often templated) member functions. - Except when the return type R is itself an TypeWrapper, a member function invocation of - the form -
-x.some_function(a1, a2,...an)
-
- always has semantics equivalent to: -
-extract<R>(x.attr("some_function")(object(a1), object(a2),...object(an)))()
-
- When the R is an TypeWrapper, the result type may be - constructed by taking direct posession of: -
-x.attr("some_function")(object(a1), object(a2),...object(an)).ptr()
-
- [see caveat below] - -

TypeWrapper Concept

- TypeWrapper is a refinement of ObjectWrapper which is associated with a - particular Python type X. For a given TypeWrapper - T, a valid constructor expression -
-T(a1, a2,...an)
-
- builds a new T object managing the result of invoking - X with arguments corresponding to -
-object(a1), object(a2),...object(an)
-
- -When used as arguments to wrapped C++ functions, or as the template -parameter to extract<>, only -instances of the associated Python type will be considered a match. - -

Caveat

- The upshot of the special member function invocation rules when the - return type is a TypeWrapper is that it is possible for the returned - object to manage a Python object of an inappropriate type. This is not - usually a serious problem; the worst-case result is that errors will be - detected at runtime a little later than they might otherwise be. For an - example of how this can occur, note that the dict member function items - returns an object of type list. Now suppose the user defines this - dict subclass in Python: -
->>> class mydict(dict):
-...     def items(self):
-...         return tuple(dict.items(self)) # return a tuple
-
- Since an instance of mydict is also an instance of - dict, when used as an argument to a wrapped C++ function, - boost::python::dict can - accept objects of Python type mydict. Invoking - items() on this object can result in an instance of boost::python::list which actually - holds a Python tuple. Subsequent attempts to use list methods (e.g. - append, or any other mutating operation) on this object will - raise the same exception that would occur if you tried to do it from - Python. -
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- -

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

- - - diff --git a/doc/v2/ResultConverter.html b/doc/v2/ResultConverter.html deleted file mode 100644 index 63187c3a..00000000 --- a/doc/v2/ResultConverter.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - -Boost.Python - ResultConverter Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

ResultConverter Concept

-
-
-
-
Introduction
-
Concept Requirements
-
-
ResultConverter Concept
-
ResultConverterGenerator Concept
-
-
- -

Introduction

- -

A ResultConverter for a type T is a type whose -instances can be used to convert C++ return values of type -T to_python. A ResultConverterGenerator is -an MPL unary metafunction class which, given the return type of a C++ -function, returns a ResultConverter for that type. ResultConverters in -Boost.Python generally inspect library's registry of converters to -find a suitable converter, but converters which don't use the registry -are also possible. - -

Concept Requirements

-

ResultConverter Concept

- -

In the table below, C denotes a ResultConverter -type for a type R , c denotes -an object of type C , and r -denotes an object of type R. - - - - - - - - - - - - - - - - - - - - - - - - -
ExpressionTypeSemantics
C c; - Constructs a C object. -
c.convertible()convertible to boolfalse iff no conversion from any R value - to a Python object is possible.
c(r)convertible to PyObject*A pointer to a Python object corresponding to r, - or 0 iff r could not be converted - to_python, in which case PyErr_Occurred - should return non-zero.
- -

ResultConverterGenerator Concept

-

In the table below, G denotes a -ResultConverterGenerator type and R denotes a possible -C++ function return type. - - - - - - - - - -
ExpressionRequirements
G::apply<R>::typeA ResultConverter type for R.
- -


-

Revised - - 09 May, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/args.html b/doc/v2/args.html deleted file mode 100644 index c2f29269..00000000 --- a/doc/v2/args.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/args.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/args.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
keyword-expressions
- -
Functions
- -
-
-
args(...)
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Supplies a family of overloaded functions for specifying argument - keywords for wrapped C++ functions.

- -

keyword-expressions

- -

A keyword-expression results in an object which holds a - sequence of ntbses, and whose type - encodes the number of keywords specified.

- -

Functions

- -

args(...)

-
-unspecified1 args(char const*);
-unspecified2 args(char const*, char const*);
-   .
-   .
-   .
-unspecifiedN args(char const*, char const*, ... char const*);
-
- -
-
Requires: Every argument must be a ntbs.
- -
Returns: an object representing a keyword-expression encapsulating the - arguments passed.
-
- -

Example

-
-#include <boost/python/def.hpp>
-using namespace boost::python;
-
-int f(int x, int y, int z);
-
-BOOST_PYTHON_MODULE(xxx)
-{
-   def("f", f, args("x", "y", "z"));
-}
-
- -

Revised 05 November, 2001

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/bibliography.html b/doc/v2/bibliography.html deleted file mode 100644 index 7ebd477b..00000000 --- a/doc/v2/bibliography.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -Boost.Python - Bibliography - - - - - - - -
-

-

-
-

Boost.Python

-

Bibliography

-
-
-{{bibliographical information}} -
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/call.html b/doc/v2/call.html deleted file mode 100644 index b5478a4b..00000000 --- a/doc/v2/call.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -Boost.Python - <call.hpp> - - - - - - - -
-

-

-
-

Boost.Python

-

Header <call.hpp>

-
-
-

Contents

-
-
Introduction
-
Functions
-
-
call
-
- -
Example(s)
- -
-
-

Introduction

-

- <boost/python/call.hpp> defines the call family of overloaded function - templates, used to invoke Python callable objects from C++. - -

Functions

-
-template <class R, class A1, class A2, ... class An>
-R call(PyObject* callable, A1 const&, A2 const&, ... An const&)
-
-
-
Requires: R is a pointer type, reference - type, or a complete type with an accessible copy constructor
- -
Effects: Invokes callable(a1, a2, ...an) in - Python, where a1...an are the arguments to - call(), converted to Python objects. -
Returns: The result of the Python call, converted to the C++ type R.
- - -
Rationale: For a complete semantic description and - rationale, see this page. -
-
- -

Example(s)

- -The following C++ function applies a Python callable object to its two -arguments and returns the result. If a Python exception is raised or -the result can't be converted to a double, an exception -is thrown. - -
-double apply2(PyObject* func, double x, double y)
-{
-   return boost::python::call<double>(func, x, y);
-}
-
- -

Revised - - 9 May, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html deleted file mode 100644 index eaa91ec9..00000000 --- a/doc/v2/call_method.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - Boost.Python - <call_method.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <call_method.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
call_method
-
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/call_method.hpp> defines the call_method family of overloaded - function templates, used to invoke callable attributes of Python objects - from C++.

- -

Functions

-
-template <class R, class A1, class A2, ... class An>
-R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... An const&)
-
- -
-
Requires: R is a pointer type, reference type, - or a complete type with an accessible copy constructor
- -
Effects: Invokes - self.method(a1, a2, ...an) in - Python, where a1...an are the - arguments to call_method(), converted to Python objects. - For a complete semantic description, see this - page.
- -
Returns: The result of the Python call, converted to the C++ - type R.
- -
Rationale: call_method is critical to - implementing C++ virtual functions which are overridable in Python, as - shown by the example below.
-
- -

Example(s)

- The following C++ illustrates the use of call_method in - wrapping a class with a virtual function that can be overridden in - Python: - -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/utility.hpp>
-#include <cstring>
-
-// class to be wrapped
-class Base
-{
- public:
-   virtual char const* class_name() const { return "Base"; }
-   virtual ~Base();
-};
-
-bool is_base(Base* b)
-{
-   return !std::strcmp(b->class_name(), "Base");
-}
-
-// Wrapper code begins here
-using namespace boost::python;
-
-// Callback class
-class Base_callback : public Base
-{
- public:
-   Base_callback(PyObject* self) : m_self(self) {}
-
-   char const* class_name() const { return call_method<char const*>(m_self, "class_name"); }
-   char const* Base_name() const { return Base::class_name(); }
- private:
-   PyObject* const m_self;
-};
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    def("is_base", is_base);
-
-    class_<Base,Base_callback, noncopyable>("Base")
-        .def("class_name", &Base_callback::Base_name)
-        ;
-
-}
-
- -

Python Code

-
->>> from my_module import *
->>> class Derived(Base):
-...    def __init__(self):
-...       Base.__init__(self)
-...    def class_name(self):
-...       return self.__class__.__name__
-...
->>> is_base(Base()) # calls the class_name() method from C++
-1
->>> is_base(Derived())
-0
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/callbacks.html b/doc/v2/callbacks.html deleted file mode 100644 index 1d215801..00000000 --- a/doc/v2/callbacks.html +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - - - - Boost.Python - Calling Python Functions and Methods - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Calling Python Functions and Methods

-
-
- -

Contents

- -
-
Introduction
- -
Argument Handling
- -
Result Handling
- -
Rationale
-
-
- -

Introduction

- The simplest way to call a Python function from C++, given an object instance f - holding the function, is simply to invoke its function call operator. -
-f("tea", 4, 2) // In Python: f('tea', 4, 2)
-
- And of course, a method of an object instance x can - be invoked by using the function-call operator of the corresponding - attribute: -
-x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
-
- -

If you don't have an object instance, Boost.Python - provides two families of function templates, call and call_method, for invoking - Python functions and methods respectively on PyObject*s. The - interface for calling a Python function object (or any Python callable - object) looks like:

-
-call<ResultType>(callable_object, a1, a2... aN);
-
- Calling a method of a Python object is similarly easy: -
-call_method<ResultType>(self_object, "method-name", a1, a2... aN);
-
- This comparitively low-level interface is the one you'll use when - implementing C++ virtual functions that can be overridden in Python. - -

Argument Handling

- -

Arguments are converted to Python according to their type. By default, - the arguments a1...aN are copied into - new Python objects, but this behavior can be overridden by the use of - ptr() and ref():

-
-class X : boost::noncopyable
-{
-   ...
-};
-
-void apply(PyObject* callable, X& x)
-{
-   // Invoke callable, passing a Python object which holds a reference to x
-   boost::python::call<void>(callable, boost::ref(x));
-}
-
- In the table below, x denotes the actual argument - object and cv denotes an optional - cv-qualification: "const", "volatile", - or "const volatile". - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Argument TypeBehavior
T cv&
- T cv
The Python argument is created by the same means used for the - return value of a wrapped C++ function returning T. When - T is a class type, that normally means *x - is copy-constructed into the new Python object.
T*If x == 0, the Python argument will be - None. - Otherwise, the Python argument is created by the same means used for - the return value of a wrapped C++ function returning T. - When T is a class type, that normally means - *x is copy-constructed into the new Python object.
boost::reference_wrapper<T>The Python argument contains a pointer to, rather than a copy of, - x.get(). Note: failure to ensure that no Python code - holds a reference to the resulting object beyond the lifetime of - *x.get() may result in a crash!
pointer_wrapper<T>If x.get() == 0, the Python argument will - be None. - Otherwise, the Python argument contains a pointer to, rather than a - copy of, *x.get(). Note: failure to ensure that no - Python code holds a reference to the resulting object beyond the - lifetime of *x.get() may result in a crash!
- -

Result Handling

- In general, call<ResultType>() and - call_method<ResultType>() return - ResultType by exploiting all lvalue and rvalue - from_python converters registered for ResultType and - returning a copy of the result. However, when ResultType is - a pointer or reference type, Boost.Python searches only for lvalue - converters. To prevent dangling pointers and references, an exception - will be thrown if the Python result object has only a single reference - count. - -

Rationale

- In general, to get Python arguments corresponding to - a1...aN, a new Python object must be - created for each one; should the C++ object be copied into that Python - object, or should the Python object simply hold a reference/pointer to - the C++ object? In general, the latter approach is unsafe, since the - called function may store a reference to the Python object somewhere. If - the Python object is used after the C++ object is destroyed, we'll crash - Python. - -

In keeping with the philosophy that users on the Python side shouldn't - have to worry about crashing the interpreter, the default behavior is to - copy the C++ object, and to allow a non-copying behavior only if the user - writes boost::ref(a1) - instead of a1 directly. At least this way, the user doesn't get dangerous - behavior "by accident". It's also worth noting that the non-copying - ("by-reference") behavior is in general only available for class types, - and will fail at runtime with a Python exception if used otherwise[1].

- -

However, pointer types present a problem: one approach is to refuse to - compile if any aN has pointer type: after all, a user can always pass - *aN to pass "by-value" or ref(*aN) to indicate - a pass-by-reference behavior. However, this creates a problem for the - expected null pointer to None conversion: it's illegal to - dereference a null pointer value.

- -

The compromise I've settled on is this:

- -
    -
  1. The default behavior is pass-by-value. If you pass a non-null - pointer, the pointee is copied into a new Python object; otherwise the - corresponding Python argument will be None.
  2. - -
  3. if you want by-reference behavior, use ptr(aN) if - aN is a pointer and ref(aN) otherwise. If a - null pointer is passed to ptr(aN), the corresponding - Python argument will be None.
  4. -
- -

As for results, we have a similar problem: if ResultType - is allowed to be a pointer or reference type, the lifetime of the object - it refers to is probably being managed by a Python object. When that - Python object is destroyed, our pointer dangles. The problem is - particularly bad when the ResultType is char const* - the - corresponding Python String object is typically uniquely-referenced, - meaning that the pointer dangles as soon as call<char - const*>(...) returns.

- -

The old Boost.Python v1 deals with this issue by refusing to compile - any uses of call<char const*>(), but this goes both - too far and not far enough. It goes too far because there are cases where - the owning Python string object survives beyond the call (just for - instance, when it's the name of a Python class), and it goes not far - enough because we might just as well have the same problem with a - returned pointer or reference of any other type.

- -

In Boost.Python v2 this is dealt with by:

- -
    -
  1. lifting the compile-time restriction on const char* callback - returns
  2. - -
  3. detecting the case when the reference count on the result Python - object is 1 and throwing an exception inside of - call<U>(...) when U is a pointer or - reference type.
  4. -
- This should be acceptably safe because users have to explicitly specify a - pointer/reference for U in call<U>, and - they will be protected against dangles at runtime, at least long enough - to get out of the call<U>(...) invocation. -
- [1] It would be possible to make it fail at compile-time - for non-class types such as int and char, but I'm not sure it's a good - idea to impose this restriction yet. - -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/callbacks.txt b/doc/v2/callbacks.txt deleted file mode 100644 index a58ca0ea..00000000 --- a/doc/v2/callbacks.txt +++ /dev/null @@ -1,88 +0,0 @@ -Here's the plan: - -I aim to provide an interface similar to that of Boost.Python v1's -callback<>::call(...) for dealing with callbacks. The interface will -look like: - - returning::call("method_name", self_object, a1, a2...); - -or - - returning::call(callable_object, a1, a2...); - -ARGUMENT HANDLING - -There is an issue concerning how to make Python objects from the -arguments a1...aN. A new Python object must be created; should the C++ -object be copied into that Python object, or should the Python object -simply hold a reference/pointer to the C++ object? In general, the -latter approach is unsafe, since the called function may store a -reference to the Python object somewhere. If the Python object is used -after the C++ object is destroyed, we'll crash Python. - -I plan to make the copying behavior the default, and to allow a -non-copying behavior if the user writes boost::ref(a1) instead of a1 -directly. At least this way, the user doesn't get dangerous behavior "by -accident". It's also worth noting that the non-copying ("by-reference") -behavior is in general only available for class types, and will fail at -runtime with a Python exception if used otherwise** - -However, pointer types present a problem: My first thought is to refuse -to compile if any aN has pointer type: after all, a user can always pass -*aN to pass "by-value" or ref(*aN) to indicate a pass-by-reference -behavior. However, this creates a problem for the expected NULL pointer -=> None conversion: it's illegal to dereference a null pointer value. - -We could use another construct, say "ptr(aN)", to deal with null -pointers, but then what does it mean? We know what it does when aN is -NULL, but it might either have by-value or by-reference behavior when aN -is non-null. - -The compromise I've settled on is this: - -1. The default behavior is pass-by-value. If you pass a non-null - pointer, the pointee is copied into a new Python object; otherwise - the corresponding Python argument will be None. - -2. if you want by-reference behavior, use ptr(aN) if aN is a pointer - and ref(aN) otherwise. If a null pointer is passed to ptr(aN), the - corresponding Python argument will be None. - -RESULT HANDLING - -As for results, we have a similar problem: if ResultType is allowed to -be a pointer or reference type, the lifetime of the object it refers to -is probably being managed by a Python object. When that Python object is -destroyed, our pointer dangles. The problem is particularly bad when the -ResultType is char const* - the corresponding Python String object is -typically uniquely-referenced, meaning that the pointer dangles as soon -as returning::call() returns. - -Boost.Python v1 deals with this issue by refusing to compile any uses of -callback::call(), but IMO this goes both too far and not -far enough. It goes too far because there are cases where the owning -String object survives beyond the call (just for instance when it's the -name of a Python class), and it goes not far enough because we might -just as well have the same problem with any returned pointer or -reference. - -I propose to address this in Boost.Python v2 by - - 1. lifting the compile-time restriction on const - char* callback returns - - 2. detecting the case when the reference count on the - result Python object is 1 and throwing an exception - inside of returning::call() when U is a pointer or - reference type. - -I think this is acceptably safe because users have to explicitly specify -a pointer/reference for U in returning, and they will be protected -against dangles at runtime, at least long enough to get out of the -returning::call() invocation. - --Dave - -**It would be possible to make it fail at compile-time for non-class -types such as int and char, but I'm not sure it's a good idea to impose -this restriction yet. diff --git a/doc/v2/class.html b/doc/v2/class.html deleted file mode 100644 index 85eda64e..00000000 --- a/doc/v2/class.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/class.hpp>, - <boost/python/class_fwd.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Headers <boost/python/class.hpp>, - <boost/python/class_fwd.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - class_
- -
-
-
Class class_ - synopsis
- -
Class class_ - constructors
- -
Class class_ - modifier functions
-
-
- -
Class template - bases
- -
-
-
Class template - bases synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/class.hpp> defines the interface - through which users expose their C++ classes to Python. It declares the - class_ class template, which is parameterized on the class - type being exposed. It also exposes the init, - optional and bases utility class templates, - which are used in conjunction with class_.

- -

<boost/python/class_fwd.hpp> contains a forward - declaration of the class_ class template.

- -

Classes

- -

Class template - class_<T, Bases, HeldType, - NonCopyable>

- -

Creates a Python class associated with the C++ type passed as its - first parameter. Although it has four template parameters, only the first - one is required. The three optional arguments can actually be supplied - in any order; Boost.Python determines - the role of the argument from its type.
-
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Template ParameterRequirementsSemanticsDefault
TA class type.The class being wrapped
BasesA specialization of bases<...> which - specifies previously-exposed C++ base classes of T[1].Registers from_python conversions from wrapped - T instances to each of its exposed direct and indirect - bases. For each polymorphic base B, registers - conversions from indirectly-held wrapped B instances to - T.bases<>
HeldTypeMust be T, a class derived from T, or a - Dereferenceable type for which - pointee<HeldType>::type - is T or a class derived from T.Specifies the type which is actually embedded in a Python object - wrapping a T instance. More details below.T
NonCopyableIf supplied, must be boost::noncopyable.Suppresses automatic registration of to_python - conversions which copy T instances. Required when - T has no publicly-accessible copy constructor.An unspecified type other than - boost::noncopyable.
- -

HeldType Semantics

- -
    -
  1. If HeldType is derived from T, its exposed - constructor(s) must accept an initial PyObject* argument - which refers back to the Python object that contains the - HeldType instance, as shown in this example. This argument is not - included in the init-expression passed to def(init_expr), below, - nor is it passed explicitly by users when Python instances of - T are created. This idiom allows C++ virtual functions - which will be overridden in Python to access the Python object so the - Python method can be invoked. Boost.Python automatically registers - additional converters which allow wrapped instances of T - to be passed to wrapped C++ functions expecting HeldType - arguments.
  2. - -
  3. Because Boost.Python will always allow wrapped instances of - T to be passed in place of HeldType - arguments, specifying a smart pointer for HeldType allows - users to pass Python T instances where a smart - pointer-to-T is expected. Smart pointers such as - std::auto_ptr<> or boost::shared_ptr<> - which contain a nested type element_type designating the - referent type are automatically supported; additional smart pointer - types can be supported by specializing pointee<HeldType>.
  4. - -
  5. As in case 1 above, when HeldType is a smart pointer - to a class derived from T, the initial - PyObject* argument must be supplied by all of - HeldType's exposed constructors.
  6. - -
  7. Except in cases 1 and 3, users may optionally specify that T itself - gets initialized with a similar initial PyObject* argument - by specializing has_back_reference<T>.
  8. -
- -

Class template class_ - synopsis

-
-namespace boost { namespace python
-{
-  template <class T
-        , class Bases = bases<>
-            , class HeldType = T
-            , class NonCopyable = unspecified
-           >
-  class class_ : public object
-  {
-    // Constructors with default __init__
-    class_(char const* name);
-    class_(char const* name, char const* docstring);
-
-    // Constructors, specifying non-default __init__
-    template <class Init>
-    class_(char const* name, Init);
-    template <class Init>
-    class_(char const* name, char const* docstring, Init);
-
-    // Exposing additional __init__ functions
-    template <class Init>
-    class_& def(Init);
-
-    // defining methods
-    template <class F>
-    class_& def(char const* name, F f);
-    template <class Fn, class A1>
-    class_& def(char const* name, Fn fn, A1 const&);
-    template <class Fn, class A1, class A2>
-    class_& def(char const* name, Fn fn, A1 const&, A2 const&);
-    template <class Fn, class A1, class A2, class A3>
-    class_& def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
-
-    // declaring method as static
-    class_& staticmethod(char const* name);
-    
-    // exposing operators
-    template <unspecified>
-    class_& def(detail::operator_<unspecified>);
-
-    // Raw attribute modification
-    template <class U>
-    class_& setattr(char const* name, U const&);
-
-    // exposing data members
-    template <class D>
-    class_& def_readonly(char const* name, D T::*pm);
-
-    template <class D>
-    class_& def_readwrite(char const* name, D T::*pm);
-
-    // property creation
-    template <class Get>
-    void add_property(char const* name, Get const& fget);
-    template <class Get, class Set>
-    void add_property(char const* name, Get const& fget, Set const& fset);
-
-    // pickle support
-    template <typename PickleSuite>
-    self& def_pickle(PickleSuite const&);
-  };
-}}
-
- -

Class template class_ - constructors

-
-class_(char const* name);
-class_(char const* name, char const* docstring);
-template <class Init>
-class_(char const* name, Init init_spec);
-template <class Init>
-class_(char const* name, char const* docstring, Init init_spec);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules. If docstring is supplied, it must be an - ntbs. If init_spec is - supplied, it must be either the special enumeration constant - no_init or an init-expression compatible with - T.
- -
Effects: Constructs a class_ object holding a - Boost.Python extension class named name. The - named attribute of the current scope is bound to the new - extension class.
- -
-
    -
  • If supplied, the value of docstring is bound to - the __doc__ attribute of the extension class.
  • - -
  • If init_spec is no_init, a special - __init__ function is generated which always raises a - Python exception. Otherwise, this->def(init_spec) - is called.
  • - -
  • If init_spec is not supplied, - this->def(init<>()) is called.
  • -
-
- -
Rationale:Allowing the user to specify constructor arguments - in the class_<> constructor helps her to avoid the - common run-time errors which result from invoking wrapped member - functions without having exposed an __init__ function - which creates the requisite T instance. Types which are - not default-constructible will cause a compile-time error unless - Init is supplied. The user must always supply - name as there is currently no portable method to derive - the text of the class name from its type.
-
- -

Class template - class_ modifier functions

-
-template <class Init>
-class_& def(Init init_expr);
-
- -
-
Requires: init_expr is the result of an init-expression compatible with - T.
- -
Effects: For each valid - prefix P of Init, adds an - __init__(...) function overload to the - extension class accepting P as arguments. Each overload - generated constructs an object of HeldType according to - the semantics described above, using a copy of - init_expr's call policies. - If the longest valid prefix of - Init contains N types and init_expr - holds M keywords, an initial sequence of the keywords are used - for all but the first N - M arguments of - each overload.
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' - constructor to Python.
-
-
- -
-template <class F>
-class_& def(char const* name, Fn fn);
-template <class Fn, class A1>
-class_& def(char const* name, Fn fn, A1 const& a1);
-template <class Fn, class A1, class A2>
-class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2);
-template <class Fn, class A1, class A2, class A3>
-class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
-
    -
  • - If a1 is the result of an overload-dispatch-expression, - only the second form is allowed and fn must be a pointer to - function or pointer to member function whose arity is the same as A1's maximum - arity. - -
    -
    Effects: For each prefix P of - Fn's sequence of argument types, beginning with - the one whose length is A1's minimum - arity, adds a - name(...) method overload to - the extension class. Each overload generated invokes - a1's call-expression with P, using a copy - of a1's call - policies. If the longest valid prefix of A1 - contains N types and a1 holds M - keywords, an initial sequence of the keywords are used for all - but the first N - M arguments of - each overload.
    -
    -
    -
  • - -
  • - Otherwise, a single method overload is built around fn, which - must not be null: - -
      -
    • If fn is a function pointer, its first argument must be of - the form U, cv&, - cv*, or - cv* const&, where - T* is convertible to U*, and - a1-a3, if supplied, may be selected - in any order from the table below.
    • - -
    • Otherwise, if fn is a member function pointer, its target - must be T or one of its public base classes, and - a1-a3, if supplied, may be selected - in any order from the table below.
    • - -
    • Otherwise, Fn must be [derived from] object, and - a1-a2, if supplied, may be selcted in any order - from the first two rows of the table below. To be useful, - fn should be - callable.
    • -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Memnonic NameRequirements/Type propertiesEffects
    docstringAny ntbs.Value will be bound to the __doc__ attribute - of the resulting method overload.
    policiesA model of CallPoliciesA copy will be used as the call policies of the resulting - method overload.
    keywordsThe result of a keyword-expression - specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting - method overload.
    -
  • -
-
- -
Returns: *this
-
-
-class_& staticmethod(char const* name);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules, and corresponds to a method whose overloads have all - been defined.
- -
Effects: Replaces the existing named attribute x with - the result of invoking staticmethod(x) - in Python. Specifies that the corresponding method is static and - therefore no object instance will be passed to it. This is equivalent - to the Python statement:
- -
-
-setattr(self, name, staticmethod(getattr(self, name)))
-
-
- -
Note: Attempting to invoke def(name,...) after - invoking staticmethod(name) will raise a RuntimeError.
- -
Returns: *this
-
-
- -
-template <unspecified>
-class_& def(detail::operator_<unspecified>);
-
- -
-
Effects: Adds a Python special method as - described here.
- -
Returns: *this
-
-
-template <class U>
-class_& setattr(char const* name, U const& u);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
Effects: Converts u to Python and adds it to the attribute - dictionary of the extension class:
- -
-
- PyObject_SetAttrString(this->ptr(), name, object(u).ptr()); -
-
- -
Returns: *this
-
-
- -
-template <class Get>
-void add_property(char const* name, Get const& fget);
-template <class Get, class Set>
-void add_property(char const* name, Get const& fget, Set const& fset);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
Effects: Creates a new Python property - class instance, passing object(fget) (and object(fset) in the - second form) to its constructor, then adds that property to the Python - class object under construction with the given attribute - name.
- -
Returns: *this
- -
Rationale: Allows users to easily expose functions that can - be invoked from Python with attribute access syntax.
-
-
-
-template <class D>
-class_& def_readonly(char const* name, D T::*pm);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
Effects:
- -
-
-this->add_property(name, make_getter(pm));
-
-
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' data - member such that it can be inspected from Python with a natural - syntax.
-
-
-template <class D>
-class_& def_readwrite(char const* name, D T::*pm);
-
- -
-
Effects:
- -
-
-this->add_property(name, make_getter(pm), make_setter(pm));
-
-
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' data - member such that it can be inspected and set from Python with a natural - syntax.
-
-
-template <typename PickleSuite>
-class_& def_pickle(PickleSuite const&);
-
- -
-
Requires: PickleSuite must be publically derived from pickle_suite.
- -
Effects: Defines a legal combination of the special - attributes and methods: __getinitargs__, - __getstate__, __setstate__, - __getstate_manages_dict__, - __safe_for_unpickling__, __reduce__
- -
Returns: *this
- -
Rationale: Provides an easy to use - high-level interface for establishing complete pickle support for - the wrapped class. The user is protected by compile-time consistency - checks.
-
-
- - -

Class template - bases<T1, T2,...TN>

- -

An MPL sequence - which can be used in class_<...> - instantiations indicate a list of base classes.

- -

Class template bases - synopsis

-
-namespace boost { namespace python
-{
-  template <T1 = unspecified,...Tn = unspecified>
-  struct bases
-  {};
-}}
-
- -

Example(s)

- -

Given a C++ class declaration:

-
-class Foo : public Bar, public Baz
-{
- public:
-   Foo(int x, char const* y);
-   Foo(double);
-
-   std::string const& name() { return m_name; }
-   void name(char const*);
-
-   double value; // public data
- private:
-   ...
-};
-
- A corresponding Boost.Python extension class can be created with: -
-using namespace boost::python;
-
-class_<Foo,bases<Bar,Baz> >("Foo",
-          "This is Foo's docstring."
-          "It describes our Foo extension class",
-
-          init<int,char const*>(args("x","y"), "__init__ docstring")
-          )
-   .def(init<double>())
-   .def("get_name", &Foo::get_name, return_internal_reference<>())
-   .def("set_name", &Foo::set_name)
-   .def_readwrite("value", &Foo::value)
-   ;
-
-
- [1] By "previously-exposed" we mean that the for - each B in bases, an instance of - class_<B, ...> must have - already been constructed. -
-class_<Base>("Base");
-class_<Derived, bases<Base> >("Derived");
-
- Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/configuration.html b/doc/v2/configuration.html deleted file mode 100644 index feee4a05..00000000 --- a/doc/v2/configuration.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - Boost.Python - Configuration - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Configuration

-
-
- -
-
Introduction
- -
Application Defined Macros
- -
Library Defined Implementation - Macros
-
- -

Introduction

- -

Boost.Python uses several configuration macros in <boost/config.hpp>, - as well as configuration macros meant to be supplied by the application. - These macros are documented here.

- -

Application Defined Macros

- -

These are the macros that may be defined by an application using - Boost.Python. Note that if you extend a strict interpretation of - the C++ standard to cover dynamic libraries, using different values of - these macros when compiling different libraries (including extension - modules and the Boost.Python library itself) is a violation of the - ODR. However, we know of no C++ - implementations on which this particular violation is detectable or - causes any problems.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MacroDefaultMeaning
BOOST_PYTHON_MAX_ARITY15The maximum arity of any function, member function, - or constructor to be wrapped, invocation of a Boost.Python - function wich is specified as taking arguments - x1, x2,...Xn. This includes, in - particular, callback mechanisms such as object::operator()(...) - or call_method<R>(... - ).
BOOST_PYTHON_MAX_BASES10The maximum number of template arguments to the - bases<...> - class template, which is used to specify the bases of a wrapped C++ - class..
BOOST_PYTHON_STATIC_MODULEnot definedIf defined, prevents your module initialization - function from being treated as an exported symbol on platforms which - support that distinction in-code
- -

Library Defined Implementation - Macros

- -

These macros are defined by Boost.Python and are implementation - details of interest only to implementors and those porting to new - platforms.

- - - - - - - - - - - - - - - - - -
MacroDefaultMeaning
BOOST_PYTHON_TYPE_ID_NAMEnot definedIf defined, this indicates that the type_info - comparison across shared library boundaries does not work on this - platform. In other words, if shared-lib-1 passes - typeid(T) to a function in shared-lib-2 which compares - it to typeid(T), that comparison may return - false. If this macro is #defined, Boost.Python uses and - compares typeid(T).name() instead of using and comparing - the std::type_info objects directly.
-
- -

Revised - - 7 January, 2003 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html deleted file mode 100644 index c65fc21c..00000000 --- a/doc/v2/copy_const_reference.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/copy_const_reference.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/copy_const_reference.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - copy_const_reference
- -
-
-
Class - copy_const_reference synopsis
- -
Class - copy_const_reference metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - copy_const_reference

- -

copy_const_reference is a model of ResultConverterGenerator - which can be used to wrap C++ functions returning a reference-to-const - type such that the referenced value is copied into a new Python - object.

- -

Class - copy_const_reference synopsis

-
-namespace boost { namespace python
-{
-    struct copy_const_reference
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - copy_const_reference metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U const& for - some U.
- -
Returns: typedef to_python_value<T> - type;
-
- -

Example

- -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/copy_const_reference.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { int x; }
-
-struct Foo {
-   Foo(int x) : { b.x = x; }
-   Bar const& get_bar() const { return b; }
- private:
-   Bar b;
-};
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    class_<Bar>("Bar");
-
-     class_<Foo>("Foo", init<int>())
-        .def("get_bar", &Foo::get_bar
-            , return_value_policy<copy_const_reference>())
-       ;
-}
-
- -

Python Code

-
->>> from my_module import *
->>> f = Foo(3)         # create a Foo object
->>> b = f.get_bar()    # make a copy of the internal Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html deleted file mode 100644 index 9cce0e74..00000000 --- a/doc/v2/copy_non_const_reference.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/copy_non_const_reference.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/copy_non_const_reference.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - copy_non_const_reference
- -
-
-
Class - copy_non_const_reference synopsis
- -
Class - copy_non_const_reference metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - copy_non_const_reference

- -

copy_non_const_reference is a model of ResultConverterGenerator - which can be used to wrap C++ functions returning a - reference-to-non-const type such that the referenced value is copied into - a new Python object.

- -

Class - copy_non_const_reference synopsis

-
-namespace boost { namespace python
-{
-    struct copy_non_const_reference
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - copy_non_const_reference metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U& for some - non-const U.
- -
Returns: typedef to_python_value<T> - type;
-
- -

Example

- -

C++ code:

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/copy_non_const_reference.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { int x; }
-
-struct Foo {
-   Foo(int x) : { b.x = x; }
-   Bar& get_bar() { return b; }
- private:
-   Bar b;
-};
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    class_<Bar>("Bar");
-
-     class_<Foo>("Foo", init<int>())
-        .def("get_bar", &Foo::get_bar
-            , return_value_policy<copy_non_const_reference>())
-       ;
-}
-
- Python Code: -
->>> from my_module import *
->>> f = Foo(3)         # create a Foo object
->>> b = f.get_bar()    # make a copy of the internal Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html deleted file mode 100644 index 0f015780..00000000 --- a/doc/v2/data_members.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/data_members.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/data_members.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
make_getter
- -
make_setter
-
-
- -
Example
-
-
- -

Introduction

- -

make_getter() and - make_setter() are the - functions used internally by class_<>::def_readonly and - class_<>::def_readwrite to produce - Python callable objects which wrap C++ data members.

- -

Functions

-
-template <class C, class D>
-object make_getter(D C::*pm);
-
-template <class C, class D, class Policies>
-object make_getter(D C::*pm, Policies const& policies);
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Creates a Python callable object which accepts a - single argument that can be converted from_python to - C*, and returns the corresponding member D - member of the C object, converted to_python. - If policies is supplied, it will be applied to the - function as described here. Otherwise, - the library attempts to determine whether D is a - user-defined class type, and if so uses return_internal_reference<>
- -
for Policies. Note that this test may inappropriately - choose return_internal_reference<> in some cases - when D is a smart pointer type. This is a known - defect.
- -
Returns: An instance of object which holds the new Python - callable object.
-
-
-template <class C, class D>
-object make_setter(D C::*pm);
-
-template <class C, class D, class Policies>
-object make_setter(D C::*pm, Policies const& policies);
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Creates a Python callable object which, when called - from Python, expects two arguments which can be converted - from_python to C* and - D const&, respectively, and sets the - corresponding D member of the C object. If - policies is supplied, it will be applied to the function - as described here.
- -
Returns: An instance of object which holds the new Python - callable object.
-
- -

Example

- -

The code below uses make_getter and make_setter to expose a data - member as functions:

-
-#include <boost/python/data_members.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-
-struct X
-{
-    X(int x) : y(x) {}
-    int y;
-};
-
-using namespace boost::python;
-
-BOOST_PYTHON_MODULE_INIT(data_members_example)
-{
-    class_<X>("X", init<int>())
-       .def("get", make_getter(&X::y))
-       .def("set", make_setter(&X::y))
-       ;
-}
-
- It can be used this way in Python: -
->>> from data_members_example import *
->>> x = X(1)
->>> x.get()
-1
->>> x.set(2)
->>> x.get()
-2
-
- -

- - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/def.html b/doc/v2/def.html deleted file mode 100644 index 80978a87..00000000 --- a/doc/v2/def.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/def.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/def.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
def
-
-
- -
Example
-
-
- -

Introduction

- -

def() is the function which can - be used to expose C++ functions and callable objects as Python functions - in the current scope.

- -

Functions

- def -
-template <class F>
-void def(char const* name, F f);
-
-template <class Fn, class A1>
-void def(char const* name, Fn fn, A1 const&);
-
-template <class Fn, class A1, class A2>
-void def(char const* name, Fn fn, A1 const&, A2 const&);
-
-template <class Fn, class A1, class A2, class A3>
-void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
-
    -
  • If Fn is [derived from] object, it will be added to - the current scope as a single overload. To be useful, - fn should be callable.
  • - -
  • - If a1 is the result of an overload-dispatch-expression, - only the second form is allowed and fn must be a pointer to - function or pointer to member function whose arity is the same as A1's maximum - arity. - -
    -
    Effects: For each prefix P of - Fn's sequence of argument types, beginning with - the one whose length is A1's minimum - arity, adds a - name(...) function overload - to the current scope. Each overload - generated invokes a1's call-expression with - P, using a copy of a1's call policies. If the longest valid - prefix of A1 contains N types and - a1 holds M keywords, an initial sequence - of the keywords are used for all but the first - N - M arguments of each - overload.
    -
    -
    -
  • - -
  • Otherwise, fn must be a non-null function or member function - pointer, and a single function overload built around fn is added to - the current scope. If any of - a1-a3 are supplied, they may be selected - in any order from the table below.
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Memnonic NameRequirements/Type propertiesEffects
docstringAny ntbs.Value will be bound to the __doc__ attribute of - the resulting method overload.
policiesA model of CallPoliciesA copy will be used as the call policies of the resulting - method overload.
keywordsThe result of a keyword-expression - specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting - method overload.
-
-
- -

Example

-
-#include <boost/python/def.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/args.hpp>
-
-using namespace boost::python;
-
-char const* foo(int x, int y) { return "foo"; }
-
-BOOST_PYTHON_MODULE(def_test)
-{
-    def("foo", foo, args("x", "y"), "foo's docstring");
-}
-
- -

- - 7 March, 2003 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/default_call_policies.html b/doc/v2/default_call_policies.html deleted file mode 100644 index 90f816fa..00000000 --- a/doc/v2/default_call_policies.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - Boost.Python - - <boost/python/default_call_policies.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header - <boost/python/default_call_policies.hpp>

-
-
- -

Contents

- -
-
Classes - -
-
-
Class - default_call_policies - -
-
-
Class - default_call_policies synopsis - -
Class - default_call_policies static functions -
- -
Class - default_result_converter - -
-
-
Class - default_result_converter synopsis - -
Class - default_result_converter metafunctions -
-
- -
Example -
-
- -

Classes

- -

Class - default_call_policies

- -

default_call_policies is a model of CallPolicies with no precall or - postcall behavior and a result_converter which - handles by-value returns. Wrapped C++ functions and member functions use - default_call_policies unless otherwise specified. You may find - it convenient to derive new models of CallPolicies from - default_call_policies. - -

Class - default_call_policies synopsis

-
-namespace boost { namespace python
-{
-    struct default_call_policies
-    {
-        static bool precall(PyObject*);
-        static PyObject* postcall(PyObject*, PyObject* result);
-        typedef default_result_converter result_converter;
-    };
-}}
-
- -

Class - default_call_policies static functions

-
-bool precall(PyObject*);
-
- -
-
Returns: true - -
Throws: nothing -
-
-PyObject* postcall(PyObject*, PyObject* result);
-
- -
-
Returns: result - -
Throws: nothing -
- -

Class - default_result_converter

- -

default_result_converter is a model of ResultConverterGenerator which can be - used to wrap C++ functions returning non-pointer types, char - const*, and PyObject*, by-value. - -

Class - default_result_converter synopsis

-
-namespace boost { namespace python
-{
-    struct default_result_converter
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - default_result_converter metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is not a reference type. If - T is a pointer type, T is const - char* or PyObject*. - -
Returns: typedef to_python_value<T - const&> type; -
- -

Example

- -

This example comes from the Boost.Python implementation itself. Because - the return_value_policy - class template does not implement precall or - postcall behavior, its default base class is - default_call_policies: -

-template <class Handler, class Base = default_call_policies>
-struct return_value_policy : Base
-{
-   typedef Handler result_converter;
-};
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html deleted file mode 100644 index 625e9b74..00000000 --- a/doc/v2/definitions.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - Boost.Python - Definitions - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Definitions

-
-


- -
-
arity: The number of arguments accepted - by a function or member function. Unless otherwise specified, the - hidden "this" argument to member functions is not counted - when specifying arity
- -

-
- -
ntbs: Null-Terminated Byte String, or - `C'-string. C++ string literals are ntbses. An - ntbs must never be null.
- -

-
- -
raise: Exceptions in Python are - "raised", not "thrown", as they are in C++. When this documentation - says that some Python exception is "raised" in the context of C++ code, - it means that the corresponding Python exception is set via the Python/'C' - API, and throw_error_already_set() - is called.
- -

-
- -
POD: A technical term from the C++ - standard. Short for "Plain Ol'Data": A POD-struct is an aggregate class - that has no non-static data members of type pointer to member, - non-POD-struct, non-POD-union (or array of such types) or reference, - and has no user-defined copy assign- ment operator and no user-defined - destructor. Similarly, a POD-union is an aggregate union that has no - non-static data members of type pointer to member, non-POD-struct, - non-POD-union (or array of such types) or reference, and has no - user-defined copy assignment operator and no user-defined destructor. A - POD class is a class that is either a POD-struct or a POD-union. An - aggregate is an array or a class (clause 9) with no user-declared - constructors (12.1), no private or protected non-static data members - (clause 11), no base classes (clause 10), and no virtual functions - (10.3).
- -

-
- -
ODR: The "One Definition - Rule", which says that any entity in a C++ program must have the same definition in all translation units (object files) which make up a program. -
- -

-
- - -
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/dict.html b/doc/v2/dict.html deleted file mode 100644 index 3b4dc211..00000000 --- a/doc/v2/dict.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/dict.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/dict.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class dict
- -
-
-
Class dict - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - dict - type.

- -

Classes

- -

Class dict

- -

Exposes the mapping - protocol of Python's built-in dict type. The semantics - of the constructors and member functions defined below can be fully - understood by reading the TypeWrapper concept - definition. Since dict is publicly derived from object, the public object - interface applies to dict instances as well.

- -

Class dict - synopsis

-
-namespace boost { namespace python
-{
-   class dict : public object
-   {
-      dict();
-
-      template< class T >
-      dict(T const & data);
-
-      // modifiers
-      void clear();
-      dict copy();
-
-      template <class T1, class T2>
-      tuple popitem();
-
-      template <class T>
-      object setdefault(T const &k);
-
-      template <class T1, class T2>
-      object setdefault(T1 const & k, T2 const & d);
-
-      void update(object_cref E);
- 
-      template< class T >
-      void update(T const & E);
-
-      // observers
-      list values() const;
-    
-      object get(object_cref k) const;
-
-      template<class T>
-      object get(T const & k) const;
-
-      object get(object_cref k, object_cref d) const;
-      object get(T1 const & k, T2 const & d) const;
-
-      bool has_key(object_cref k) const;
-
-      template< class T >
-      bool has_key(T const & k) const;
-
-      list items() const;
-      object iteritems() const;
-      object iterkeys() const;
-      object itervalues() const;
-      list keys() const;
-  };
-}}
-
- -

Example

-
-using namespace boost::python;
-dict swap_object_dict(object target, dict d)
-{
-    dict result = extract<dict>(target.attr("__dict__"));
-    target.attr("__dict__") = d;
-    return result;
-}
-
- -

Revised 30 September, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/enum.html b/doc/v2/enum.html deleted file mode 100644 index 57926794..00000000 --- a/doc/v2/enum.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/enum.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/enum.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - enum_
- -
-
-
Class template enum_ - synopsis
- -
Class template enum_ - constructors
- -
Class template enum_ - modifier functions
-
-
- -
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/enum.hpp> defines the - interface through which users expose their C++ enumeration types - to Python. It declares the - enum_ class template, which is parameterized on the - enumeration type being exposed.

- - -

Classes

- -

Class template - enum_<T>

- -

Creates a Python class derived from Python's int - type which is associated with the C++ type passed as its first - parameter. - -

Class template enum_ - synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  class enum_ : public object
-  {
-    enum_(char const* name);
-    enum_<T>& value(char const* name, T);
-    enum_<T>& export_values();
-  };
-}}
-
- -

Class template enum_ - constructors

-
-enum_(char const* name);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules. - -
Effects: Constructs an enum_ object - holding a Python extension type derived from int - which is named name. The - named attribute of the current scope is bound to the new - extension type.
-
- -

Class template - enum_ modifier functions

-
-inline enum_<T>& value(char const* name, T x);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules. - -
Effects: adds an instance of the wrapped enumeration - type with value x to the type's dictionary as the - named attribute
. - -
Returns: *this
- -
- -
-inline enum_<T>& export_values();
-
- -
- -
Effects: sets attributes in the current scope with the - same names and values as all enumeration values exposed so far - by calling value()
. - -
Returns: *this
- -
- -

Example(s)

- -

C++ module definition -

-#include <boost/python/enum.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/module.hpp>
-
-using namespace boost::python;
-
-enum color { red = 1, green = 2, blue = 4 };
-
-color identity_(color x) { return x; }
-
-BOOST_PYTHON_MODULE(enums)
-{
-    enum_<color>("color")
-        .value("red", red)
-        .value("green", green)
-        .export_values()
-        .value("blue", blue)
-        ;
-    
-    def("identity", identity_);
-}
-
-

Interactive Python: -

->>> from enums import *
-
->>> identity(red)
-enums.color.red
-
->>> identity(color.red)
-enums.color.red
-
->>> identity(green)
-enums.color.green
-
->>> identity(color.green)
-enums.color.green
-
->>> identity(blue)
-Traceback (most recent call last):
-  File "<stdin>", line 1, in ?
-NameError: name blue' is not defined
-
->>> identity(color.blue)
-enums.color.blue
-
->>> identity(color(1))
-enums.color.red
-
->>> identity(color(2))
-enums.color.green
-
->>> identity(color(3))
-enums.color(3)
-
->>> identity(color(4))
-enums.color.blue
-
->>> identity(1)
-Traceback (most recent call last):
-  File "<stdin>", line 1, in ?
-TypeError: bad argument type for built-in operation
-
-
- - Revised - - 13 December, 2002 - - - -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/errors.html b/doc/v2/errors.html deleted file mode 100644 index 940c30fd..00000000 --- a/doc/v2/errors.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/errors.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/errors.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class - error_already_set
- -
-
-
Class - error_already_set synopsis
-
-
-
-
- -
Functions
- -
-
-
handle_exception
- -
expect_non_null
- -
throw_error_already_set
-
-
- -
Examples
-
-
- -

Introduction

- -

<boost/python/errors.hpp> provides types and - functions for managing and translating between Python and C++ exceptions. - This is relatively low-level functionality that is mostly used internally - by Boost.Python. Users should seldom need it.

- -

Classes

- -

Class - error_already_set

- -

error_already_set is an exception type which can be - thrown to indicate that a Python error has occurred. If thrown, the - precondition is that PyErr_Occurred() - returns a value convertible to true. Portable code shouldn't - throw this exception type directly, but should instead use throw_error_already_set(), - below.

- -

Class error_already_set - synopsis

-
-namespace boost { namespace python
-{
-    class error_already_set {};
-}}
-
- -

Functions

-
-template <class T> bool handle_exception(T f) throw();
-
-void handle_exception() throw();
-
- -
-
Requires: The first form requires that the expression - function0<void>(f) - is valid. The second form requires that a C++ exception is currently - being handled (see section 15.1 in the C++ standard).
- -
Effects: The first form calls f() inside a - try block which first attempts to use all registered exception translators. If none of - those translates the exception, the catch clauses then set - an appropriate Python exception for the C++ exception caught, returning - true if an exception was thrown, false - otherwise. The second form passes a function which rethrows the - exception currently being handled to the first form.
- -
Postconditions: No exception is being handled
- -
Throws: nothing
- -
Rationale: At inter-language boundaries it is important to - ensure that no C++ exceptions escape, since the calling language - usually doesn't have the equipment neccessary to properly unwind the - stack. Use handle_exception to manage exception - translation whenever your C++ code is called directly from the Python - API. This is done for you automatically by the usual function wrapping - facilities: make_function(), - make_constructor(), - def() and class_::def(). The second form can be - more convenient to use (see the example below), - but various compilers have problems when exceptions are rethrown from - within an enclosing try block.
-
-
-template <class T> T* expect_non_null(T* x);
-
- -
-
Returns: x
- -
Throws: error_already_set() iff x == - 0.
- -
Rationale: Simplifies error-handling when calling functions - in the Python/C - API which return 0 on error.
-
-
-void throw_error_already_set();
-
- -
-
Effects: throw error_already_set();
-
- -
-
Rationale: Many platforms and compilers are not able to - consistently catch exceptions thrown across shared library boundaries. - Using this function from the Boost.Python library ensures that the - appropriate catch block in handle_exception() can catch the - exception.
-
- -

Examples

-
-#include <string>
-#include <boost/python/errors.hpp>
-#include <boost/python/object.hpp>
-#include <boost/python/handle.hpp>
-
-// Returns a std::string which has the same value as obj's "__name__"
-// attribute.
-std::string get_name(boost::python::object obj)
-{
-   // throws if there's no __name__ attribute
-   PyObject* p = boost::python::expect_non_null(
-      PyObject_GetAttrString(obj.ptr(), "__name__"));
-
-   char const* s = PyString_AsString(p);
-   if (s != 0) 
-        Py_DECREF(p);
-
-   // throws if it's not a Python string
-   std::string result(
-      boost::python::expect_non_null(
-         PyString_AsString(p)));
-
-   Py_DECREF(p); // Done with p
-   
-   return result;
-}
-
-//
-// Demonstrate form 1 of handle_exception
-//
-
-// Place into result a Python Int object whose value is 1 if a and b have
-// identical "__name__" attributes, 0 otherwise.
-void same_name_impl(PyObject*& result, boost::python::object a, boost::python::object b)
-{
-   result = PyInt_FromLong(
-      get_name(a) == get_name(a2));
-}
-
-object borrowed_object(PyObject* p)
-{
-   return boost::python::object(
-        boost::python::handle<>(
-             boost::python::borrowed(a1)));
-}
-
-// This is an example Python 'C' API interface function
-extern "C" PyObject*
-same_name(PyObject* args, PyObject* keywords)
-{
-   PyObject* a1;
-   PyObject* a2;
-   PyObject* result = 0;
-
-   if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
-      return 0;
-   
-   // Use boost::bind to make an object compatible with
-   // boost::Function0<void>
-   if (boost::python::handle_exception(
-         boost::bind<void>(same_name_impl, boost::ref(result), borrowed_object(a1), borrowed_object(a2))))
-   {
-      // an exception was thrown; the Python error was set by
-      // handle_exception()
-      return 0;
-   }
-
-   return result;
-}
-
-//
-// Demonstrate form 2 of handle_exception. Not well-supported by all
-// compilers.
-//
-extern "C" PyObject*
-same_name2(PyObject* args, PyObject* keywords)
-{
-   PyObject* a1;
-   PyObject* a2;
-   PyObject* result = 0;
-
-   if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
-      return 0;
-
-   try {
-      return PyInt_FromLong(
-         get_name(borrowed_object(a1)) == get_name(borrowed_object(a2)));
-   }
-   catch(...)
-   {
-      // If an exception was thrown, translate it to Python
-      boost::python::handle_exception();
-      return 0;
-   }
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/exception_translator.html b/doc/v2/exception_translator.html deleted file mode 100644 index 8aa0fe3b..00000000 --- a/doc/v2/exception_translator.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/exception_translator.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/exception_translator.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
register_exception_translator
-
-
- -
Example(s)
-
-
- -

Introduction

- -

As described here, it - is important to make sure that exceptions thrown by C++ code do not pass - into the Python interpreter core. By default, Boost.Python translates all - C++ exceptions thrown by wrapped functions and module init functions into - Python, but the default translators are extremely limited: most C++ - exceptions will appear in Python as a RuntimeError - exception whose representation is - 'Unidentifiable C++ Exception'. To produce better - error messages, users can register additional exception translators as - described below.

- -

Functions

- -

register_exception_translator

- -
-template<class ExceptionType, class Translate>
-void register_exception_translator(Translate const& translate);
-
- -
-
Requires:
- -
- Translate is Copyconstructible, and - the following code must be well-formed: -
-void f(ExceptionType x) { translate(x); }
-
- The expression translate(x) must either throw a C++ - exception, or a subsequent call to PyErr_Occurred() - must return 1. -
- -

- -

Effects: Adds a copy of translate to the sequence of - exception translators tried when Boost.Python catches an exception that - is about to pass into Python's core interpreter. The new translator - will get "first shot" at translating all exceptions matching the catch - clause shown above. Any subsequently-registered translators will be - allowed to translate the exception earlier. A translator which cannot - translate a given C++ exception can re-throw it, and it will be handled - by a translator which was registered earlier (or by the default - translator).
-
- -

Example

-
-#include <boost/python/module.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/exception_translator.hpp>
-#include <exception>
-
-struct my_exception : std::exception
-{
-  char const* what() throw() { return "One of my exceptions"; }
-};
-
-void translate(my_exception const& e)
-{
-    // Use the Python 'C' API to set up an exception object
-    PyErr_SetString(PyExc_RuntimeError, e.what());
-}
-
-void something_which_throws()
-{
-    ...
-    throw my_exception();
-    ...
-}
-
-BOOST_PYTHON_MODULE(exception_translator_ext)
-{
-  using namespace boost::python;
-  register_exception_translator<my_exception>(&translate);
-  
-  def("something_which_throws", something_which_throws);
-}
-
-
-
- -
- -

Revised 03 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/extract.html b/doc/v2/extract.html deleted file mode 100644 index bec97f28..00000000 --- a/doc/v2/extract.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/extract.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/extract.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class extract
- -
-
-
Class extract - synopsis
- -
Class extract - constructors and destructor
- -
Class - extract observer functions
-
-
-
-
- - -
Example
-
-
- -

Introduction

- -

Exposes a mechanism for extracting C++ object values from - generalized Python objects. Note that - extract<...> can also be used to - "downcast" an object to some specific ObjectWrapper. Because - invoking a mutable python type with an argument of the same type - (e.g. list([1,2]) typically makes a copy of - the argument object, this may be the only way to access the ObjectWrapper's - interface on the original object. - -

Classes

- -

Class template extract

- -

extract<T> can be used to extract a value of - an arbitrary C++ type from an instance of object. Two usages are supported: -

    -
  1. extract<T>(o) is a temporary object -which is implicitly convertible to T (explicit conversion -is also available through the object's function-call -operator). However, if no conversion is available which can convert -o to an object of type T, a Python -TypeError exception will be raised. - -
  2. extract<T> x(o); constructs an extractor -whose check() member function can be used to ask whether -a conversion is available without causing an exception to be thrown. -
- -

Class template extract - synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  struct extract
-  {
-      typedef unspecified result_type;
-
-      extract(PyObject*);
-      extract(object const&);
-
-      result_type operator()() const;
-      operator result_type() const;
-
-      bool check() const;
-  };
-}}
-
- -

Class extract - constructors and destructor

-
-extract(PyObject* p);
-extract(object const&);
-
- -
-
Requires: The first form requires that p is non-null.
- -
Effects:Stores a pointer to the Python object managed - by its constructor argument. In particular, the reference - count of the object is not incremented. The onus is on the user - to be sure it is not destroyed before the extractor's conversion - function is called.
-
- -

Class extract - observer functions

-
-result_type operator()() const;
-operator result_type() const;
-
- -
-
Effects: Converts the stored pointer to - result_type, which is either T or - T const&. -
- -
Returns: An object of result_type - corresponding to the one referenced by the stored pointer.
- -
Throws: error_already_set - and sets a TypeError if no such conversion is - available. May also emit other unspecified exceptions thrown by - the converter which is actually used.
-
- -
-bool check() const;
-
- -
- -
Postconditions: None. In particular, note that a - return value of true does not preclude an exception - being thrown from operator result_type() or - operator()().
- -
Returns: false only if no conversion from the - stored pointer to T is available.
- -
- - -

Examples

- -
-#include <cstdio>
-using namespace boost::python;
-int Print(str s)
-{ 
-   // extract a C string from the Python string object
-   char const* c_str = extract<char const*>(s);
-
-   // Print it using printf
-   std::printf("%s\n", c_str);
-
-   // Get the Python string's length and convert it to an int
-   return extract<int>(s.attr("__len__")())
-}
-
- -The following example shows how extract can be used along with -class_<...> -to create and access an instance of a wrapped C++ class. - -
-struct X
-{
-   X(int x) : v(x) {}
-   int value() { return v; }
- private:
-   int v;
-};
-
-BOOST_PYTHON_MODULE(extract_ext)
-{
-    object x_class(
-       class_<X>("X", init<int>())
-          .def("value", &X::value))
-          ;
-        
-    // Instantiate an X object through the Python interface. 
-    // Its lifetime is now managed by x_obj.
-    object x_obj = x_class(3);
-
-    // Get a reference to the C++ object out of the Python object
-    X& x = extract<X&>(x_obj);
-    assert(x.value() == 3);
-}
-
-

Revised 15 November, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/faq.html b/doc/v2/faq.html deleted file mode 100644 index 4a6448cb..00000000 --- a/doc/v2/faq.html +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - - - - Boost.Python - FAQ - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Frequently Asked Questions (FAQs)

-
-
- -
-
I'm getting the "attempt to return dangling - reference" error. What am I doing wrong?
- -
Is return_internal_reference - efficient?
- -
How can I wrap functions which take C++ - containers as arguments?
- -
fatal error C1204:Compiler limit:internal - structure overflow
- -
How do I debug my Python extensions?
- -
Why doesn't my *= operator - work?
- -
Does Boost.Python work with Mac OS X?
- -
How can I find the existing PyObject that holds a - C++ object?
- -
How can I wrap a function which needs to take - ownership of a raw pointer?
-
-
- -

I'm getting the "attempt to return dangling - reference" error. What am I doing wrong?

- That exception is protecting you from causing a nasty crash. It usually - happens in response to some code like this: -
-period const& get_floating_frequency() const
-{
-  return boost::python::call_method<period const&>(
-      m_self,"get_floating_frequency");
-}
-
- And you get: -
-ReferenceError: Attempt to return dangling reference to object of type:
-class period
-
- -

In this case, the Python method invoked by call_method - constructs a new Python object. You're trying to return a reference to a - C++ object (an instance of class period) contained within - and owned by that Python object. Because the called method handed back a - brand new object, the only reference to it is held for the duration of - get_floating_frequency() above. When the function returns, - the Python object will be destroyed, destroying the instance of - class period, and leaving the returned reference dangling. - That's already undefined behavior, and if you try to do anything with - that reference you're likely to cause a crash. Boost.Python detects this - situation at runtime and helpfully throws an exception instead of letting - you do that.
-  

-
- -

Is return_internal_reference efficient?

- -
- Q: I have an object composed of 12 doubles. A const& to - this object is returned by a member function of another class. From the - viewpoint of using the returned object in Python I do not care if I get - a copy or a reference to the returned object. In Boost.Python Version 2 - I have the choice of using copy_const_reference or - return_internal_reference. Are there considerations that would lead me - to prefer one over the other, such as size of generated code or memory - overhead? - -

A: copy_const_reference will make an instance with storage - for one of your objects, size = base_size + 12 * sizeof(double). - return_internal_reference will make an instance with storage for a - pointer to one of your objects, size = base_size + sizeof(void*). - However, it will also create a weak reference object which goes in the - source object's weakreflist and a special callback object to manage the - lifetime of the internally-referenced object. My guess? - copy_const_reference is your friend here, resulting in less overall - memory use and less fragmentation, also probably fewer total - cycles.

-
-
- -

How can I wrap functions which take C++ - containers as arguments?

- -

Ralf W. Grosse-Kunstleve provides these notes:

- -
    -
  1. - Using the regular class_<> wrapper: -
    -class_<std::vector<double> >("std_vector_double")
    -  .def(...)
    -  ...
    -  ;
    -
    - This can be moved to a template so that several types (double, int, - long, etc.) can be wrapped with the same code. This technique is used - in the file - -
    - scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h -
    - in the "scitbx" package. The file could easily be modified for - wrapping std::vector<> instantiations. - -

    This type of C++/Python binding is most suitable for containers - that may contain a large number of elements (>10000).

    -
  2. - -
  3. - Using custom rvalue converters. Boost.Python "rvalue converters" - match function signatures such as: -
    -void foo(std::vector<double> const& array); // pass by const-reference
    -void foo(std::vector<double> array); // pass by value
    -
    - Some custom rvalue converters are implemented in the file - -
    - scitbx/include/scitbx/boost_python/container_conversions.h -
    - This code can be used to convert from C++ container types such as - std::vector<> or std::list<> to Python tuples and vice - versa. A few simple examples can be found in the file - -
    - scitbx/array_family/boost_python/regression_test_module.cpp -
    - Automatic C++ container <-> Python tuple conversions are most - suitable for containers of moderate size. These converters generate - significantly less object code compared to alternative 1 above. -
  4. -
- A disadvantage of using alternative 2 is that operators such as - arithmetic +,-,*,/,% are not available. It would be useful to have custom - rvalue converters that convert to a "math_array" type instead of tuples. - This is currently not implemented but is possible within the framework of - Boost.Python V2 as it will be released in the next couple of weeks. [ed.: - this was posted on 2002/03/10] - -

It would also be useful to also have "custom lvalue converters" such - as std::vector<> <-> Python list. These converters would - support the modification of the Python list from C++. For example:

- -

C++:

-
-void foo(std::vector<double>& array)
-{
-  for(std::size_t i=0;i<array.size();i++) {
-    array[i] *= 2;
-  }
-}
-
- Python: -
->>> l = [1, 2, 3]
->>> foo(l)
->>> print l
-[2, 4, 6]
-
- Custom lvalue converters require changes to the Boost.Python core library - and are currently not available. - -

P.S.:

- -

The "scitbx" files referenced above are available via anonymous - CVS:

-
-cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
-cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
-
-
- -

fatal error C1204:Compiler limit:internal - structure overflow

- -
- Q: I get this error message when compiling a large source - file. What can I do? - -

A: You have two choices:

- -
    -
  1. Upgrade your compiler (preferred)
  2. - -
  3. - Break your source file up into multiple translation units. - -

    my_module.cpp:

    -
    -...
    -void more_of_my_module();
    -BOOST_PYTHON_MODULE(my_module)
    -{
    -   def("foo", foo);
    -   def("bar", bar);
    -   ...
    -   more_of_my_module();
    -}
    -
    - more_of_my_module.cpp: -
    -void more_of_my_module()
    -{
    -   def("baz", baz);
    -   ...
    -}
    -
    - If you find that a class_<...> declaration - can't fit in a single source file without triggering the error, you - can always pass a reference to the class_ object to a - function in another source file, and call some of its member - functions (e.g. .def(...)) in the auxilliary source - file: - -

    more_of_my_class.cpp:

    -
    -void more_of_my_class(class<my_class>& x)
    -{
    -   x
    -     .def("baz", baz)
    -     .add_property("xx", &my_class::get_xx, &my_class::set_xx)
    -     ;
    -
    -   ...
    -}
    -
    -
  4. -
-
-
- -

How do I debug my Python extensions?

- -

Greg Burley gives the following answer for Unix GCC users:

- -
- Once you have created a boost python extension for your c++ library or - class, you may need to debug the code. Afterall this is one of the - reasons for wrapping the library in python. An expected side-effect or - benefit of using BPL is that debugging should be isolated to the c++ - library that is under test, given that python code is minimal and - boost::python either works or it doesn't. (ie. While errors can occur - when the wrapping method is invalid, most errors are caught by the - compiler ;-). - -

The basic steps required to initiate a gdb session to debug a c++ - library via python are shown here. Note, however that you should start - the gdb session in the directory that contains your BPL my_ext.so - module.

-
-(gdb) target exec python
-(gdb) run
- >>> from my_ext import *
- >>> [C-c]
-(gdb) break MyClass::MyBuggyFunction
-(gdb) cont
- >>> pyobj = MyClass()
- >>> pyobj.MyBuggyFunction()
-Breakpoint 1, MyClass::MyBuggyFunction ...
-Current language:  auto; currently c++
-(gdb) do debugging stuff
-
-
- -

Greg's approach works even better using Emacs' "gdb" - command, since it will show you each line of source as you step through - it.

- -

On Windows, my favorite debugging solution is the debugger that - comes with Microsoft Visual C++ 7. This debugger seems to work with code - generated by all versions of Microsoft and Metrowerks toolsets; it's rock - solid and "just works" without requiring any special tricks from the - user.

- -

Unfortunately for Cygwin and MinGW users, as of this writing gdb on - Windows has a very hard time dealing with shared libraries, which could - make Greg's approach next to useless for you. My best advice for you is - to use Metrowerks C++ for compiler conformance and Microsoft Visual - Studio as a debugger when you need one.

- -

Debugging extensions through Boost.Build

- If you are launching your extension module tests with Boost.Build using the - boost-python-runtest rule, you can ask it to launch your - debugger for you by adding "-sPYTHON_LAUNCH=debugger" to your bjam - command-line: -
-bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
-bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
-
- It can also be extremely useful to add the -d+2 option when - you run your test, because Boost.Build will then show you the exact - commands it uses to invoke it. This will invariably involve setting up - PYTHONPATH and other important environment variables such as - LD_LIBRARY_PATH which may be needed by your debugger in order to get - things to work right. -
- -

Why doesn't my *= operator work?

- -
- Q: I have exported my class to python, with many overloaded - operators. it works fine for me except the *= - operator. It always tells me "can't multiply sequence with non int - type". If I use p1.__imul__(p2) instead of - p1 *= p2, it successfully executes my code. What's - wrong with me? - -

A: There's nothing wrong with you. This is a bug in Python - 2.2. You can see the same effect in Pure Python (you can learn a lot - about what's happening in Boost.Python by playing with new-style - classes in Pure Python).

-
->>> class X(object):
-...     def __imul__(self, x):
-...         print 'imul'
-...
->>> x = X()
->>> x *= 1
-
- To cure this problem, all you need to do is upgrade your Python to - version 2.2.1 or later. -
-
- -

Does Boost.Python work with Mac OS X?

- -
-

The short answer: as of January 2003, unfortunately not.

- -

The longer answer: using Mac OS 10.2.3 with the December Developer's - Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles - fine, including the examples. However, there are problems at runtime - (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). - Solutions are currently unknown.

- -

It is known that under certain circumstances objects are - double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html - for details. It is not clear however if this problem is related to the - Boost.Python runtime issues.

-
-
- -

How can I find the existing PyObject that holds a C++ - object?

- -
- "I am wrapping a function that always returns a pointer to an - already-held C++ object." -
- One way to do that is to hijack the mechanisms used for wrapping a class - with virtual functions. If you make a wrapper class with an initial - PyObject* constructor argument and store that PyObject* as "self", you - can get back to it by casting down to that wrapper type in a thin wrapper - function. For example: -
-class X { X(int); virtual ~X(); ... };
-X* f();  // known to return Xs that are managed by Python objects
-
-
-// wrapping code
-
-struct X_wrap : X
-{
-    X_wrap(PyObject* self, int v) : self(self), X(v) {}
-    PyObject* self;
-};
-
-handle<> f_wrap()
-{
-    X_wrap* xw = dynamic_cast<X_wrap*>(f());
-    assert(xw != 0);
-    return handle<>(borrowed(xw->self));
-}
-
-...
-
-def("f", f_wrap());
-class_<X,X_wrap>("X", init<int>())
-   ...
-   ;
-
- Of course, if X has no virtual functions you'll have to use - static_cast instead of dynamic_cast with no - runtime check that it's valid. This approach also only works if the - X object was constructed from Python, because - Xs constructed from C++ are of course never - X_wrap objects. - -

Another approach to this requires you to change your C++ code a bit; - if that's an option for you it might be a better way to go. work we've - been meaning to get to anyway. When a shared_ptr<X> is - converted from Python, the shared_ptr actually manages a reference to the - containing Python object. When a shared_ptr<X> is converted back to - Python, the library checks to see if it's one of those "Python object - managers" and if so just returns the original Python object. So you could - just write object(p) to get the Python object back. To - exploit this you'd have to be able to change the C++ code you're wrapping - so that it deals with shared_ptr instead of raw pointers.

- -

There are other approaches too. The functions that receive the Python - object that you eventually want to return could be wrapped with a thin - wrapper that records the correspondence between the object address and - its containing Python object, and you could have your f_wrap function - look in that mapping to get the Python object out.

- -

How can I wrap a function which needs to take - ownership of a raw pointer?

- -
- Part of an API that I'm wrapping goes something like this: -
-struct A {}; struct B { void add( A* ); }
-where B::add() takes ownership of the pointer passed to it.
-
- -

However:

-
-a = mod.A()
-b = mod.B()
-b.add( a )
-del a         
-del b
-# python interpreter crashes 
-# later due to memory corruption.
-
- -

Even binding the lifetime of a to b via - with_custodian_and_ward doesn't prevent the python object a from - ultimately trying to delete the object it's pointing to. Is there a way - to accomplish a 'transfer-of-ownership' of a wrapped C++ object?

- -

--Bruce Lowery

-
- Yes: Make sure the C++ object is held by auto_ptr: -
-class_<A, std::auto_ptr<A> >("A")
-    ...
-    ;
-
- Then make a thin wrapper function which takes an auto_ptr parameter: -
-void b_insert(B& b, std::auto_ptr<A> a)
-{
-    b.insert(a.get());
-    a.release();
-}
-
- Wrap that as B.add. Note that pointers returned via manage_new_object - will also be held by auto_ptr, so this transfer-of-ownership - will also work correctly. -
- -

Revised - - 23 January, 2003 - -

- -

© Copyright Dave Abrahams 2002-2003. All - Rights Reserved.

- - - diff --git a/doc/v2/feb2002.html b/doc/v2/feb2002.html deleted file mode 100644 index bc305a47..00000000 --- a/doc/v2/feb2002.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - Boost.Python - February 2002 Progress Report - - - - -
-

-

- -
-

Boost.Python

- -

February 2002 Progress Report

-
-
- -

Contents

- -
-
Python10 Conference Report - -
Boost.Python v2 Progress - -
-
-
Documentation - -
Overhaul of - to_python/from_python - conversion mechanism - -
Miscellaneous -
-
- -

Python10 Conference Report

- I spent the first week of February at the Python10 conference - in Alexandria, VA. I'm including this experience report - for two reasons: firstly, it documents where my time was - used. Secondly, a public presence for Boost.Python and - interaction between the Python and C++ communities is - important to the future of Boost.Python, which in turn is - important to the Kull Project. - -

Andy Koenig, of all people, was the keynote speaker of - this year's opening plenary session. He presented his - "impressions of a polyglot outsider", which - studiously avoided any mention of C++ until the end of his - talk, when he was asked about standardization. I was - surprised to learn that the C++ community at large wanted a - few more years before beginning but when ANSI accepted - HP's request for a standard, the process was forced to - start: it was a matter of participating or having - standardization proceed without one's input. Andy managed - to highlight very effectively the balance of strengths in - Python, one of the most important being its support for - extension via libraries. In many ways that makes Python a - good analogue for C++ in the interpreted world - -

There were several kind mentions of the Boost.Python - library from people who found it indispensable. I was - particularly happy that Karl MacMillan, Michael Droettboom, - and Ichiro Fujinaga from Johns Hopkins is using it to do OCR - on a vast library of music notation, since in a previous life - I was an author of music notation software. These guys are - also drawing on Ullrich Koethe's VIGRA library for image - manipulation (Ullrich has been a major contributor to - Boost.Python). They also have a system for writing the - Boost.Python wrapper code in C++ comments, which allows them - to keep all of the code in one place. I've asked them to - send me some information on that. - -

The development of Swig has been gaining momentum again - (the basic description at - www.boost.org/libs/python/doc/comparisons.html still - applies). The talk given about it by David Beazly was very - well-attended, and they appear to have quite a few users. - Swig's strengths (coverage of many langauages) and - weaknesses (incomplete C++ language support) haven't - changed, although the C++ support seems to have improved - considerably - they now claim to have a complete model of the - C++ type system. It seems to be mostly geared at wrapping - what Walter Landry calls "C-Tran": C++ code which - traffics in built-in types with little use of abstraction. - I'm not knocking that, either: I'm sure a lot of that - code exists, so it's a valuable service. One feature Swig - has which I'd like to steal is the ability to unwrap a - single Python argument into multiple C++ arguments, for - example, by converting a Python string into a pointer and - length. When his talk was over, David approached me about a - possible joint workshop on language binding, which sounds - like a fun idea to me. - -

I spent some considerable time talking with Steven Knight, - the leader of the Scons build tool effort. We had a lot to - share with one another, and I gained a much better - appreciation for many of the Scons design decisions. Scons - seems to be concentrating on being the ultimate build system - substrate, and Steve seemed to think that we were on the - right track with our high-level design. We both hope that the - Boost.Build V2 high-level architecture can eventually be - ported to run on top of Scons. - -

They also have a highly-refined and successful development - procedure which I'd like to emulate for Boost.Build V2. - Among many other things they do, their source-control system - automatically ensures that when you check in a new test, it - is automatically run on the currently checked-in state of the - code, and is expected to fail -- a relatively obvious good - idea which I've never heard before. - -

Guido Van Rossum's "State of the Python - Union" address was full of questions for the community - about what should be done next, but the one idea Guido seemed - to stress was that core language stability and continuing - library development would be a good idea (sound familiar?) I - mentioned the Boost model as a counterpoint to the idea of - something like CPAN (the massive Perl library archives), and - it seemed to generate some significant interest. I've - offered to work with anyone from the Python community who - wants to set up something like Boost. - -

There was some discussion of "string - interpolation" (variable substitution in strings), and - Guido mentioned that he had some thoughts about the - strengths/weaknesses of Python's formatting interface. It - might be useful for those working on formatting for boost to - contact him and find out what he has to say. - -

Ka-Ping Yee demoed a Mailman discussion thread weaver. - This tool weaves the various messages in a discussion thread - into a single document so you can follow the entire - conversation. Since we're looking very seriously at - moving Boost to Mailman, this could be a really useful thing - for us to have. If we do this, we'll move the yahoogroups - discussions into the mailman archive so old discussions can - be easily accessed in the same fashion. - -

And, just because it's cool, though perhaps not - relevant: http://homepages.ulb.ac.be/~arigo/psyco/ is a - promising effort to accelerate the execution of Python code - to speeds approaching those of compiled languages. It - reminded me a lot of Todd Veldhuizen's research into - moving parts of C++ template compilation to runtime, only - coming from the opposite end of things. - -

Boost.Python v2 Progress

- Here's what actually got accomplished. - -

Documentation

- -

My first priority upon returning from Python10 was to get - some documentation in place. After wasting an unfortunate - amount of time looking at automatic documentation tools which - don't quite work, I settled down to use Bill Kempf's - HTML templates designed to be a boost standard. While they - are working well, it is highly labor-intensive. - -

I decided to begin with the high-level reference material, - as opposed to tutorial, narrative, or nitty-gritty details of - the framework. It seemed more important to have a precise - description of the way the commonly-used components work than - to have examples in HTML (since we already have some test - modules), and since the low-level details are much - less-frequently needed by users it made sense for me to - simply respond to support requests for the time being. - -

After completing approximately 60% of the high-level docs - (currently checked in to libs/python/doc/v2), I found myself - ready to start documenting the mechanisms for creating - to-/from-python converters. This caused a dilemma: I had - realized during the previous week that a much simpler, - more-efficient, and easier-to-use implementation was - possible, but I hadn't planned on implementing it right - away, since what was already in place worked adequately. I - had also received my first query on the C++-sig about how to - write such a converter - -

Given the labor-intensive nature of documentation writing, - I decided it would be a bad idea to document the conversion - mechanism if I was just going to rewrite it. Often the best - impetus for simplifying a design is the realization that - understandably documenting its current state would be too - difficult, and this was no exception. - -

Overhaul of - to_python/from_python conversion - mechanism

- -

There were two basic realizations involved here: - -

    -
  1. to_python conversion could be a one-step - process, once an appropriate conversion function is found. - This allows elimination of the separate indirect - convertibility check - -
  2. There are basically two categories of from_python - conversions: those which lvalues stored within or held by - the Python object (essentially extractions), like what - happens when an instance of a C++ class exposed with class_ - is used as the target of a wrapped member function), and - those in which a new rvalue gets created, as when a Python - Float is converted to a C++ - complex<double> or a Python tuple is - converted to a C++ std::vector<>. From - the client side, there are two corresponding categories of - conversion: those which demand an lvalue conversion and - those which can accept an lvalue or an rvalue conversion. -
- The latter realization allowed the following collapse, which - considerably simplified things: - -
- - - - - - - - - - - - - - - - - -
Target Type - - Eligible Converters - -
T - - T rvalue or lvalue - -
T const - -
T volatile - -
T const volatile - -
T const& - -
T const* - - T lvalue - -
T volatile* - -
T const volatile* - -
T& - -
T volatile& - -
T const volatile& - -
T* const& - -
T const* const& - -
T volatile*const& - -
T const volatile*const& -
-
- This job included the following additional enhancements: - -
    -
  • Elimination of virtual functions, which cause object - code bloat - -
  • Registration of a single converter function for all - lvalue conversions, two for all rvalue conversions - -
  • Killed lots of unneeded code - -
  • Increased opacity of registry interface - -
  • Eliminated all need for decorated runtime type - identifiers - -
  • Updated test modules to reflect new interface - -
  • Eliminated the need for users to worry about converter - lifetime issues Additional Builtin Conversion Enhancements - -
  • Support for complex<float>, - complex<double>, and complex<long double> - conversions - -
  • Support for bool conversions - -
  • NULL pointers representable by None in Python - -
  • Support for conversion of Python classic classes to - numeric types -
- -

Miscellaneous

- These don't fit easily under a large heading: - -
    -
  • Support CallPolicies for class member functions - -
  • from_python_data.hpp: revamped type alignment - metaprogram so that it's fast enough for KCC - -
  • classfwd.hpp header forward-declares class_<T> - -
  • indirect_traits.hpp: - -
  • added is_pointer_to_reference - -
  • fixed bugs - -
  • Reduced recompilation dependencies - -
  • msvc_typeinfo works around broken MS/Intel typeid() - implementation - -
  • Many fixes and improvements to the type_traits library - in order to work around compiler bugs and suppress warnings - -
  • Eliminated the need for explicit acquisition of - converter registrations - -
  • Expanded constructor support to 6 arguments - -
  • Implemented generalized pointer lifetime support - -
  • Updated code generation for returning.hpp - -
  • Tracked down and fixed cycle GC bugs - -
  • Added comprehensive unit tests for destroy_reference, - pointer_type_id, select_from_python, complex<T>, - bool, and classic class instance conversions -
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams - 2002. All Rights Reserved. - diff --git a/doc/v2/from_python.html b/doc/v2/from_python.html deleted file mode 100644 index 6d08f733..00000000 --- a/doc/v2/from_python.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Boost.Python - <boost/python/from_python.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/from_python.hpp>

-
-


- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class - Templatefrom_python - -
-
-
Class Template - from_python synopsis - -
Class Template - from_python constructor - -
Class Template - from_python observer functions -
-
- -
Example -
-
- -

Introduction

- -

<boost/python/from_python.hpp> introduces a class - template from_python<T> for extracting a C++ object of - type T from a Python object. - -

Classes

- -

Class Template - from_python<class T>

- -

from_python<T> is the type used internally by - Boost.Python to extract C++ function arguments from a Python argument tuple - when calling a wrapped function. It can also be used directly to make - similar conversions in other contexts. - -

Class Template - from_python synopsis

-
-namespace boost { namespace python
-{
-   template <class T>
-   struct from_python : private boost::noncopyable // Exposition only.
-       // from_python<T> meets the NonCopyable requirements
-   {
-      from_python(PyObject*);
-      bool convertible() const;
-      convertible-to-T operator()(PyObject*) const;
-   };
-}
-
- -

Class Template - from_python constructor

-
-from_python(PyObject* p);
-
- -
-
Requires: p != 0 - -
Effects: Constructs a from_python object suitable - for extracting a C++ object of type T from p. -
- -

Class Template - from_python observer functions

-
-bool convertible() const;
-
- -
-
Returns: false if the conversion cannot succeed. - This indicates that either: - -
-
    -
  1. No from_python_converter was registered for - T, or - -
  2. any such converter rejected the constructor argument - p by returning 0 from its - convertible() function -
- Note that conversion may still fail in operator() due to - an exception. - -
Throws: nothing - -
Rationale: Because from_python<> is used in - overload resolution, and throwing an exception can be slow, it is useful - to be able to rule out a broad class of unsuccessful conversions without - throwing an exception. -
-
-convertible-to-T operator()(PyObject* p) const;
-
- -
-
Requires: *p refers to the same object which was - passed to the constructor, and convertible() returns - true. - -
Effects: performs the conversion - -
Returns: an object convertible to T. -
- -

Example

-
-#include <string>
-#include <boost/python/from_python.hpp>
-
-// If a std::string can be extracted from p, return its
-// length. Otherwise, return 0.
-std::size_t length_if_string(PyObject* p)
-{
-   from_python<std::string> converter(p);
-   if (!converter.convertible())
-      return 0;
-   else
-      return converter(p).size();
-}
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/handle.html b/doc/v2/handle.html deleted file mode 100644 index 947bc82c..00000000 --- a/doc/v2/handle.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/handle.hpp> - - - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/handle.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - handle
- -
-
-
Class handle - synopsis
- -
Class handle - constructors and destructor
- -
Class handle - modifier functions
- -
Class handle - observer functions
-
-
-
-
- -
Functions
- -
-
-
borrowed
- -
allow_null
-
-
-
-
- -

Introduction

- -

<boost/python/handle.hpp> provides - class template handle, a smart pointer for - managing reference-counted Python objects.

- -

Classes

- -

Class template handle

- -

handle is a smart pointer to a Python object type; it - holds a pointer of type T*, where T is its template - parameter. T must be either a type derived from - PyObject or a POD type - whose initial sizeof(PyObject) bytes are layout-compatible - with PyObject. Use handle<> at the - boundary between the Python/'C' API and high-level code; prefer object for a generalized - interface to Python objects.

- -

In this document, the term "upcast" refers to an - operation which converts a pointer Y* to a base class - pointer T* via static_cast<T*> if - Y is derived from T, or via C-style cast - (T*) if it is not. However, in the latter case the "upcast" - is ill-formed if the initial sizeof(PyObject) bytes of - Y are not layout-compatible with PyObject.

- -

Class template handle - synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  class handle
-  {
-      typedef unspecified-member-function-pointer bool_type;
-
-   public: // types
-      typedef T element_type;
-
-   public: // member functions
-      ~handle();
-
-      template <class Y>
-      explicit handle(detail::borrowed<null_ok<Y> >* p);
-
-      template <class Y>
-      explicit handle(null_ok<detail::borrowed<Y> >* p);
-
-      template <class Y>
-      explicit handle(detail::borrowed<Y>* p);
-
-      template <class Y>
-      explicit handle(null_ok<Y>* p);
-
-      template <class Y>
-      explicit handle(Y* p);
-
-      handle();
-
-      handle& operator=(handle const& r);
-
-      template<typename Y>
-      handle& operator=(handle<Y> const & r); // never throws
-
-
-      template <typename Y>
-      handle(handle<Y> const& r);
-
-      handle(handle const& r);
-
-      T* operator-> () const;
-      T& operator* () const;
-      T* get() const;
-      void reset();
-      T* release();
-
-      operator bool_type() const; // never throws
-   private:
-      T* m_p;
-  };
-  
-  template <class T> struct null_ok;
-  namespace detail { template <class T> struct borrowed; }
-}}
-
- -

Class handle constructors - and destructor

-
-virtual ~handle();
-
- -
-
Effects: - Py_XDECREF(upcast<PyObject*>(m_p))
-
-
-template <class Y>
-explicit handle(detail::borrowed<null_ok<Y> >* p);
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(p)); - m_p = upcast<T*>(p);
-
-
-template <class Y>
-explicit handle(null_ok<detail::borrowed<Y> >* p);
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(p)); - m_p = upcast<T*>(p);
-
-
-template <class Y>
-explicit handle(detail::borrowed<Y>* p);
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(p)); - m_p = upcast<T*>(expect_non_null(p));
-
-
-template <class Y>
-explicit handle(null_ok<Y>* p);
-
- -
-
Effects: - m_p = upcast<T*>(p);
-
-
-template <class Y>
-explicit handle(Y* p);
-
- -
-
Effects: - m_p = upcast<T*>(expect_non_null(p));
-
-
-handle();
-
- -
-
Effects: m_p = 0;
-
-
-template <typename Y>
-handle(handle<Y> const& r);
-handle(handle const& r);
-
- -
-
Effects: - m_p = r.m_p; Py_XINCREF(upcast<PyObject*>(m_p));
-
- -

Class handle - modifiers

-
-handle& operator=(handle const& r);
-template<typename Y>
-handle& operator=(handle<Y> const & r); // never throws
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(r.m_p)); Py_XDECREF( - upcast<PyObject*>(m_p)); m_p = r.m_p;
-
-
-T* release();
-
- -
-
Effects: T* x = m_p; m_p = 0;return - x;
-
-
-void reset();
-
- -
-
Effects: - *this = handle<T>();
-
- -

Class handle - observers

-
-T* operator-> () const;
-T* get() const;
-
- -
-
Returns: m_p;
-
-
-T& operator* () const;
-
- -
-
Returns: *m_p;
-
-
-operator bool_type() const; // never throws
-
- -
-
Returns: 0 if m_p == 0, a pointer - convertible to true otherwise.
-
- -

Functions

- -

borrowed

-
-template <class T>
-detail::borrowed<T>* borrowed(T* p)
-{
-    return (detail::borrowed<T>*)p;
-}
-
- -

allow_null

-
-template <class T>
-null_ok<T>* allow_null(T* p)
-{
-    return (null_ok<T>*)p;
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/has_back_reference.html b/doc/v2/has_back_reference.html deleted file mode 100644 index ab92e353..00000000 --- a/doc/v2/has_back_reference.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/has_back_reference.hpp> - - - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/has_back_reference.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - has_back_reference
- -
-
-
Class template - has_back_reference synopsis
-
-
- -
Example(s)
-
-
-
-
- -

Introduction

- -

<boost/python/has_back_reference.hpp> defines the - traits class template has_back_reference<>, which can - be specialized by the user to indicate that a wrapped class instance - holds a PyObject* corresponding to a Python object.

- -

Classes

- -

Class template - has_back_reference

- -

A unary metafunction whose value is true iff its argument - is a pointer_wrapper<>.

- -

Class template - has_back_reference synopsis

-
-namespace boost { namespace python
-{
-    template<class WrappedClass> class has_back_reference
-    { 
-        static unspecified value = false;
-    };
-}}
-
- -

A "traits - class" which is inspected by Boost.Python to determine how wrapped - classes can be constructed.

- -
-
value is an integral constant convertible to bool of - unspecified type.
- -
Specializations may substitute a value convertible to - true for value iff for each invocation of - class_<WrappedClass>::def(init<type-sequence... - >()), there exists a corresponding constructor - WrappedClass::WrappedClass(PyObject*, type-sequence... - ). If such a specialization exists, the - WrappedClass constructors will be called with a "back - reference" pointer to the corresponding Python object whenever they are - invoked from Python.
-
- -

Example

- -

C++ module definition

-
-#include <boost/python/class.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/has_back_reference.hpp>
-#include <boost/python/handle.hpp>
-#include <boost/shared_ptr.hpp>
-
-using namespace boost::python;
-
-struct X
-{
-    X(PyObject* self) : m_self(self), m_x(0) {}
-    X(PyObject* self, int x) : m_self(self), m_x(x) {}
-    
-    handle<> self() { return handle<>(borrowed(m_self)); }
-    int get() { return m_x; }
-    void set(int x) { m_x = x; }
-
-    PyObject* m_self;
-    int x;
-};
-
-// specialize has_back_reference for X
-namespace boost { namespace python
-{
-  template <>
-  struct has_back_reference<X>
-  {
-     enum { value = true; }
-  }
-}}
-
-struct Y
-{
-    Y() : m_x(0) {}
-    Y(int x) : m_x(x) {}
-    int get() { return m_x; }
-    void set(int x) { m_x = x; }
-
-    int x;
-};
-
-boost::shared_ptr<Y> Y_self(boost::shared_ptr<Y> self) const { return self; }
-
-BOOST_PYTHON_MODULE(back_references)
-{
-    class_<X>("X")
-       .def(init<int>())
-       .def("self", &X::self)
-       .def("get", &X::get)
-       .def("set", &X::set)
-       ;
-
-    class_<Y, shared_ptr<Y> >("Y")
-       .def(init<int>())
-       .def("get", &Y::get)
-       .def("set", &Y::set)
-       .def("self", Y_self)
-       ;
-}
-
- The following Python session illustrates that x.self() - returns the same Python object on which it is invoked, while - y.self() must create a new Python object which refers to the - same Y instance. - -

Python code

-
->>> from back_references import *
->>> x = X(1)
->>> x2 = x.self()
->>> x2 is x
-1
->>> (x.get(), x2.get())
-(1, 1)
->>> x.set(10)
->>> (x.get(), x2.get())
-(10, 10)
->>>
->>>
->>> y = Y(2)
->>> y2 = y.self()
->>> y2 is y
-0
->>> (y.get(), y2.get())
-(2, 2)
->>> y.set(20)
->>> (y.get(), y2.get())
-(20, 20)
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/header.html b/doc/v2/header.html deleted file mode 100644 index 73d3aea6..00000000 --- a/doc/v2/header.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - Boost.Python - <{{header}}> - - - -
-

-

- -
-

Boost.Python

- -

Header <{{header}}>

-
-
- -

Contents

- -
-
Introduction - -
Macros - -
-
-
{{macro name}} -
- -
Values - -
-
-
{{value name}} -
- -
Types - -
-
-
{{type name}} -
- -
Classes - -
-
-
Class {{name}} - -
-
-
Class {{name}} synopsis - -
Class {{name}} - constructors and destructor - -
Class {{name}} comparison functions - -
Class {{name}} modifier functions - -
Class {{name}} observer functions - -
Class {{name}} static functions -
-
- -
Functions - -
-
-
{{function name}} -
- -
Objects - -
-
-
{{object name}} -
- -
Example(s) -
-
- -

Introduction

- -

{{Introductory text}} - -

Macros

- -

{{Macro specifications}} - -

Values

- -

{{Value specifications}} - -

Types

- -

{{Type specifications}} - -

Classes

- -

Class {{name}}

- -

{{class overview text}} - -

Class {{name}} synopsis

-
-namespace boost
-{
-    class {{name}}
-  {
-  };
-};
-
- -

Class {{name}} constructors and - destructor

-
-{{constructor}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
-
-{{destructor}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} comparison - functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} modifier - functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} observer - functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} static functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Functions

-
-
-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Objects

- -

{{Object specifications}} - -

Example(s)

- -

{{Example(s)}} - -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html deleted file mode 100644 index c830a6c9..00000000 --- a/doc/v2/implicit.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/implicit.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/implicit.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
Function Template - implicitly_convertible
-
-
- -
Example
-
-
- -

Introduction

- implicitly_convertible allows Boost.Python to implicitly - take advantage of a C++ implicit or explicit conversion when matching - Python objects to C++ argument types. - -

Functions

- -

Function template - implicitly_convertible

-
-template <class Source, class Target>
-void implicitly_convertible();
-
- - - - - - - - - - - - - - - - - - - - - -
- implicitly_convertible template parameters
-
ParameterDescription
SourceThe source type of the implicit conversion
TargetThe target type of the implicit conversion
- -
-
Requires: The declaration Target t(s);, where - s is of type Source, is valid.
- -
Effects: registers an rvalue from_python - converter to Target which can succeed for any - PyObject* p iff there exists any registered converter - which can produce Source rvalues
- -
Rationale: C++ users expect to be able to take advantage of - the same sort of interoperability in Python as they do in C++.
-
- -

Example

- -

C++ module definition

-
-#include <boost/python/class.hpp>
-#include <boost/python/implicit.hpp>
-#include <boost/python/module.hpp>
-
-using namespace boost::python;
-
-struct X
-{
-    X(int x) : v(x) {}
-    operator int() { return v; }
-    int v;
-};
-
-int x_value(X const& x)
-{
-    return x.v;
-}
-
-X make_x(int n) { return X(n); }
-
-BOOST_PYTHON_MODULE(implicit_ext)
-{
-    def("x_value", x_value);
-    def("make_x", make_x);
-
-    class_<X>("X", 
-        init<int>())
-        ;
-
-    implicitly_convertible<X,int>();
-    implicitly_convertible<int,X>();
-}
-
- -

Python code

-
->>> from implicit_ext import *
->>> x_value(X(42))
-42
->>> x_value(42)
-42
->>> x = make_x(X(42))
->>> x_value(x)
-42
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/index.html b/doc/v2/index.html deleted file mode 100644 index 6f5150fb..00000000 --- a/doc/v2/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - Automatic redirection failed, please go to ../index.html. - - - diff --git a/doc/v2/init.html b/doc/v2/init.html deleted file mode 100644 index 644a54e7..00000000 --- a/doc/v2/init.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/init.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Headers <boost/python/init.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
init-expressions
- -
Classes
- -
-
-
Class template init
- -
-
-
Class template - init synopsis
- -
Class init - constructors
- -
-
- -
Class template - optional
- -
-
-
Class template - optional synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/init.hpp> defines the interface for - exposing C++ constructors to Python as extension class - __init__ functions.

- -

init-expressions

- An init-expression is used to describe a family of - __init__ methods to be generated for an extension class, and - the result has the following properties: - -
-
-
docstring: An ntbs - whose value will bound to the method's __doc__ - attribute
- -
keywords: A keyword-expression which will be - used to name (a trailing subsequence of) the arguments to the - generated __init__ function(s).
- -
call policies: An instance of a model of CallPolicies.
- -
argument types: An MPL sequence of C++ argument types - which will be used to construct the wrapped C++ object. An init - expression has one or more - valid prefixes which are given by a sequence of - prefixes of its argument types.
-
-
- -

Classes

- -

Class template init<T1 = - unspecified, T2 = - unspecified,...Tn = - unspecified>

- -

A MPL sequence which - can be used to specify a family of one or more __init__ - functions. Only the last Ti supplied - may be an instantiation of optional<...>.

- -

Class template init - synopsis

-
-namespace boost { namespace python
-{
-  template <T1 = unspecified,...Tn = unspecified>
-  struct init
-  {
-      init(char const* doc = 0);
-      template <class Keywords> init(Keywords const& kw, char const* doc = 0);
-      template <class Keywords> init(char const* doc, Keywords const& kw);
-
-      template <class CallPolicies>
-      unspecified operator[](CallPolicies const& policies) const
-  };
-}}
-
- -

Class template init - constructors

-
-init(char const* doc = 0);
-template <class Keywords> init(Keywords const& kw, char const* doc = 0);
-template <class Keywords> init(char const* doc, Keywords const& kw);
-
- -
-
Requires: If supplied, doc is an ntbs. If supplied, kw is the - result of a
- -
Effects: The result is an init-expression whose - docstring is doc and whose keywords are - a reference to kw. If the first form is used, the - resulting expression's keywords are empty. The expression's - call policies are an instance of default_call_policies. - If Tn is optional<U1, U2,... - Um>, the - expression's valid prefixes are given by:
- -
-
- (T1, T2,...Tn-1), - (T1, T2,...Tn-1 - , U1), - (T1, T2,...Tn-1 - , U1, U2), - ...(T1, T2,...Tn-1 - , U1, U2,...Um). -
- Otherwise, the expression has one valid prefix given by the - the template arguments the user specified. -
-
- -

Class template init - observer functions

-
-template <class Policies>
-unspecified operator[](Policies const& policies) const
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Returns a new init-expression with all the same - properties as the init object except that its call - policies are replaced by a reference to - policies.
-
- -

Class template optional<T1 - = unspecified, T2 = - unspecified,...Tn = - unspecified>

- -

A MPL sequence which - can be used to specify the optional arguments to an __init__ - function.

- -

Class template - optional synopsis

-
-namespace boost { namespace python
-{
-  template <T1 = unspecified,...Tn = unspecified>
-  struct optional {};
-}}
-
- -

Example(s)

- -

Given the C++ declarations:

-
-class Y;
-class X
-{
- public:
-   X(int x, Y* y) : m_y(y) {}
-   X(double);
- private:
-   Y* m_y;
-};
-
- A corresponding Boost.Python extension class can be created with: -
-using namespace boost::python;
-
-class_<X>("X", "This is X's docstring.",
-          init<int,char const*>(args("x","y"), "X.__init__'s docstring")[
-                with_custodian_and_ward<1,3>()]
-          )
-   .def(init<double>())
-   ;
-
-
- Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/instance_holder.html b/doc/v2/instance_holder.html deleted file mode 100755 index 4fabad4a..00000000 --- a/doc/v2/instance_holder.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - Boost.Python - <boost/python/instance_holder.hpp> - - - - -
-

C++ Boost

- -
-

Boost.Python

- -

Header <boost/python/instance_holder.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class - instance_holder - -
-
-
Class - instance_holder synopsis - -
Class - instance_holder destructor - -
Class - instance_holder modifier functions - -
Class - instance_holder observer functions -
-
- -
Example -
-
- -

Introduction

- -

<boost/python/instance_holder.hpp> provides - class instance_holder, the base class for types - which hold C++ instances of wrapped classes. - -

Classes

- -

Class instance_holder

- -

instance_holder is an abstract base class whose - concrete derived classes hold C++ class instances within their - Python object wrappers. To allow multiple inheritance in Python - from C++ class wrappers, each such Python object contains a chain - of instance_holders. When an __init__ - function for a wrapped C++ class is invoked, a new - instance_holder instance is created and installed in - the Python object using its install() - function. Each concrete class derived from - instance_holder must provide a holds() - implementation which allows Boost.Python to query it for the - type(s) it is holding. In order to support the held type's wrapped - constructor(s), the class must also provide constructors that can - accept an initial PyObject* argument referring to the - owning Python object, and which forward the rest of their - arguments to the constructor of the held type. The initial - argument is needed to enable virtual function overriding in - Python, and may be ignored, depending on the specific - instance_holder subclass. - -

Class instance_holder - synopsis

-
-namespace boost { namespace python
-{
-  class instance_holder : noncopyable
-  {
-   public:
-      // destructor
-      virtual ~instance_holder();
-
-      // instance_holder modifiers
-      void install(PyObject* inst) throw();
-
-      // instance_holder observers
-      virtual void* holds(type_info) = 0;
-  };
-}}
-
- -

Class instance_holder - destructor

-
-virtual ~instance_holder();
-
- -
-
Effects: destroys the object -
- -

Class - instance_holder modifiers

-
-void install(PyObject* inst) throw();
-
- -
-
Requires: inst is a Python instance of a - wrapped C++ class type, or is a type derived from a wrapped C++ - class type. -
Effects: installs the new instance at the head of the - Python object's chain of held instances. -
Throws: nothing -
- -

Class instance_holder - observers

-
-virtual void* holds(type_info x) = 0;
-
- -
-
Returns: A pointer to an object of the type described - by x if *this contains such an object, - 0 otherwise. -
- -

Example

- -The following is a simplified version of the instance holder template -used by Boost.Python to wrap classes held by smart pointers: -
-template <class SmartPtr, class Value>
-struct pointer_holder : instance_holder
-{
-   // construct from the SmartPtr type
-   pointer_holder(SmartPtr p)
-       :m_p(p)
-
-   // Forwarding constructors for the held type
-   pointer_holder(PyObject*)
-       :m_p(new Value())
-   {
-   }
-
-   template<class A0>
-   pointer_holder(PyObject*,A0 a0)
-       :m_p(new Value(a0))
-   {
-   }
-
-   template<class A0,class A1>
-   pointer_holder(PyObject*,A0 a0,A1 a1)
-       :m_p(new Value(a0,a1))
-   {
-   }
-   ...
-
- private: // required holder implementation
-   void* holds(type_info dst_t)
-   {
-       // holds an instance of the SmartPtr type...
-       if (dst_t == python::type_id<SmartPtr>())
-           return &this->m_p;
-
-       // ...and an instance of the SmartPtr's element_type, if the
-       // pointer is non-null
-       return python::type_id<Value>() == dst_t ? &*this->m_p : 0;
-   }
-
- private: // data members
-   SmartPtr m_p;
-};
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All - Rights Reserved. - diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html deleted file mode 100644 index f6d80185..00000000 --- a/doc/v2/iterator.html +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/iterator.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/iterator.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - iterator
- -
-
-
Class - iterator synopsis
- -
Class template - iterator constructor
-
-
-
- -
-
Class template - iterators
- -
-
-
Class - iterators synopsis
- -
Class template - iterators nested types
- -
Class template - iterators static functions
-
-
-
-
- -
Functions
- -
-
-
range
-
-
- -
Examples
-
-
- -

Introduction

- -

<boost/python/iterator.hpp> provides types and - functions for creating Python - iterators from C++ Containers and Iterators. Note - that if your class_ supports random-access iterators, - implementing __getitem__ - (also known as the Sequence Protocol) may serve you better than using - this facility: Python will automatically create an iterator type for you - (see iter()), - and each access can be range-checked, leaving no possiblity of accessing - through an invalidated C++ iterator.

- -

Classes

- -

Class Template iterator

- -

Instances of iterator<C,P> hold a reference to a - callable Python object which, when invoked from Python, expects a single - argument c convertible to C and creates a - Python iterator that traverses [c.begin(), - c.end()). The optional CallPolicies P can be used to - control how elements are returned during iteration.

- -

In the table below, c is an instance of - Container.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Template ParameterRequirementsSemanticsDefault
Container[c.begin(),c.end()) is a valid Iterator range.The result will convert its argument to c and call - c.begin() and c.end() to acquire iterators. - To invoke Container's const - begin() and end() functions, make it - const.
NextPoliciesA default-constructible model of CallPolicies.Applied to the resulting iterators' next() - method.An unspecified model of CallPolicies which - always makes a copy of the result of deferencing the underlying C++ - iterator
- -

Class Template iterator - synopsis

-
-namespace boost { namespace python
-{
-  template <class Container
-             , class NextPolicies = unspecified>
-  struct iterator : object
-  {
-      iterator();
-  };
-}}
-
- -

Class Template iterator - constructor

-
-iterator()
-
- -
-
Effects:
- -
- Initializes its base class with the result of: -
-range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)
-
-
- -
Postconditions: this->get() points to a - Python callable object which creates a Python iterator as described - above.
- -
Rationale: Provides an easy way to create iterators for the - common case where a C++ class being wrapped provides - begin() and end().
-
- - -

Class Template - iterators

- -

A utility class template which provides a way to reliably call its - argument's begin() and end() member functions. - Note that there is no portable way to take the address of a member - function of a C++ standard library container, so - iterators<> can be particularly helpful when wrapping - them.

- -

In the table below, x is an instance of - C.

- - - - - - - - - - - - - - - - - - - -
Required Valid ExpressionType
x.begin()Convertible to C::const_iterator if C - is a const type; convertible to C::iterator - otherwise.
x.end()Convertible to C::const_iterator if C - is a const type; convertible to C::iterator - otherwise.
- -

Class Template iterators - synopsis

-
-namespace boost { namespace python
-{
-  template <class C>
-  struct iterators
-  {
-      typedef typename C::[const_]iterator iterator;
-      static iterator begin(C& x);
-      static iterator end(C& x);
-  };
-}}
-
-
- -

Class Template iterators nested - types

- If C is a const type, -
-typedef typename C::const_iterator iterator;
-
- Otherwise: -
-typedef typename C::iterator iterator;
-
- -

Class Template iterators static - functions

-
-static iterator begin(C&);
-
- -
-
Returns: x.begin()
-
-
-static iterator end(C&);
-
- -
-
Returns: x.end()
-
- - -

Functions

-
-template <class NextPolicies, class Target, class Accessor1, class Accessor2>
-object range(Accessor1 start, Accessor2 finish);
-
-template <class NextPolicies, class Accessor1, class Accessor2>
-object range(Accessor1 start, Accessor2 finish);
-
-template <class Accessor1, class Accessor2>
-object range(Accessor1 start, Accessor2 finish);
-
- -
-
Requires: NextPolicies is a - default-constructible model of CallPolicies.
- -
Effects:
- -
-
-
The first form creates a Python callable object which, when - invoked, converts its argument to a Target object - x, and creates a Python iterator which traverses - [bind(start,_1)(x)bind(finish,_1)(x)), - applying NextPolicies to the iterator's - next() function.
- -
The second form is identical to the first, except that - Target is deduced from Accessor1 as - follows:
- -
-
    -
  1. If Accessor1 is a function type, - Target is the type of its first argument.
  2. - -
  3. If Accessor1 is a data member pointer of the - form R (T::*), Target is - identical to T.
  4. - -
  5. If Accessor1 is a member function pointer of - the form - R (T::*)(arguments...)  - cv-opt, where cv-opt is an optional - cv-qualifier, Target is identical to - T.
  6. -
-
- -
The third form is identical to the second, except that - NextPolicies is an unspecified model of CallPolicies which - always makes a copy of the result of deferencing the underlying C++ - iterator
-
-
- -
Rationale: The use of boost::bind() allows C++ iterators - to be accessed through functions, member functions or data member - pointers. Customization of NextPolicies (e.g. using - return_internal_reference) - is useful when it is expensive to copy sequence elements of a wrapped - class type. Customization of Target is useful when - Accessor1 is a function object, or when a base class of - the intended target type would otherwise be deduced.
-
- -

Examples

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-
-#include <vector>
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(demo)
-{
-    class_<std::vector<double> >("dvec")
-        .def("__iter__", iterator<std::vector<double> >())
-        ;
-}
-
- A more comprehensive example can be found in: - -
-
libs/python/test/iterator.cpp
- -
libs/python/test/input_iterator.cpp
- -
libs/python/test/input_iterator.py
- -
-

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All - Rights Reserved.

-
-
- - - diff --git a/doc/v2/list.html b/doc/v2/list.html deleted file mode 100644 index f999996d..00000000 --- a/doc/v2/list.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/list.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/list.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class list
- -
-
-
Class list - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - list - type.

- -

Classes

- -

Class list

- -

Exposes the mapping - protocol of Python's built-in list type. The semantics - of the constructors and member functions defined below can be fully - understood by reading the TypeWrapper concept - definition. Since list is publicly derived from object, the public object - interface applies to list instances as well.

- -

Class list - synopsis

-
-namespace boost { namespace python
-{
-  class list : public object
-  {
-   public:
-      list(); // new list
-
-      template <class T>
-      explicit list(T const& sequence);
-
-      template <class T>
-      void append(T const& x);
-
-      template <class T>
-      long count(T const& value) const;
-
-      template <class T>
-      void extend(T const& x);
-
-      template <class T>
-      long index(T const& x) const;
-
-      template <class T>
-      void insert(object const& index, T const& x); // insert object before index
-
-      object pop(); // remove and return item at index (default last)
-      object pop(long index);
-      object pop(object const& index);
-
-      template <class T>
-      void remove(T const& value);
-
-      void reverse(); // reverse *IN PLACE*
-
-      void sort(); //  sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
-
-      template <class T>
-      void sort(T const& value);
-  };
-}}
-
- -

Example

-
-using namespace boost::python;
-
-// Return the number of zeroes in the list
-long zeroes(list l)
-{
-   return l.count(0);
-}
-
- -

Revised 1 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/long.html b/doc/v2/long.html deleted file mode 100644 index a9683fd3..00000000 --- a/doc/v2/long.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/long.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/long.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class long_
- -
-
-
Class long_ - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - long - integer type.

- -

Classes

- -

Class long_

- -

Exposes the numeric type - protocol of Python's built-in long type. The semantics - of the constructors and member functions defined below can be fully - understood by reading the TypeWrapper concept - definition. Since long_ is publicly derived from object, the public object - interface applies to long_ instances as well.

- -

Class long_ - synopsis

-
-namespace boost { namespace python
-{
-  class long_ : public object
-  {
-   public:
-      long_(); // new long_
-
-      template <class T>
-      explicit long_(T const& rhs);
-
-      template <class T, class U>
-      long_(T const& rhs, U const& base);
-  };
-}}
-
- -

Example

-
-namespace python = boost::python;
-
-// compute a factorial without overflowing
-python::long_ fact(long n)
-{
-   if (n == 0)
-      return python::long_(1);
-   else
-      return n * fact(n - 1);
-}
-
- -

Revised 1 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html deleted file mode 100755 index 9ccccd7a..00000000 --- a/doc/v2/lvalue_from_pytype.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/lvalue_from_python.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/lvalue_from_pytype.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - lvalue_from_pytype
- -
-
-
Class Template - lvalue_from_pytype synopsis
- -
Class Template - lvalue_from_pytype constructor
-
-
-
- -
-
Class Template - extract_identity
- -
-
-
Class Template - extract_identity synopsis
- -
Class Template - extract_identity static functions
-
-
- -
Class Template - extract_member
- -
-
-
Class Template - extract_member synopsis
- -
Class Template - extract_member static functions
-
-
-
-
- -
Example
-
-
- -

Introduction

- <boost/python/lvalue_from_pytype.hpp> supplies a - facility for extracting C++ objects from within Python instances of a - given type. This is typically useful for dealing with "traditional" - Python extension types. - -

Classes

- -

Class template - lvalue_from_pytype

- -

Class template lvalue_from_pytype will register - from_python converters which, given an object of the given Python type, - can extract references and pointers to a particular C++ type. Its - template arguments are:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- lvalue_from_pytype Requirements
- In the table below, x denotes an object of type - PythonObject& -
ParameterRequirementsSemantics
Extractora model of Extractor whose execute - function returns a reference type.Extracts the lvalue from the Python object once its type has been - confirmed
python_typeA compile-time constant PyTypeObject*The Python type of instances convertible by this converter. - Python subtypes are also convertible.
- -

Class template - lvalue_from_pytype synopsis

-
-namespace boost { namespace python
-{
-   template <class Extractor, PyTypeObject const* python_type>
-   struct lvalue_from_pytype
-   {
-       lvalue_from_pytype();
-   };
-}}
-
- -

Class template - lvalue_from_pytype constructor

-
-lvalue_from_pytype();
-
- -
-
Effects: Registers converters which can convert Python - objects of the given type to lvalues of the type returned by - Extractor::execute.
-
- -

Class template - extract_identity

- -

extract_identity is a model of Extractor which can be used in the - common case where the C++ type to be extracted is the same as the Python - object type.

- -

Class template - extract_identity synopsis

-
-namespace boost { namespace python
-{
-   template <class InstanceType>
-   struct extract_identity
-   {
-      static InstanceType& execute(InstanceType& c);
-   };
-}}
-
- -

Class template - extract_identity static functions

-
-InstanceType& execute(InstanceType& c);
-
- -
-
Returns: c
-
- -

Class template - extract_member

- -

extract_member is a model of Extractor which can be used in the - common case in the common case where the C++ type to be extracted is a - member of the Python object.

- -

Class template - extract_member synopsis

-
-namespace boost { namespace python
-{
-   template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
-   struct extract_member
-   {
-      static MemberType& execute(InstanceType& c);
-   };
-}}
-
- -

Class template - extract_member static functions

-
-static MemberType& execute(InstanceType& c);
-
- -
-
Returns: c.*member
-
- -

Example

- This example presumes that someone has implemented the standard noddy example - module from the Python documentation, and we want to build a module - which manipulates Noddys. Since - noddy_NoddyObject is so simple that it carries no - interesting information, the example is a bit contrived: it assumes you - want to keep track of one particular object for some reason. This module - would have to be dynamically linked to the module which defines - noddy_NoddyType. - -

C++ module definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/handle.hpp>
-#include <boost/python/borrowed.hpp>
-#include <boost/python/lvalue_from_pytype.hpp>
-
-// definition lifted from the Python docs
-typedef struct {
-   PyObject_HEAD
-} noddy_NoddyObject;
-
-using namespace boost::python;
-static handle<noddy_NoddyObject> cache;
-
-bool is_cached(noddy_NoddyObject* x)
-{
-   return x == cache.get();
-}
-
-void set_cache(noddy_NoddyObject* x)
-{
-   cache = handle<noddy_NoddyObject>(borrowed(x));
-}
-
-BOOST_PYTHON_MODULE(noddy_cache)
-{
-   def("is_cached", is_cached);
-   def("set_cache", set_cache);
-
-   // register Noddy lvalue converter
-   lvalue_from_pytype<extract_identity<noddy_NoddyObject>,&noddy_NoddyType>();
-}
-
- -

Python code

-
->>> import noddy
->>> n = noddy.new_noddy()
->>> import noddy_cache
->>> noddy_cache.is_cached(n)
-0
->>> noddy_cache.set_cache(n)
->>> noddy_cache.is_cached(n)
-1
->>> noddy_cache.is_cached(noddy.new_noddy())
-0
-
- -

Revised - - 20 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html deleted file mode 100644 index 592eb37d..00000000 --- a/doc/v2/make_function.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/make_function.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/make_function.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
make_function
- -
make_constructor
-
-
- -
Example
-
-
- -

Introduction

- -

make_function() and - make_constructor() are - the functions used internally by def() and class_<>::def() to produce Python - callable objects which wrap C++ functions and member functions.

- -

Functions

-
-template <class F>
-object make_function(F f)
-
-template <class F, class Policies>
-object make_function(F f, Policies const& policies)
-
-template <class F, class Policies, class Keywords>
-object make_function(F f, Policies const& policies, Keywords const& keywords)
-
- -
-
Requires: F is a function pointer or member - function pointer type. If policies are supplied, it must - be a model of CallPolicies. If - kewords are supplied, it must be the result of a keyword-expression - specifying no more arguments than the arity of f.
- -
Effects: Creates a Python callable object which, when called - from Python, converts its arguments to C++ and calls f. If - F is a pointer-to-member-function type, the target object - of the function call (*this) will be taken from the first - Python argument, and subsequent Python arguments will be used as the - arguments to f. If policies are supplied, it - will be applied to the function as described here. If keywords are - supplied, the keywords will be applied in order to the final - arguments of the resulting function.
- -
Returns: An instance of object which holds the new Python - callable object.
-
-
-template <class T, class ArgList, class Generator>
-object make_constructor();
- 
-template <class ArgList, class Generator, class Policies>
-object make_constructor(Policies const& policies)
-
- -
-
Requires: T is a class type. - Policies is a model of CallPolicies. ArgList is an MPL sequence of C++ argument - types (A1, A2,... AN) such that if - a1, a2... aN are objects of type - A1, A2,... AN respectively, the expression new - Generator::apply<T>::type(a1, a2... aN) - is valid. Generator is a model of HolderGenerator.
- -
Effects: Creates a Python callable object which, when called - from Python, expects its first argument to be a Boost.Python extension - class object. It converts its remaining its arguments to C++ and passes - them to the constructor of a dynamically-allocated - Generator::apply<T>::type object, which is then - installed in the extension class object. In the second form, the - policies are applied to the arguments and result (None) - of the Python callable object
- -
Returns: An instance of object which holds the new Python - callable object.
-
- -

Example

- -

C++ function exposed below returns a callable object wrapping one of - two functions.

-
-#include <boost/python/make_function.hpp>
-#include <boost/python/module.hpp>
-
-char const* foo() { return "foo"; }
-char const* bar() { return "bar"; }
-
-using namespace boost::python;
-object choose_function(bool selector)
-{
-    if (selector)
-        return boost::python::make_function(foo);
-    else
-        return boost::python::make_function(bar);
-}
-
-BOOST_PYTHON_MODULE(make_function_test)
-{
-    def("choose_function", choose_function);
-}
-
- It can be used this way in Python: -
->>> from make_function_test import *
->>> f = choose_function(1)
->>> g = choose_function(0)
->>> f()
-'foo'
->>> g()
-'bar'
-
- -

- - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html deleted file mode 100644 index 6b94a4d4..00000000 --- a/doc/v2/manage_new_object.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/manage_new_object.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/manage_new_object.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - manage_new_object
- -
-
-
Class - manage_new_object synopsis
- -
Class - manage_new_object metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - manage_new_object

- -

manage_new_object is a model of ResultConverterGenerator - which can be used to wrap C++ functions which return a pointer to an - object allocated with a new-expression, and expect the caller to - take responsibility for deleting that object.

- -

Class - manage_new_object synopsis

-
-namespace boost { namespace python
-{
-    struct manage_new_object
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - manage_new_object metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U* for some - U.
- -
Returns: typedef to_python_indirect<T> - type;
-
- -

Example

- -

In C++:

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/manage_new_object.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-
-struct Foo {
-   Foo(int x) : x(x){}
-   int get_x() { return x; }
-   int x;
-};
-
-Foo* make_foo(int x) { return new Foo(x); }
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    def("make_foo", make_foo, return_value_policy<manage_new_object>())
-    class_<Foo>("Foo")
-        .def("get_x", &Foo::get_x)
-        ;
-}
-
- In Python: -
->>> from my_module import *
->>> f = make_foo(3)     # create a Foo object
->>> f.get_x()
-3
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/module.html b/doc/v2/module.html deleted file mode 100644 index bb041f32..00000000 --- a/doc/v2/module.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - Boost.Python - <boost/python/module.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/module.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Macros - -
-
-
BOOST_PYTHON_MODULE -
- -
Example(s) -
-
- -

Introduction

- -

This header provides the basic facilities needed to create a - Boost.Python extension module. - -

Macros

- -

BOOST_PYTHON_MODULE(name) - is used to declare Python - module initialization functions. The name argument must - exactly match the name of the module to be initialized, and must conform to - Python's identifier naming - rules. Where you would normally write -

-extern "C" void initname()
-{
-   ...
-}
-
- Boost.Python modules should be initialized with -
-BOOST_PYTHON_MODULE(name)
-{
-   ...
-}
-
- -This macro generates two functions in the scope where it is used: -extern "C" void initname(), -and void init_module_name(), whose body must -follow the macro invocation. init_name passes -init_module_name to handle_exception() so -that any C++ exceptions generated are safely processeed. During the -body of init_name, the current scope refers to the module -being initialized. - -

Example(s)

- -

C++ module definition: -

-#include <boost/python/module.hpp>
-
-BOOST_PYTHON_MODULE(xxx)
-{
-    throw "something bad happened"
-}
-
- -Interactive Python: -
->>> import xxx
-Traceback (most recent call last):
-  File "", line 1, in ?
-RuntimeError: Unidentifiable C++ Exception
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/numeric.html b/doc/v2/numeric.html deleted file mode 100644 index a1d59ca9..00000000 --- a/doc/v2/numeric.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/numeric.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/numeric.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class array
- -
-
-
Class array - synopsis
- -
Class array - observer functions
- -
Class array - static functions
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - array - type.

- -

Classes

- -

Class array

- -

Provides access to the array types of Numerical Python's Numeric and NumArray modules. With - the exception of the functions documented below, the semantics of the constructors and - member functions defined below can be fully understood by reading the TypeWrapper concept - definition. Since array is publicly derived from object, the public object - interface applies to array instances as well.

- -

The default behavior is to use - Numeric.ArrayType as the associated Python type if the - Numeric module is installed in the default location. - Otherwise it falls back to use numarray.NDArray. If neither - extension module is installed, conversions to arguments of type - numeric::array will cause overload resolution to reject the - overload, and other attempted uses of numeric::array will raise an appropriate Python exception. - The associated Python type can be set manually using the set_module_and_type(...) static - function.

- -

Class array - synopsis

-
-namespace boost { namespace python { namespace numeric
-{
-   class array : public object
-   {
-    public:
-      object astype();
-      template <class Type>
-      object astype(Type const& type_);
-
-      template <class Type>
-      object new_(Type const& type_) const;
-
-      template <class Sequence> 
-      void resize(Sequence const& x);
-      void resize(long x1);
-      void resize(long x1, long x2);
-      ...
-      void resize(long x1, long x2,...long xn);
-
-      template <class Sequence> 
-      void setshape(Sequence const& x);
-      void setshape(long x1);
-      void setshape(long x1, long x2);
-      ...
-      void setshape(long x1, long x2,...long xn);
-
-      template <class Indices, class Values>
-      void put(Indices const& indices, Values const& values);
-
-      template <class Sequence>
-      object take(Sequence const& sequence, long axis = 0);
-
-      template <class File>
-      void tofile(File const& f) const;
-
-      object factory();
-      template <class Buffer>
-      object factory(Buffer const&);
-      template <class Buffer, class Type>
-      object factory(Buffer const&, Type const&);
-      template <class Buffer, class Type, class Shape>
-      object factory(Buffer const&, Type const&, Shape const&, bool copy = true, bool savespace = false);
-      template <class Buffer, class Type, class Shape>
-      object factory(Buffer const&, Type const&, Shape const&, bool copy, bool savespace, char typecode);
-
-      template <class T1>
-      explicit array(T1 const& x1);
-      template <class T1, class T2>
-      explicit array(T1 const& x1, T2 const& x2);
-      ...
-      template <class T1, class T2,...class Tn>
-      explicit array(T1 const& x1, T2 const& x2,...Tn const& xn);
-
-      static void set_module_and_type();
-      static void set_module_and_type(char const* package_path = 0, char const* type_name = 0);
-
-      object argmax(long axis=-1);
-
-      object argmin(long axis=-1);
-
-      object argsort(long axis=-1);
-
-      void byteswap();
-
-      object copy() const;
-
-      object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const;
-
-      void info() const;
-
-      bool is_c_array() const;
-      bool isbyteswapped() const;
-      void sort();
-      object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const;
-      object type() const;
-      char typecode() const;
-      
-      object getflat() const;
-      long getrank() const;
-      object getshape() const;
-      bool isaligned() const;
-      bool iscontiguous() const;
-      long itemsize() const;
-      long nelements() const;
-      object nonzero() const;
-   
-      void ravel();
-   
-      object repeat(object const& repeats, long axis=0);
-   
-      void setflat(object const& flat);
-   
-      void swapaxes(long axis1, long axis2);
-   
-      str tostring() const;
-   
-      void transpose(object const& axes = object());
-   
-      object view() const;
-  };
-}}}
-
- -

Class array observer - functions

-
-object factory();
-template <class Buffer>
-object factory(Buffer const&);
-template <class Buffer, class Type>
-object factory(Buffer const&, Type const&);
-template <class Buffer, class Type, class Shape>
-object factory(Buffer const&, Type const&, Shape const&, bool copy = true, bool savespace = false);
-template <class Buffer, class Type, class Shape>
-object factory(Buffer const&, Type const&, Shape const&, bool copy, bool savespace, char typecode);
-
- These functions map to the underlying array type's array() - function family. They are not called "array" because of the - C++ limitation that you can't define a member function with the same name - as its enclosing class. -
-template <class Type>
-object new_(Type const&) const;
-
- This function maps to the underlying array type's new() - function. It is not called "new" because that is a keyword - in C++. - -

Class array static - functions

-
-static void set_module_and_type(char const* package_path, char const* type_name);
-static void set_module_and_type();
-
- -
-
Requires: package_path and - type_name, if supplied, is an ntbs.
- -
Effects: The first form sets the package path of the module - which supplies the type named by type_name to - package_path. The second form restores the default search behavior. The associated Python - type will be searched for only the first time it is needed, and - thereafter the first time it is needed after an invocation of - set_module_and_type.
-
- -

Example

-
-#include <boost/python/numeric.hpp>
-#include <boost/python/tuple.hpp>
-
-// sets the first element in a 2d numeric array
-void set_first_element(numeric::array& y, double value)
-{
-    y[make_tuple(0,0)] = value;
-}
-
- -

Revised 03 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/object.html b/doc/v2/object.html deleted file mode 100644 index 93b9027e..00000000 --- a/doc/v2/object.html +++ /dev/null @@ -1,931 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/object.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/object.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Types
- -
-
-
slice_nil
-
-
- -
Classes
- -
-
-
Class - const_attribute_policies
- -
-
-
Class - const_attribute_policies synopsis
- -
Class - const_attribute_policies static functions
-
-
- -
Class - attribute_policies
- -
-
-
Class - attribute_policies synopsis
- -
Class - attribute_policies static functions
-
-
- -
Class - const_item_policies
- -
-
-
Class - const_item_policies synopsis
- -
Class - const_item_policies static functions
-
-
- -
Class - item_policies
- -
-
-
Class - item_policies synopsis
- -
Class - item_policies static functions
-
-
- -
Class - const_slice_policies
- -
-
-
Class - const_slice_policies synopsis
- -
Class - const_slice_policies static functions
-
-
- -
Class - slice_policies
- -
-
-
Class - slice_policies synopsis
- -
Class - slice_policies static functions
-
-
- -
Class - object_operators
- -
-
-
Class - object_operators synopsis
- -
Class - object_operators observer functions
-
-
- -
Class object
- -
-
-
Class object - synopsis
- -
Class object - constructors and destructor
- -
Class template - object modifier functions
- -
Class template - object observer functions
-
-
- -
Class template - proxy
- -
-
-
Class template - proxy synopsis
- -
Class template - proxy modifier functions
- -
Class template - proxy observer functions
-
-
-
-
- -
Functions
- -
-
-
del
- -
comparisons
- -
binary operations
- -
assignment operations
-
- -
-
operators
-
-
- -
Example
-
-
- -

Introduction

- -

Exposes the generic Python object wrapper class object, - and related classes. In order to avoid some potenential problems with - argument-dependent lookup and the generalized operators defined on - object, all these facilities are defined in - namespace boost::python::api, and object - is imported into namespace boost::python with a - using-declaration.

- -

Types

- -

-
-enum slice_nil { _ };
-
- A type that can be used to get the effect of leaving out an index in a - Python slice expression: -
->>> x[:-1]
-
- C++ equivalent: -
-x.slice(_,-1)
-
- -

Classes

- - -

Class - const_attribute_policies

- -

The policies which are used for proxies representing an attribute - access to a const object.

- -

Class - const_attribute_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct const_attribute_policies
-  {
-      typedef char const* key_type;
-      static object get(object const& target, char const* key);
-  };
-}}}
-
- -

Class - const_attribute_policies static functions

-
-static object get(object const& target, char const* key);
-
- -
-
Requires: key is an ntbs.
- -
Effects: accesses the attribute of target named - by key.
- -
Returns: An object managing the result of the - attribute access.
- -
Throws: error_already_set if a - Python exception is raised.
-
- -

Class - attribute_policies

- -

The policies which are used for proxies representing an attribute - access to a mutable object.

- -

Class - attribute_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct attribute_policies : const_attribute_policies
-  {
-      static object const& set(object const& target, char const* key, object const& value);
-      static void del(object const&target, char const* key);
-  };
-}}}
-
- -

Class - attribute_policies static functions

-
-static object const& set(object const& target, char const* key, object const& value);
-
- -
-
Requires: key is an ntbs.
- -
Effects: sets the attribute of target named by - key to value.
- -
Throws: error_already_set if a - Python exception is raised.
-
-
-static void del(object const&target, char const* key);
-
- -
-
Requires: key is an ntbs.
- -
Effects: deletes the attribute of target named - by key.
- -
Throws: error_already_set if a - Python exception is raised.
-
- - - -

Class - const_item_policies

- -

The policies which are used for proxies representing an item access - (via the Python bracket operators []) to a - const object.

- -

Class - const_item_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct const_item_policies
-  {
-      typedef object key_type;
-      static object get(object const& target, object const& key);
-  };
-}}}
-
- -

Class - const_item_policies static functions

-
-static object get(object const& target, object const& key);
-
- -
-
Effects: accesses the item of target specified - by key.
- -
Returns: An object managing the result of the - item access.
- -
Throws: error_already_set if a - Python exception is raised.
-
- -

Class - item_policies

- -

The policies which are used for proxies representing an item access - (via the Python bracket operators []) to a mutable - object.

- -

Class - item_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct item_policies : const_item_policies
-  {
-      static object const& set(object const& target, object const& key, object const& value);
-      static void del(object const& target, object const& key);
-  };
-}}}
-
- -

Class - item_policies static functions

-
-static object const& set(object const& target, object const& key, object const& value);
-
- -
-
Effects: sets the item of target specified by - key to value.
- -
Throws: error_already_set if a - Python exception is raised.
-
-
-static void del(object const& target, object const& key);
-
- -
-
Effects: deletes the item of target specified - by key.
- -
Throws: error_already_set if a - Python exception is raised.
-
- - - -

Class - const_slice_policies

- -

The policies which are used for proxies representing an slice access - (via the Python slice notation - [x:y]) to a - const object.

- -

Class - const_slice_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct const_slice_policies
-  {
-      typedef std::pair<handle<>, handle<> > key_type;
-      static object get(object const& target, key_type const& key);
-  };
-}}}
-
- -

Class - const_slice_policies static functions

-
-static object get(object const& target, key_type const& key);
-
- -
-
Effects: accesses the slice of target specified - by key.
- -
Returns: An object managing the result of the - slice access.
- -
Throws: error_already_set if a - Python exception is raised.
-
- -

Class - slice_policies

- -

The policies which are used for proxies representing an slice access - to a mutable object.

- -

Class - slice_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct slice_policies : const_slice_policies
-  {
-      static object const& set(object const& target, key_type const& key, object const& value);
-      static void del(object const& target, key_type const& key);
-  };
-}}}
-
- -

Class - slice_policies static functions

-
-static object const& set(object const& target, key_type const& key, object const& value);
-
- -
-
Effects: sets the slice of target specified by - key to value.
- -
Throws: error_already_set if a - Python exception is raised.
-
-
-static void del(object const& target, key_type const& key);
-
- -
-
Effects: deletes the slice of target specified - by key.
- -
Throws: error_already_set if a - Python exception is raised.
-
- - -

Class template - object_operators<U>

- -

This is the base class of object and its - proxy template used to supply common interface: member - functions, and operators which must be defined within the class body. Its - template parameter U is expected to be a class derived from - object_operators<U>. In practice users should never - use this class directly, but it is documented here because it supplies - important interface to object and its proxies.

- -

Class template - object_operators synopsis

-
-namespace boost { namespace python { namespace api
-{
-  template <class U>
-  class object_operators
-  {
-   public:
-      // function call
-      //
-      object operator()() const;
-
-      template <class A0>
-      object operator()(A0 const&) const;
-      template <class A0, class A1>
-      object operator()(A0 const&, A1 const&) const;
-      ...
-      template <class A0, class A1,...class An>
-      object operator()(A0 const&, A1 const&,...An const&) const;
-
-      // truth value testing
-      //
-      typedef unspecified bool_type;
-      operator bool_type() const;
-
-      // Attribute access
-      //
-      proxy<const_object_attribute> attr(char const*) const;
-      proxy<object_attribute> attr(char const*);
-
-      // item access
-      //
-      template <class T>
-      proxy<const_object_item> operator[](T const& key) const;
-    
-      template <class T>
-      proxy<object_item> operator[](T const& key);
-
-      // slicing
-      //
-      template <class T, class V>
-      proxy<const_object_slice> slice(T const& start, V const& end) const
-    
-      template <class T, class V>
-      proxy<object_slice> slice(T const& start, V const& end);
-  };
-}}}
-
- -

Class template - object_operators observer functions

-
-object operator()() const;
-template <class A0>
-object operator()(A0 const&) const;
-template <class A0, class A1>
-object operator()(A0 const&, A1 const&) const;
-...
-template <class A0, class A1,...class An>
-object operator()(A0 const& a1, A1 const& a2,...An const& aN) const;
-
- -
-
Effects: - call<object>(object(*static_cast<U*>(this)).ptr(), a1, - a2,...aN)
-
-
-operator bool_type() const;
-
- -
-
Effects: Tests truth value of *this.
- -
Returns: - call<object>(object(*static_cast<U*>(this)).ptr(), a1, - a2,...aN)
-
-
-proxy<const_object_attribute> attr(char const* name) const;
-proxy<object_attribute> attr(char const* name);
-
- -
-
Requires: name is an ntbs.
- -
Effects: accesses the named attribute of - *this.
- -
Returns: a proxy object which binds - object(*static_cast<U*>(this)) as its target, and - name as its key.
-
-
-template <class T>
-proxy<const_object_item> operator[](T const& key) const;
-template <class T>
-proxy<object_item> operator[](T const& key);
-
- -
-
Effects: accesses the item of *this indicated - by key.
- -
Returns: a proxy object which binds - object(*static_cast<U*>(this)) as its target, and - object(key) as its key.
-
-
-template <class T, class V>
-proxy<const_object_slice> slice(T const& start; start, V const& finish) const
-template <class T, class V>
-proxy<object_slice> slice(T const& start; start, V const& finish);
-
- -
-
Effects: accesses the slice of *this indicated - by std::make_pair(object(start), object(finish)).
- -
Returns: a proxy object which binds - object(*static_cast<U*>(this)) as its target, and - std::make_pair(object(start), object(finish)) as its - key.
-
- - -

Class object

- -

The intention is that object acts as much like a - Python variable as possible. Thus expressions you'd expect to work - in Python should generally work in the same way from C++. Most of - object's interface is provided by its base class - object_operators<object>, - and the free functions defined in this - header. -

- -

Class object - synopsis

-
-namespace boost { namespace python { namespace api
-{
-  class object : public object_operators<object>
-  {
-   public:
-      object();
-
-      object(object const&);
-      
-      template <class T>
-      explicit object(T const& x);
-
-      ~object();
-
-      object& operator=(object const&); 
-
-      PyObject* ptr() const;
-  };
-}}}
-
- -

Class object - constructors and destructor

-
-object();
-
- -
-
Effects: Constructs an object managing a reference to the - Python None object.
- -
Throws: nothing.
-
-
-template <class T>
-explicit object(T const& x);
-
- -
-
Effects: converts x to python and manages a - reference to it.
- -
Throws: error_already_set and sets a Python - TypeError exception if no such conversion is - possible.
-
-
-~object();
-
- -
-
Effects: decrements the reference count of the - internally-held object.
-
- -

Class object - modifiers

-
-object& operator=(object const& rhs); 
-
- -
-
Effects: increments the reference count of the object held - by rhs and decrements the reference count of the object - held by *this.
-
- -

Class object - observers

-
-PyObject* ptr() const;
-
- -
-
Returns: a pointer to the internally-held Python - object.
-
- - -

Class template proxy

- -

This template is instantiated with various Policies described in this - document in order to implement attribute, item, and slice access for - object. It stores an object of type - Policies::key_type.

- -

Class template proxy - synopsis

-
-namespace boost { namespace python { namespace api
-{
-  template <class Policies>
-  class proxy : public object_operators<proxy<Policies> >
-  {
-   public:
-      operator object() const;
-
-      proxy const& operator=(proxy const&) const;
-      template <class T>
-      inline proxy const& operator=(T const& rhs) const;
-      
-      void del() const;
-
-      template <class R>
-      proxy operator+=(R const& rhs);
-      template <class R>
-      proxy operator-=(R const& rhs);
-      template <class R>
-      proxy operator*=(R const& rhs);
-      template <class R>
-      proxy operator/=(R const& rhs);
-      template <class R>
-      proxy operator%=(R const& rhs);
-      template <class R>
-      proxy operator<<=(R const& rhs);
-      template <class R>
-      proxy operator>>=(R const& rhs);
-      template <class R>
-      proxy operator&=(R const& rhs);
-      template <class R>
-      proxy operator|=(R const& rhs);
-  };
-}}}
-
- -

Class template proxy - observer functions

-
-operator object() const;
-
- -
-
Effects: applies - Policies::get(target, key - ) with the proxy's target and key objects.
-
- -

Class template proxy - modifier functions

-
-proxy const& operator=(proxy const& rhs) const;
-template <class T>
-inline proxy const& operator=(T const& rhs) const;
-
- -
-
Effects: - Policies::set(target, key - , object(rhs)) with the proxy's target and key - objects.
-
-
-template <class R>
-proxy operator+=(R const& rhs);
-template <class R>
-proxy operator-=(R const& rhs);
-template <class R>
-proxy operator*=(R const& rhs);
-template <class R>
-proxy operator/=(R const& rhs);
-template <class R>
-proxy operator%=(R const& rhs);
-template <class R>
-proxy operator<<=(R const& rhs);
-template <class R>
-proxy operator>>=(R const& rhs);
-template <class R>
-proxy operator&=(R const& rhs);
-template <class R>
-proxy operator|=(R const& rhs);
-
- -
-
Effects: for a given operator@=, - object(*this) @= rhs;
-
Returns: *this
-
-
-void del() const;
-
- -
-
Effects: - Policies::del(target, key - ) with the proxy's target and key objects.
-
- - -

Functions

-
-template <class T>
-void del(proxy<T> const& x);
-
- -
-
Effects: x.del()
-
-
-
-template<class L,class R> bool operator>(L const&l,R const&r);
-template<class L,class R> bool operator>=(L const&l,R const&r);
-template<class L,class R> bool operator<(L const&l,R const&r);
-template<class L,class R> bool operator<=(L const&l,R const&r);
-template<class L,class R> bool operator==(L const&l,R const&r);
-template<class L,class R> bool operator!=(L const&l,R const&r);
-
- -
-
Effects: returns the result of applying the operator to - object(l) and object(r), respectively, in - Python.
-
-
-
-template<class L,class R> object operator+(L const&l,R const&r);
-template<class L,class R> object operator-(L const&l,R const&r);
-template<class L,class R> object operator*(L const&l,R const&r);
-template<class L,class R> object operator/(L const&l,R const&r);
-template<class L,class R> object operator%(L const&l,R const&r);
-template<class L,class R> object operator<<(L const&l,R const&r);
-template<class L,class R> object operator>>(L const&l,R const&r);
-template<class L,class R> object operator&(L const&l,R const&r);
-template<class L,class R> object operator^(L const&l,R const&r);
-template<class L,class R> object operator|(L const&l,R const&r);
-
- -
-
Effects: returns the result of applying the operator to - object(l) and object(r), respectively, in - Python.
-
-
-
-template<class R> object& operator+=(object&l,R const&r);
-template<class R> object& operator-=(object&l,R const&r);
-template<class R> object& operator*=(object&l,R const&r);
-template<class R> object& operator/=(object&l,R const&r);
-template<class R> object& operator%=(object&l,R const&r);
-template<class R> object& operator<<=(object&l,R const&r)
-template<class R> object& operator>>=(object&l,R const&r);
-template<class R> object& operator&=(object&l,R const&r);
-template<class R> object& operator^=(object&l,R const&r);
-template<class R> object& operator|=(object&l,R const&r);
-
- -
-
Effects: assigns to l the result of applying the - corresponding Python inplace operator to l and - object(r), respectively.
- -
Returns: l.
-
- -

Example

- Python code: -
-def sum_items(seq):
-   result = 0
-   for x in seq:
-      result += x
-   return result
-
- C++ version: -
-object sum_items(object seq)
-{
-   object result = object(0);
-   for (int i = 0; i < seq.attr("__len__")(); ++i)
-      result += seq[i];
-   return result;
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/operators.html b/doc/v2/operators.html deleted file mode 100755 index 45f502a6..00000000 --- a/doc/v2/operators.html +++ /dev/null @@ -1,888 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/operators.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/operators.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class - self_ns::self_t
- -
-
-
Class self_t - synopsis
- -
Class self_t - inplace operators
- -
Class - self_t comparison functions
- -
Class self_t - non-member operations
- -
Class - self_t unary operations
- -
Class - self_t value operations
-
-
- -
Class template - other
- -
-
-
Class other - synopsis
-
-
- -
Class template - operator_
- -
-
-
Class - operator_ synopsis
-
-
-
-
- -
Objects
- -
-
-
self
-
-
- -
Examples
-
-
- -

Introduction

- -

<boost/python/operators.hpp> provides types and - functions for automatically generating Python special methods - from the corresponding C++ constructs. Most of these constructs are - operator expressions, hence the name. To use the facility, substitute the - self object for an object of the - class type being wrapped in the expression to be exposed, and pass the - result to class_<>::def(). Much of - what is exposed in this header should be considered part of the - implementation, so is not documented in detail here.

- -

Classes

- -

Class self_ns::self_t

- -

self_ns::self_t is the actual type of the self object. The library isolates - self_t in its own namespace, self_ns, in order - to prevent the generalized operator templates which operate on it from - being found by argument-dependent lookup in other contexts. This should - be considered an implementation detail, since users should never have to - mention self_t directly.

- -

Class self_ns::self_t - synopsis

-
-namespace boost { namespace python { namespace self_ns {
-{
-   unspecified-type-declaration self_t;
-
-   // inplace operators
-   template <class T> operator_<unspecified> operator+=(self_t, T);
-   template <class T> operator_<unspecified> operator-=(self_t, T);
-   template <class T> operator_<unspecified> operator*=(self_t, T);
-   template <class T> operator_<unspecified> operator/=(self_t, T);
-   template <class T> operator_<unspecified> operator%=(self_t, T);
-   template <class T> operator_<unspecified> operator>>=(self_t, T);
-   template <class T> operator_<unspecified> operator<<=(self_t, T);
-   template <class T> operator_<unspecified> operator&=(self_t, T);
-   template <class T> operator_<unspecified> operator^=(self_t, T);
-   template <class T> operator_<unspecified> operator|=(self_t, T);
-
-   // comparisons
-   template <class L, class R> operator_<unspecified> operator==(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator!=(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator<(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator>(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator<=(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator>=(L const&, R const&);
-
-   // non-member operations
-   template <class L, class R> operator_<unspecified> operator+(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator-(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator*(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator/(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator%(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator>>(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator<<(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator&(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator^(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator|(L const&, R const&);
-   template <class L, class R> operator_<unspecified> pow(L const&, R const&);
-
-   // unary operations
-   operator_<unspecified> operator-(self_t);
-   operator_<unspecified> operator+(self_t);
-   operator_<unspecified> operator~(self_t);
-
-   // value operations
-   operator_<unspecified> int_(self_t);
-   operator_<unspecified> long_(self_t);
-   operator_<unspecified> float_(self_t);
-   operator_<unspecified> complex_(self_t);
-   operator_<unspecified> str(self_t);
-
-}}};
-
- The tables below describe the methods generated when the results of the - expressions described are passed as arguments to class_<>::def(). - x is an object of the class type being wrapped. - -

Class self_t inplace - operators

- In the table below, If r is an object of type - other<T>, - y is an object of type T; otherwise, - y is an object of the same type as - r. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
self += r__iadd__x += y
self -= r__isub__x -= y
self *= r__imul__x *= y
self /= r__idiv__x /= y
self %= r__imod__x %= y
self >>= r__irshift__x >>= y
self <<= r__ilshift__x <<= y
self &= r__iand__x &= y
self ^= r__ixor__x ^= y
self |= r__ior__x |= y
- -

Class self_t - comparison functions

- In the tables below, if r is of type self_t, y is an object of - the same type as x;
- if l or r is an object of type - other<T>, - y is an object of type T;
- otherwise, y is an object of the same type as - l or r.
- l is never of type self_t. - -

The column of Python Expressions illustrates the expressions - that will be supported in Python for objects convertible to the types of - x and y. The secondary operation arises due to - Python's reflection - rules for rich comparison operators, and are only used when the - corresponding operation is not defined as a method of the y - object.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ ImplementationPython Expressions
- (primary, secondary)
self == r__eq__x == yx == y, y == x
l == self__eq__y == xy == x, x == y
self != r__ne__x != yx != y, y != x
l != self__ne__y != xy != x, x != y
self < r__lt__x < yx < y, y > x
l < self__gt__y < xy > x, x < y
self > r__gt__x > yx > y, y < x
l > self__lt__y > xy < x, x > y
self <= r__le__x <= yx <= y, y >= x
l <= self__ge__y <= xy >= x, x <= y
self >= r__ge__x >= yx >= y, y <= x
l >= self__le__y >= xy <= x, x >= y
- -

Class self_t non-member - operations

- The operations whose names begin with "__r" below will only - be called if the left-hand operand does not already support the given - operation, as described here. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
self + r__add__x + y
l + self__radd__y + x
self - r__sub__x - y
l - self__rsub__y - x
self * r__mul__x * y
l * self__rmul__y * x
self / r__div__x / y
l / self__rdiv__y / x
self % r__mod__x % y
l % self__rmod__y % x
self >> r__rshift__x >> y
l >> self__rrshift__y >> x
self << r__lshift__x << y
l << self__rlshift__y << x
self & r__and__x & y
l & self__rand__y & x
self ^ r__xor__x ^ y
l ^ self__rxor__y ^ x
self | r__or__x | y
l | self__ror__y | x
pow(self, r)__pow__pow(x, y)
pow(l, self)__rpow__pow(y, x)
- -

Class self_t unary - operations

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
-self__neg__-x
+self__pos__+x
~self__invert__~x
- -

Class self_t value - operations

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
int_(self)__int__long(x)
long___long__PyLong_FromLong(x)
float___float__double(x)
complex___complex__std::complex<double>(x)
str__str__lexical_cast<std::string>(x)
- -

Class Template other

- -

Instances of other<T> can be used in operator - expressions with self; the result is equivalent - to the same expression with a T object in place of - other<T>. Use other<T> to prevent - construction of a T object in case it is heavyweight, when - no constructor is available, or simply for clarity.

- -

Class Template other synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  struct other
-  {
-  };
-}}
-
- - -

Class Template - detail::operator_

- -

Instantiations of detail::operator_<> are used as - the return type of operator expressions involving self. This should be considered an implementation - detail and is only documented here as a way of showing how the result of - self-expressions match calls to class_<>::def().

- -

Class Template - detail::operator_ synopsis

-
-namespace boost { namespace python { namespace detail
-{
-  template <unspecified>
-  struct operator_
-  {
-  };
-}}}
-
- -

Objects

- -

self

-
-namespace boost { namespace python
-{
-  using self_ns::self;
-}}
-
- -

Example

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/operators.hpp>
-#include <boost/operators.hpp>
-
-struct number
-   : boost::integer_arithmetic<number>
-{
-   number(long x_) : x(x_) {}
-   operator long() const { return x; }
-
-   number& operator+=(number const& rhs)
-      { x += rhs }
-   number& operator-=(number const& rhs);
-      { x -= rhs }
-   number& operator*=(number const& rhs)
-      { x *= rhs }
-   number& operator/=(number const& rhs);
-      { x /= rhs }
-   number& operator%=(number const& rhs);
-      { x %= rhs }
-
-   long x;
-};
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(demo)
-{
-   class_<number>("number")
-      // interoperate with self
-      .def(self += self)
-      .def(self + self)
-      .def(self -= self)
-      .def(self - self)
-      .def(self *= self)
-      .def(self * self)
-      .def(self /= self)
-      .def(self / self)
-      .def(self %= self)
-      .def(self % self)
-
-      // Convert to Python int
-      .def(int_(self))
-
-      // interoperate with long
-      .def(self += long())
-      .def(self + long())
-      .def(long() + self)
-      .def(self -= long())
-      .def(self - long())
-      .def(long() - self)
-      .def(self *= long())
-      .def(self * long())
-      .def(long() * self)
-      .def(self /= long())
-      .def(self / long())
-      .def(long() / self)
-      .def(self %= long())
-      .def(self % long())
-      .def(long() % self)
-      ;
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/overloads.html b/doc/v2/overloads.html deleted file mode 100644 index a0a37b34..00000000 --- a/doc/v2/overloads.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/overloads.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/overloads.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
overload-dispatch-expressions
- -
OverloadDispatcher concept
- -
Macros
- -
-
-
BOOST_PYTHON_FUNCTION_OVERLOADS
- -
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Defines facilities for generating families of overloaded Python - functions and extension class methods from C++ functions and - member functions with default arguments, or from similar families - of C++ overloads

- -

overload-dispatch-expressions

- -

- An overload-dispatch-expression is used to describe a - family of overloaded methods to be generated for an extension - class. It has the following properties: - -

-
-
docstring: An ntbs - whose value will bound to the methods' __doc__ - attribute
- -
keywords: A keyword-expression which - will be used to name (a trailing subsequence of) the arguments - to the generated methods.
- -
call policies: An instance of some type which models CallPolicies.
- -
minimum arity - The minimum number of arguments to be accepted by a generated - method overload.
- -
maximum arity - The maximum number of arguments to be accepted by a generated - method overload.
-
-
- -

OverloadDispatcher Concept

- - An OverloadDispatcher X is a class which has a - minimum arity and a maximum arity, and for which - the following following are valid overload-dispatch-expressions, - with the same minimum and maximum arity as the OverloadDispatcher. - -
-X()
-X(docstring)
-X(docstring, keywords)
-X(keywords, docstring)
-X()[policies]
-X(docstring)[policies]
-X(docstring, keywords)[policies]
-X(keywords, docstring)[policies]
-
- -
    -
  • If policies are supplied, it must be an instance of a -type which models CallPolicies, and -will be used as the result's call policies. Otherwise the result's -call policies will be an instance of default_call_policies. - -
  • If docstring is supplied it must be an ntbs, and will be used as the result's docstring. Otherwise the result has an empty docstring. - -
  • If keywords is supplied it must be the result of a keyword-expression - whose length is no greater than X's maximum - arity, and will be used as the result's keywords. Otherwise - the result's keywords will be empty. -
- - - - -

Macros

- -

BOOST_PYTHON_FUNCTION_OVERLOADS(name, func_id, min_args, max_args)

- Expands to the definition of an OverloadDispatcher called - name in the current scope which can be used to - generate the following function invocation: -
-func_id(a1, a2,...ai);
-
- - for all min_args <= i <= max_args. - -

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(name, member_name, min_args, max_args)

- - Expands to the definition of an OverloadDispatcher called - name in the current scope which can be used to - generate the following function invocation: -
-x.member_name(a1, a2,...ai);
-
- - for all min_args <= i <= - max_args, where x is a reference to an - object of class type. - -

Example(s)

- -
-#include <boost/python/module.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/args.hpp>
-#include <boost/python/tuple.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/overloads.hpp>
-#include <boost/python/return_internal_reference.hpp>
-
-using namespace boost::python;
-
-tuple f(int x = 1, double y = 4.25, char const* z = "wow")
-{
-    return make_tuple(x, y, z);
-}
-
-BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
-
-struct Y {};
-struct X
-{
-    Y& f(int x, double y = 4.25, char const* z = "wow")
-    {
-        return inner;
-    }
-    Y inner;
-};
-
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 1, 3)
-
-BOOST_PYTHON_MODULE(args_ext)
-{
-    def("f", f, args("x", "y", "z")
-        , "This is f's docstring"
-        );
-
-    
-    class_<Y>("Y")
-        ;
-            
-    class_<X>("X", "This is X's docstring")
-        .def("f1", &X::f, 
-                X_f_overloads(args("x", "y", "z"),
-                              "f's docstring"
-                                  )[return_internal_reference<>()])
-        ;
-}
-
- -

Revised - - 15 December, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/overview.html b/doc/v2/overview.html deleted file mode 100644 index 00a39773..00000000 --- a/doc/v2/overview.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - -Boost.Python - Overview - - - - - - - -
-

-

-
-

Boost.Python

-

Overview

-
-
-
-
Introduction
-
First topic
-
Second topic
-
Footnotes
-
-

Introduction

-

{{text}}

-

First Topic

-

{{text}}

-

Second Topic

-

{{text}}

-

Footnotes

-
-
(1) {{text}}
-
(2) {{text}}
-
-
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/pickle.html b/doc/v2/pickle.html deleted file mode 100644 index 13c7b306..00000000 --- a/doc/v2/pickle.html +++ /dev/null @@ -1,293 +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 -through the interface as described in detail in the -Python Library Reference for pickle. This interface -involves the special methods __getinitargs__, -__getstate__ and __setstate__ as described -in the following. Note that Boost.Python is also fully compatible -with Python's cPickle module. - -


-

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, pickle.load - will call the constructor (__init__) without arguments; - i.e., the object must be default-constructible. - -

-

-__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. - -

-

-__setstate__ - -
- When an instance of a Boost.Python extension class is restored by the - unpickler (pickle.load), 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. - -
- -The three special methods described above may be .def()'ed -individually by the user. However, Boost.Python provides an easy to use -high-level interface via the -boost::python::pickle_suite class that also -enforces consistency: __getstate__ and __setstate__ -must be defined as pairs. Use of this interface is demonstrated by the -following examples. - -
-

Examples

- -There are three files in boost/libs/python/test that show how to -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__. - This is done in the following way: - -
    -
  • 1. Definition of the C++ pickle function: -
    -  struct world_pickle_suite : boost::python::pickle_suite
    -  {
    -    static
    -    boost::python::tuple
    -    getinitargs(world const& w)
    -    {
    -        return boost::python::make_tuple(w.get_country());
    -    }
    -  };
    -
    -
  • 2. Establishing the Python binding: -
    -  class_<world>("world", args<const std::string&>())
    -      // ...
    -      .def_pickle(world_pickle_suite())
    -      // ...
    -
    -
- -
-

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: - -
    -
  • 1. Definition of the C++ pickle functions: -
    -  struct world_pickle_suite : boost::python::pickle_suite
    -  {
    -    static
    -    boost::python::tuple
    -    getinitargs(const world& w)
    -    {
    -      // ...
    -    }
    -
    -    static
    -    boost::python::tuple
    -    getstate(const world& w)
    -    {
    -      // ...
    -    }
    -
    -    static
    -    void
    -    setstate(world& w, boost::python::tuple state)
    -    {
    -      // ...
    -    }
    -  };
    -
    -
  • 2. Establishing the Python bindings for the entire suite: -
    -  class_<world>("world", args<const std::string&>())
    -      // ...
    -      .def_pickle(world_pickle_suite())
    -      // ...
    -
    -
- -

- 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 guard - described below 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 a little more code but is - unavoidable if the object's __dict__ is not always empty. - -
-

Pitfall and Safety Guard

- -The pickle protocol described above has an important pitfall that the -end user of a Boost.Python extension module might not be aware of: -

- -__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 - either at the C++ or the Python level. Finally, the safety guard - should intentionally be overridden. E.g. in C++ (from - pickle3.cpp): - -
-  struct world_pickle_suite : boost::python::pickle_suite
-  {
-    // ...
-
-    static bool getstate_manages_dict() { return true; }
-  };
-
- - Alternatively 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

- -
    -
  • - 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. - -

    -

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

    -

  • - If __getstate__ is required, include the instance's - __dict__ in the Python object that is returned. - -
- -
- -© Copyright Ralf W. Grosse-Kunstleve 20012-2002. Permission to copy, -use, modify, sell and distribute this document is granted provided this -copyright notice appears in all copies. This document is provided "as -is" without express or implied warranty, and with no claim as to its -suitability for any purpose. - -

-Updated: Aug 2002. -

diff --git a/doc/v2/platforms.html b/doc/v2/platforms.html deleted file mode 100644 index 42429b2e..00000000 --- a/doc/v2/platforms.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - Boost.Python - Known Working Platforms and Compilers - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Known Working Platforms and Compilers

-
-
- Boost.Python has been successfully tested on the following - platforms and compilers: - -
-
Unix Platforms:
- -
-
-
with Python 2.2 and 2.2.2b1:
- -
-
-
GCC 2.95.3, 2.96, 3.0.4, - 3.1, and 3.2 on RedHat Linux 7.3 - for Intel x86
- -
Tru64 CXX - 6.5.1 on OSF v. 5.1 for Dec/Compaq Alpha
- -
- MIPSPro 7.3.1.2m on IRIX 6.5 for SGI - mips
- -
GCC 3.1 on SunOS 5.8
-
-
- -
with Python 2.2.1
- -
-
-
KCC - 3.4d on OSF v. 5.1 for Dec/Compaq Alpha
- -
KCC - 3.4d on AIX
-
-
-
-
-
- -
Microsoft - Windows XP Professional with Python 2.2, 2.2.1, and 2.2.2b1:
- -
-
-
Microsoft Visual - C++ 6, 7, and 7.1 beta
- -
Microsoft Visual - C++ 6 with STLPort - 4.5.3
- -
- Metrowerks CodeWarrior 7.2, 8.0, 8.2 and 8.3 beta
- -
Intel - C++ 5.0, 6.0, and 7.0 beta
- -
Intel C++ - 5.0 with STLPort - 4.5.3
- -
Cygwin GCC 3.0.4 and 3.2
- -
MinGW-1.1 (GCC 2.95.3-5)
- -
MinGW-2.0 (GCC 3.2)
-
-
-
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/pointee.html b/doc/v2/pointee.html deleted file mode 100644 index 47440700..00000000 --- a/doc/v2/pointee.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Boost.Python - <boost/python/pointee.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/pointee.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class Templatepointee - -
-
-
Class Template - pointee synopsis -
-
- -
Example -
-
- -

Introduction

- -

<boost/python/pointee.hpp> introduces a - traits metafunction - template pointee<T> which can be used to extract the "pointed-to" type from the type of a pointer or smart pointer. - -

Classes

- -

Class Template pointee<class T>

- -

pointee<T> is used by the class_<...> - template to deduce the type being held when a pointer or smart - pointer type is used as its HeldType argument. - -

Class Template - pointee synopsis

-
-namespace boost { namespace python
-{
-   template <class T> struct pointee
-   {
-      typedef T::element_type type;
-   };
-
-   // specialization for pointers
-   template <T> struct pointee<T*>
-   {
-      typedef T type;
-   };
-}
-
- - -

Example

- -Given a 3rd-party smart pointer type -smart_pointer<T>, one might partially specialize -pointee<smart_pointer<T> > so that it can be -used as the HeldType for a class wrapper: - -
-#include <boost/python/pointee.hpp>
-#include <boost/python/class.hpp>
-#include <third_party_lib.hpp>
-
-namespace boost { namespace python
-{
-  template <class T> struct pointee<smart_pointer<T> >
-  {
-     typedef T type;
-  };
-}}
-
-BOOST_PYTHON_MODULE(pointee_demo)
-{
-   class_<third_party_class, smart_pointer<third_party_class> >("third_party_class")
-      .def(...)
-      ...
-      ;
-}
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/progress_reports.html b/doc/v2/progress_reports.html deleted file mode 100644 index f5441edd..00000000 --- a/doc/v2/progress_reports.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - -Boost.Python - Progress Reports - - - - - - - -
-

-

-
-

Boost.Python

-

Progress Reports

-
-


- -Monthly progress reports are required as part of Boost Consulting's -contract with LLNL for Boost.Python development. These reports contain -a useful record of the project history, including the rationale for -design decisions and links to relevant discussions. - -
-
February 2002
-
March 2002
-
April 2002
-
May 2002
-
June 2002
-
-
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/ptr.html b/doc/v2/ptr.html deleted file mode 100644 index 0633be80..00000000 --- a/doc/v2/ptr.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - Boost.Python - <boost/python/ptr.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/ptr.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Functions -
-
-
ptr -
- -
Classes -
-
-
Class template pointer_wrapper - -
-
-
Class template pointer_wrapper synopsis - -
Class - pointer_wrapper types - -
Class - pointer_wrapper constructors and destructor - -
Class - pointer_wrapper observer functions - -
-
- -
Metafunctions -
-
-
Class template is_pointer_wrapper - -
-
-
Class template is_pointer_wrapper synopsis -
- - -
Class template unwrap_pointer - -
-
-
Class template unwrap_pointer synopsis -
- -
- - -
Example(s) -
-
- -

Introduction

- -

<boost/python/ptr.hpp> defines the - ptr() function template, which allows users to - specify how to convert C++ pointer values to python in the context - of implementing overridable virtual functions, invoking Python - callable objects, or explicitly converting C++ objects to - Python. Normally, when passing pointers to Python callbacks, the - pointee is copied to ensure that the Python object - never holds a dangling reference. To specify that the new Python - object should merely contain a copy of a pointer p, - the user can pass ptr(p) instead of passing - p directly. This interface is meant to mirror the use - of boost::ref(), - which can be similarly used to prevent copying of referents. - -

ptr(p) returns an instance of pointer_wrapper<>, which - can be detected using the is_pointer_wrapper<> - metafunction; unwrap_pointer<> is a - metafunction which extracts the original pointer type from a - pointer_wrapper<>. These classes can be thought - of as implementation details. - -

Functions

-
-
-template <class T>
-pointer_wrapper<T> ptr(T x);
-
- -
-
Requires: T is a pointer type. - -
Returns: pointer_wrapper<T>(x) - -
Throws: nothing. -
- -

Classes

- -

Class template pointer_wrapper

- -

A "type envelope" which is returned by ptr(), used to indicate reference semantics - for pointers passed to Python callbacks. - -

Class - pointer_wrapper synopsis

-
-namespace boost { namespace python
-{
-    template<class Ptr> class pointer_wrapper
-    { 
-     public:
-        typedef Ptr type;
-
-        explicit pointer_wrapper(Ptr x);
-        operator Ptr() const;
-        Ptr get() const;
-    };
-}}
-
- -

Class template pointer_wrapper types

-
-typedef Ptr type;
-
-The type of the pointer being wrapped. - -

Class template pointer_wrapper constructors and - destructor

-
-explicit pointer_wrapper(Ptr x);
-
- -
-
Requires: Ptr is a pointer type. - -
Effects: Stores x in a the pointer_wrapper<>. -
Throws: nothing. -
- -

Class template pointer_wrapper observer - functions

-
-operator Ptr() const;
-Ptr get() const;
-
- -
-
Returns: a copy of the stored pointer. -
Rationale: pointer_wrapper is intended - to be a stand-in for the actual pointer type, but sometimes it's - better to have an explicit way to retrieve the pointer. -
- -

Metafunctions

- -

Class template is_pointer_wrapper

- -

A unary metafunction whose value is true iff its - argument is a pointer_wrapper<>. - -

Class template is_pointer_wrapper synopsis

-
-namespace boost { namespace python
-{
-    template<class T> class is_pointer_wrapper
-    { 
-        static unspecified value = ...;
-    };
-}}
-
- - -
-
Returns: true iff T is a - specialization of -pointer_wrapper<>. -
value is an integral constant convertible to bool of -unspecified type - -
- -

Class template unwrap_pointer

- -A unary metafunction which extracts the wrapped pointer type from a -specialization of pointer_wrapper<>. - -

Class template unwrap_pointer synopsis

-
-namespace boost { namespace python
-{
-    template<class T> class unwrap_pointer
-    { 
-        typedef unspecified type;
-    };
-}}
-
- -
-
Returns: T::type if T is a - specialization of -pointer_wrapper<>, T otherwise -
- - -

Example(s)

- -This example illustrates the use of ptr() to prevent an -object from being copied: -
-#include <boost/python/call.hpp>
-#include <boost/python/ptr.hpp>
-
-class expensive_to_copy
-{
-   ...
-};
-
-void pass_as_arg(expensive_to_copy* x, PyObject* f)
-{
-   // call the Python function f, passing a Python object built around
-   // which refers to *x by-pointer.
-   //
-   // *** Note: ensuring that *x outlives the argument to f() is    ***
-   // *** up to the user! Failure to do so could result in a crash! ***
-
-   boost::python::call<void>(f, ptr(x));
-}
-...
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/python.html b/doc/v2/python.html deleted file mode 100644 index 64d0c135..00000000 --- a/doc/v2/python.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python.hpp>

-
-


- -

Contents

- -
-
Introduction
-
-
- -

Introduction

- -

This is a convenience header which #includes all of the public - interface headers that are part of the Boost.Python library

-
-# include <args.hpp>
-# include <args_fwd.hpp>
-# include <back_reference.hpp>
-# include <bases.hpp>
-# include <borrowed.hpp>
-# include <call.hpp>
-# include <call_method.hpp>
-# include <class.hpp>
-# include <copy_const_reference.hpp>
-# include <copy_non_const_reference.hpp>
-# include <data_members.hpp>
-# include <def.hpp>
-# include <default_call_policies.hpp>
-# include <dict.hpp>
-# include <enum.hpp>
-# include <errors.hpp>
-# include <exception_translator.hpp>
-# include <extract.hpp>
-# include <handle.hpp>
-# include <has_back_reference.hpp>
-# include <implicit.hpp>
-# include <init.hpp>
-# include <instance_holder.hpp>
-# include <iterator.hpp>
-# include <list.hpp>
-# include <long.hpp>
-# include <lvalue_from_pytype.hpp>
-# include <make_function.hpp>
-# include <manage_new_object.hpp>
-# include <module.hpp>
-# include <numeric.hpp>
-# include <object.hpp>
-# include <object_protocol.hpp>
-# include <object_protocol_core.hpp>
-# include <operators.hpp>
-# include <other.hpp>
-# include <overloads.hpp>
-# include <pointee.hpp>
-# include <ptr.hpp>
-# include <reference_existing_object.hpp>
-# include <return_internal_reference.hpp>
-# include <return_value_policy.hpp>
-# include <scope.hpp>
-# include <self.hpp>
-# include <slice_nil.hpp>
-# include <str.hpp>
-# include <to_python_converter.hpp>
-# include <to_python_indirect.hpp>
-# include <to_python_value.hpp>
-# include <tuple.hpp>
-# include <type_id.hpp>
-# include <with_custodian_and_ward.hpp>
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/rationale.html b/doc/v2/rationale.html deleted file mode 100644 index 8219adad..00000000 --- a/doc/v2/rationale.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - -Boost.Python - Rationale - - - - - - - -
-

-

-
-

Boost.Python

-

Rationale

-
-
-
-
Introduction
-
First topic
-
Second topic
-
Footnotes
-
-

Introduction

-

{{text}}

-

First Topic

-

{{text}}

-

Second Topic

-

{{text}}

-

Footnotes

-
-
(1) {{text}}
-
(2) {{text}}
-
-
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/raw_function.html b/doc/v2/raw_function.html deleted file mode 100755 index ae1ad6c0..00000000 --- a/doc/v2/raw_function.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/raw_function.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/raw_function.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
raw_function
-
-
- -
Example
-
-
- -

Introduction

- -

raw_function(...) - is used to convert a function taking a tuple and a dict into a Python callable object - which accepts a variable number of arguments and arbitrary keyword - arguments. - -

Functions

- raw_function -
-template <class F>
-object raw_function(F f, std::size_t min_args = 0);
-
- -
-
Requires: f(tuple(), dict()) is - well-formed.
- -
Returns: a callable object which requires at least min_args arguments. When called, the actual non-keyword arguments will be passed in a tuple as the first argument to f, and the keyword arguments will be passed in a dict as the second argument to f. - - -
- -

Example

-C++: -
-#include <boost/python/def.hpp>
-#include <boost/python/tuple.hpp>
-#include <boost/python/dict.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/raw_function.hpp>
-
-using namespace boost::python;
-
-tuple raw(tuple args, dict kw)
-{
-    return make_tuple(args, kw);
-}
-
-BOOST_PYTHON_MODULE(raw_test)
-{
-    def("raw", raw_function(raw));
-}
-
- -Python: -
->>> from raw_test import *
-
->>> raw(3, 4, foo = 'bar', baz = 42)
-((3, 4), {'foo': 'bar', 'baz': 42})
-
-

- - 7 March, 2003 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html deleted file mode 100644 index e066debf..00000000 --- a/doc/v2/reference_existing_object.html +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/reference_existing_object.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/reference_existing_object.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - reference_existing_object
- -
-
-
Class - reference_existing_object synopsis
- -
Class - reference_existing_object metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - reference_existing_object

- -

reference_existing_object is a model of ResultConverterGenerator - which can be used to wrap C++ functions which return a reference or - pointer to a C++ object. When the wrapped function is called, the value - referenced by its return value is not copied. A new Python object is - created which contains a pointer to the referent, and no attempt is made - to ensure that the lifetime of the referent is at least as long as that - of the corresponding Python object. Thus, it can be highly dangerous to use - reference_existing_object without additional lifetime - management from such models of CallPolicies as with_custodian_and_ward. - This class is used in the implementation of return_internal_reference.

- -

Class - reference_existing_object synopsis

-
-namespace boost { namespace python
-{
-    struct reference_existing_object
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - reference_existing_object metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U& or - U*for some U.
- -
Returns: typedef to_python_indirect<T,V> - type, where V is a HolderObjectGenerator - which constructs an instance holder containing an unowned - U* pointing to the referent of the wrapped function's - return value.
-
- -

Example

- -

In C++:

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/reference_existing_object.hpp>
-#include <boost/python/return_value_policy.hpp>
-#include <utility>
-
-// classes to wrap
-struct Singleton
-{
-   Singleton() : x(0) {}
-
-   int exchange(int n)  // set x and return the old value
-   {
-        std::swap(n, x);
-        return n;
-   }
-
-   int x;
-};
-
-Singleton& get_it()
-{
-   static Singleton just_one;
-   return just_one;
-}
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(singleton)
-{
-    def("get_it", get_it,
-        return_value_policy<reference_existing_object>());
-
-    class_<Singleton>("Singleton")
-       .def("exchange", &Singleton::exchange)
-       ;
-}
-
- In Python: -
->>> import singleton
->>> s1 = singleton.get_it()  
->>> s2 = singleton.get_it()
->>> id(s1) == id(s2)  # s1 and s2 are not the same object
-0
->>> s1.exchange(42)   # but they reference the same C++ Singleton
-0
->>> s2.exchange(99)
-42
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/return_by_value.html b/doc/v2/return_by_value.html deleted file mode 100644 index 80c26d75..00000000 --- a/doc/v2/return_by_value.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/return_by_value.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/return_by_value.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - return_by_value
- -
-
-
Class - return_by_value synopsis
- -
Class - return_by_value metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - return_by_value

- -

return_by_value is a model of ResultConverterGenerator - which can be used to wrap C++ functions returning any reference or value - type such that the return value is copied into a new Python object.

- -

Class - return_by_value synopsis

-
-namespace boost { namespace python
-{
-    struct return_by_value
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - return_by_value metafunctions

-
-template <class T> struct apply
-
- -
-
Returns: typedef to_python_value<T> - type;
-
- -

Example

- -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/return_by_value.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { };
-
-Bar global_bar;
-
-// functions to wrap:
-Bar b1();
-Bar& b2();
-Bar const& b3();
-
-// Wrapper code
-using namespace boost::python;
-template <class R>
-void def_void_function(char const* name, R (*f)())
-{
-   def(name, f, return_value_policy<return_by_value>());
-}
-
-BOOST_PYTHON_MODULE(my_module)
-{
-    class_<Bar>("Bar");
-    def_void_function("b1", b1);
-    def_void_function("b2", b2);
-    def_void_function("b3", b3);
-}
-
- -

Python Code

-
->>> from my_module import *
->>> b = b1() # each of these calls
->>> b = b2() # creates a brand
->>> b = b3() # new Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html deleted file mode 100644 index bd9946da..00000000 --- a/doc/v2/return_internal_reference.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/return_internal_reference.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/return_internal_reference.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - return_internal_reference
- -
-
-
Class - Template return_internal_reference - synopsis
- -
Class - return_internal_reference static - functions
-
-
-
-
- -
Example
-
-
- -

Introduction

- return_internal_reference instantiations are models of CallPolicies which allow pointers and - references to objects held internally by a free or member function - argument or from the target of a member function to be returned safely - without making a copy of the referent. The default for its first template - argument handles the common case where the containing object is the - target (*this) of a wrapped member function. - -

Classes

- -

Class template - return_internal_reference

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- return_internal_reference template parameters -
ParameterRequirementsDescriptionDefault
owner_argA positive compile-time constant of type - std::size_t.The index of the parameter which contains the object to which the - reference or pointer is being returned. If used to wrap a member - function, parameter 1 is the target object (*this). Note - that if the target Python object type doesn't support weak - references, a Python TypeError exception will be raised - when the function being wrapped is called.1
BaseA model of CallPoliciesUsed for policy composition. Any result_converter it - supplies will be overridden by - return_internal_reference, but its precall - and postcall policies are composed as described here CallPolicies.default_call_policies
- -

Class template - return_internal_reference synopsis

-
-namespace boost { namespace python
-{
-   template <std::size_t owner_arg = 1, class Base = default_call_policies>
-   struct return_internal_reference : Base
-   {
-      static PyObject* postcall(PyObject*, PyObject* result);
-      typedef reference_existing_object result_converter;
-   };
-}}
-
- -

Class - default_call_policies static functions

-
-PyObject* postcall(PyObject* args, PyObject* result);
-
- -
-
Requires: PyTuple_Check(args) - != 0
- -
Returns: - with_custodian_and_ward_postcall::postcall(args, - result)
-
- -

Example

- -

C++ module definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/return_internal_reference.hpp>
-
-class Bar
-{
-   Bar(int x) : x(x) {}
-   int get_x() const { return x; }
-   void set_x(int x) { this->x = x; }
- private:
-   int x;
-}
-
-class Foo
-{
- public:
-   Foo(int x) : b(x) {}
-
-   // Returns an internal reference
-   Bar const& get_bar() const { return b; }
-
- private:
-   Bar b;
-};
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(internal_refs)
-{
-   class_<Bar>("Bar")
-      .def("get_x", &Bar::get_x)
-      .def("set_x", &Bar::set_x)
-      ;
-
-   class_<Foo>("Foo", init<int>())
-      .def("get_bar", &Foo::get_bar
-          , return_internal_reference<>())
-      ;
-}
-
- -

Python code

-
->>> from internal_refs import *
->>> f = Foo(3)
->>> b1 = f.get_bar()
->>> b2 = f.get_bar()
->>> b1.get_x()
-3
->>> b2.get_x()
-3
->>> b1.set_x(42)
->>> b2.get_x()
-42
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html deleted file mode 100644 index 601c49d5..00000000 --- a/doc/v2/return_value_policy.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/return_value_policy.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/return_value_policy.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - return_value_policy
- -
-
-
Class Template - return_value_policy synopsis
-
-
-
-
- -
Example
-
-
- -

Introduction

- return_value_policy instantiations are simply models of CallPolicies which are composed of a ResultConverterGenerator - and optional Base CallPolicies. - -

Classes

- -

Class template - return_value_policy

- - - - - - - - - - - - - - - - - - - - - - - - - -
- return_value_policy template parameters -
ParameterRequirementsDefault
ResultConverterGeneratorA model of ResultConverterGenerator.
BaseA model of CallPoliciesdefault_call_policies
- -

Class template - return_value_policy synopsis

-
-namespace boost { namespace python
-{
-  template <class ResultConverterGenerator, class Base = default_call_policies>
-  struct return_value_policy : Base
-  {
-      typedef ResultConverterGenerator result_converter;
-  };
-}}
-
- -

Example

- -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/copy_const_reference.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { int x; }
-
-struct Foo {
-   Foo(int x) : { b.x = x; }
-   Bar const& get_bar() const { return b; }
- private:
-   Bar b;
-};
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-   class_<Bar>("Bar");
-
-   class_<Foo>("Foo", init<int>())
-      .def("get_bar", &Foo::get_bar
-          , return_value_policy<copy_const_reference>())
-      ;
-}
-
- -

Python Code

-
->>> from my_module import *
->>> f = Foo(3)         # create a Foo object
->>> b = f.get_bar()    # make a copy of the internal Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/scope.html b/doc/v2/scope.html deleted file mode 100644 index 1d578d36..00000000 --- a/doc/v2/scope.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/scope.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/scope.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class scope
- -
-
-
Class scope - synopsis
- -
Class scope - constructors and destructor
-
-
-
-
- -
Example
-
-
- -

Introduction

- -

Defines facilities for querying and controlling the Python scope - (namespace) which will contain new wrapped classes and functions.

- -

Classes

- -

Class scope

- -

The scope class has an associated global Python - object which controls the Python namespace in which new extension - classes and wrapped functions will be defined as - attributes. Default-constructing a new scope object - binds it to the associated global Python object. Constructing a - scope object with an argument changes the associated - global Python object to the one held by the argument, until the - lifetime of the scope object ends, at which time the - associated global Python object reverts to what it was before the - scope object was constructed.

- -

Class scope - synopsis

-
-namespace boost { namespace python
-{
-  class scope : public object
-  {
-   public:
-      scope(scope const&);
-      scope(object const&);
-      scope();
-      ~scope()
-   private:
-      void operator=(scope const&);
-  };
-}}
-
- -

Class scope constructors - and destructor

-
-explicit scope(scope const& x);
-explicit scope(object const& x);
-
- Stores a reference to the current associated scope object, and sets the - associated scope object to the one referred to by x.ptr(). - The object base class is initialized with x. -
-scope();
-
- Stores a reference to the current associated scope object. The - object base class is initialized with the current associated - scope object. Outside any module initialization function, the current - associated Python object is None. -
-~scope()
-
- Sets the current associated Python object to the stored object. - -

Example

- The following example shows how scope setting can be used to define - nested classes. - -

C++ Module definition:

-
-#include <boost/python/class.hpp>
-#include <boost/python/scope.hpp>
-using namespace boost::python;
-
-struct X
-{
-  void f();
-
-  struct Y { int g() { return 42; } };
-};
-
-BOOST_PYTHON_MODULE(nested)
-{
-   // add some constants to the current (module) scope
-   scope().attr("yes") = 1;
-   scope().attr("no") = 0;
-
-   // Change the current scope 
-   scope outer
-       = class_<X>("X")
-            .def("f", &X::f)
-            ;
-
-   // Define a class Y in the current scope, X
-   class_<Y>("Y")
-      .def("g", &Y::g)
-      ;
-}
-
- Interactive Python: -
->>> import nested
->>> nested.yes
-1
->>> y = nested.X.Y()
->>> y.g()
-42
-
- -

Revised 09 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/str.html b/doc/v2/str.html deleted file mode 100644 index 79ae74f1..00000000 --- a/doc/v2/str.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/str.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/str.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class str
- -
-
-
Class str - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - str - type.

- -

Classes

- -

Class str

- -

Exposes the string - methods of Python's built-in str type. The - semantics of the constructors and member functions defined below - can be fully understood by reading the TypeWrapper concept - definition. Since str is publicly derived from - object, the - public object interface applies to str instances as - well.

- -

Class str - synopsis

-
-namespace boost { namespace python
-{
-  class str : public object
-  {
-   public:
-      str(); // new str
-
-      str(const char* s); // new str
-
-      template <class T>
-      explicit str(T const& other);
-
-      str capitalize() const;
-
-      template <class T>
-      str center(T const& width) const;
-
-      template<class T>
-      long count(T const& sub) const;
-      template<class T1, class T2>
-      long count(T1 const& sub,T2 const& start) const;
-      template<class T1, class T2, class T3>
-      long count(T1 const& sub,T2 const& start, T3 const& end) const;
-
-      object decode() const;
-      template<class T>
-      object decode(T const& encoding) const;
-      template<class T1, class T2>
-      object decode(T1 const& encoding, T2 const& errors) const;
-
-      object encode() const;
-      template <class T>
-      object encode(T const& encoding) const;
-      template <class T1, class T2>
-      object encode(T1 const& encoding, T2 const& errors) const;
-
-      template <class T>
-      bool endswith(T const& suffix) const;
-      template <class T1, class T2>
-      bool endswith(T1 const& suffix, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const;
-
-      str expandtabs() const;
-      template <class T>
-      str expandtabs(T const& tabsize) const;
-
-      template <class T>
-      long find(T const& sub) const;
-      template <class T1, class T2>
-      long find(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long find(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      template <class T>
-      long index(T const& sub) const;
-      template <class T1, class T2>
-      long index(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long index(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      bool isalnum() const;
-      bool isalpha() const;
-      bool isdigit() const;
-      bool islower() const;
-      bool isspace() const;
-      bool istitle() const;
-      bool isupper() const;
-
-      template <class T>
-      str join(T const& sequence) const;
-
-      template <class T>
-      str ljust(T const& width) const;
-
-      str lower() const;
-      str lstrip() const;
-
-      template <class T1, class T2>
-      str replace(T1 const& old, T2 const& new_) const;
-      template <class T1, class T2, class T3>
-      str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const;
-
-      template <class T>
-      long rfind(T const& sub) const;
-      template <class T1, class T2>
-      long rfind(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long rfind(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      template <class T>
-      long rindex(T const& sub) const;
-      template <class T1, class T2>
-      long rindex(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long rindex(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      template <class T>
-      str rjust(T const& width) const;
-
-      str rstrip() const;
-
-      list split() const; 
-      template <class T>
-      list split(T const& sep) const;
-      template <class T1, class T2>
-      list split(T1 const& sep, T2 const& maxsplit) const;
-
-      list splitlines() const;
-      template <class T>
-      list splitlines(T const& keepends) const;
-
-      template <class T>
-      bool startswith(T const& prefix) const;
-      template <class T1, class T2>
-      bool startswidth(T1 const& prefix, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const;
-
-      str strip() const;
-      str swapcase() const;
-      str title() const;
-
-      template <class T>
-      str translate(T const& table) const;
-      template <class T1, class T2>
-      str translate(T1 const& table, T2 const& deletechars) const;
-
-      str upper() const;
-  };
-}}
-
- -

Example

-
-using namespace boost::python;
-str remove_angle_brackets(str x)
-{
-  return x.strip('<').strip('>');
-}
-
- -

Revised 3 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/to_python_converter.html b/doc/v2/to_python_converter.html deleted file mode 100644 index 33e3b684..00000000 --- a/doc/v2/to_python_converter.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/to_python_converter.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/to_python_converter.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - to_python_converter
- -
-
-
Class Template - to_python_converter synopsis
- -
Class Template - to_python_converter constructor
-
-
-
-
- -
Example
-
-
- -

Introduction

- to_python_converter registers a conversion from objects of a - given C++ type into a Python object. - -

Classes

- -

Class template - to_python_converter

- to_python_converter adds a wrapper around a static member - function of its second template parameter, handling low-level details - such as insertion into the converter registry. - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- to_python_converter template parameters
- In the table below, x denotes an object of type - T -
ParameterRequirementsDescription
T - The C++ type of the source object in the conversion
Conversion - PyObject* p = Conversion::convert(x),
- if p == 0, PyErr_Occurred() != 0.
A class type whose static member function convert - does the real work of the conversion.
- -

Class template - to_python_converter synopsis

-
-namespace boost { namespace python
-{
-  template <class T, class Conversion>
-  struct to_python_converter
-  {
-      to_python_converter();
-  };
-}}
-
- -

Class template - to_python_converter constructor

-
-to_python_converter();
-
- -
-
Effects: Registers a to_python converter which uses - Conversion::convert() to do its work.
-
- -

Example

- This example presumes that someone has implemented the standard noddy example - module from the Python documentation, and placed the corresponding - declarations in "noddy.h". Because - noddy_NoddyObject is the ultimate trivial extension type, - the example is a bit contrived: it wraps a function for which all - information is contained in the type of its return value. - -

C++ module definition

-
-#include <boost/python/reference.hpp>
-#include <boost/python/module.hpp>
-#include "noddy.h"
-
-struct tag {};
-tag make_tag() { return tag(); }
-
-using namespace boost::python;
-
-struct tag_to_noddy
-{
-    static PyObject* convert(tag const& x)
-    {
-        return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
-    }
-};
-
-BOOST_PYTHON_MODULE(to_python_converter)
-{
-    def("make_tag", make_tag);
-    to_python_converter<tag, tag_to_noddy>();
-}
-
- -

Python code

-
->>> import to_python_converter
->>> def always_none():
-...     return None
-...
->>> def choose_function(x):
-...     if (x % 2 != 0):
-...         return to_python_converter.make_tag
-...     else:
-...         return always_none
-...
->>> a = [ choose_function(x) for x in range(5) ]
->>> b = [ f() for f in a ]
->>> type(b[0])
-<type 'NoneType'>
->>> type(b[1])
-<type 'Noddy'>
->>> type(b[2])
-<type 'NoneType'>
->>> type(b[3])
-<type 'Noddy'>
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/to_python_indirect.html b/doc/v2/to_python_indirect.html deleted file mode 100644 index 7871c548..00000000 --- a/doc/v2/to_python_indirect.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - Boost.Python - <boost/python/to_python_indirect.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/to_python_indirect.hpp>

-
-
- -

Contents

- -
-
Introduction - - -
Classes - -
-
-
Class Template to_python_indirect - -
-
- -
Class Template - to_python_indirect synopsis - -
Class Template - to_python_indirect observer functions - -
Class Template - to_python_indirect static functions -
-
- -
Example -
-
- -

Introduction

- - <boost/python/to_python_indirect.hpp> supplies - a way to construct new Python objects that hold wrapped C++ class - instances via a pointer or smart pointer. - -

Classes

- -

Class template to_python_indirect

-

Class template to_python_indirect converts objects -of its first argument type to python as extension class instances, using the ownership policy provided by its 2nd argument. - -

- - - - - - - -
- to_python_indirect Requirements
- - In the table below, x denotes an object of - type T, h denotes an - object of type - boost::python::objects::instance_holder*, and - p denotes an object of type - U*. - -
Parameter - - Requirements - - Description - -
T - - Either U cv& - (where cv is any optional cv-qualification) or a Dereferenceable type such that - *x is convertible to U const&, where - U is a class type. - - A type deferencing a C++ class exposed to Python using - class template class_. - -
MakeHolder - - h = MakeHolder::execute(p); - - A class whose static execute() creates an - instance_holder. - -
- - Instantiations of to_python_indirect are models of ResultConverter. - - -

Class template to_python_indirect synopsis

-
-namespace boost { namespace python
-{
-  template <class T, class MakeHolder>
-  struct to_python_indirect
-  {
-     static bool convertible();
-     PyObject* operator()(T ptr_or_reference) const;
-   private:
-     static PyTypeObject* type();
-  };
-}}
-
- -

Class template to_python_indirect observers

-
-PyObject* operator()(T x) const;
-
- -
- -
Requires: x refers to an object (if it - is a pointer type, it is non-null). convertible() == - true. - -
Effects: Creates an appropriately-typed Boost.Python - extension class instance, uses MakeHolder to create - an instance_holder from x, installs - the instance_holder in the new extension class - instance, and returns a pointer to it. - -
- - -

Class template to_python_indirect statics

-
-bool convertible();
-
- -
Effects: Returns true iff any module has - registered a Python type corresponding to U. - -

Example

- -This example replicates the functionality of reference_existing_object, -but without some of the compile-time error checking. - - -
-
-struct make_reference_holder
-{
-   typedef boost::python::objects::instance_holder* result_type;
-   template <class T>
-   static result_type execute(T* p)
-   {
-      return new boost::python::objects::pointer_holder<T*, T>(p);
-   }
-};
-
-struct reference_existing_object
-{
-   // metafunction returning the ResultConverter
-   template <class T>
-   struct apply
-   {
-      typedef boost::python::to_python_indirect<T,make_reference_holder> type;
-   };
-};
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/to_python_value.html b/doc/v2/to_python_value.html deleted file mode 100644 index 76446024..00000000 --- a/doc/v2/to_python_value.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - Boost.Python - <boost/python/to_python_value.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header - <boost/python/to_python_value.hpp>

-
-


- -

Contents

- -
-
Classes - -
-
-
Class - to_python_value - -
-
-
Class template - to_python_value synopsis - -
Class template - to_python_value observer functions -
-
- -
-
- -

Classes

- -

Class template - to_python_value

- -

to_python_value is a model of ResultConverter - which copies its argument into a new Python object. - -

Class - to_python_value synopsis

-
-namespace boost { namespace python
-{
-   template <class T>
-   struct to_python_value
-   {
-      typedef typename add_reference<
-         typename add_const<T>::type
-      >::type argument_type;
-
-      static bool convertible();
-      PyObject* operator()(argument_type) const;
-   };
-}}
-
- -

Class - to_python_value observers

-
-static bool convertible();
-
- -
-
Returns: true iff a converter has been registered which can convert T to python by-value. -
- -
-PyObject* operator()(argument_type x) const;
-
- -
-
Requires: convertible() == true -
Effects: converts x to python -
Returns: the resulting Python object iff a converter for T has been registered, 0 otherwise. -
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/tuple.html b/doc/v2/tuple.html deleted file mode 100644 index 3108cc5f..00000000 --- a/doc/v2/tuple.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/tuple.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/tuple.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class tuple
- -
-
-
Class tuple - synopsis
-
-
-
-
- -
Functions
- -
-
-
make_tuple
-
-
- -
Example
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - - tuple type.

- -

Classes

- -

Class tuple

- -

Exposes the interface of Python's built-in tuple type. - The semantics of the constructors and member functions defined below can - be fully understood by reading the TypeWrapper concept - definition. Since tuple is publicly derived from object, the public object - interface applies to tuple instances as well.

- -

Class tuple - synopsis

-
-namespace boost { namespace python
-{
-   class tuple : public object
-   {
-      // tuple() -> an empty tuple
-      tuple();
-
-      // tuple(sequence) -> tuple initialized from sequence's items
-      template <class T>
-      explicit tuple(T const& sequence)
-  };
-}}
-
- -

Functions

- -

make_tuple

-
-namespace boost { namespace python
-{
-  tuple make_tuple();
-
-  template <class A0>
-  tuple make_tuple(A0 const& a0);
-
-  template <class A0, class A1>
-  tuple make_tuple(A0 const& a0, A1 const& a1);
-  ...
-  template <class A0, class A1,...class An> 
-  tuple make_tuple(A0 const& a0, A1 const& a1,...An const& an);
-}}
-
- Constructs a new tuple object composed of object(a0), - object(a0),...object(an). - -

Example

-
-using namespace boost::python;
-tuple head_and_tail(object sequence)
-{
-    return make_tuple(sequence[0],sequence[-1]);
-}
-
- -

Revised 03 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/type_id.html b/doc/v2/type_id.html deleted file mode 100755 index 62300206..00000000 --- a/doc/v2/type_id.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - Boost.Python - <boost/python/type_id.hpp> - - - - -
-

C++ Boost

- -
-

Boost.Python

- -

Header <boost/python/type_id.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class - type_info - -
-
-
Class - type_info synopsis - -
Class - type_info constructor - -
Class - type_info comparison functions - -
Class - type_info observer functions -
-
- -
Functions - -
-
-
type_id -
- -
Example -
-
- -

Introduction

- -

<boost/python/type_id.hpp> provides types and - functions for runtime type identification like those of of - <typeinfo>. It exists mostly to work around - certain compiler bugs and platform-dependent interactions with - shared libraries. - -

Classes

- -

Class type_info

- -

type_info instances identify a type. As - std::type_info is specified to (but unlike its - implementation in some compilers), - boost::python::type_info never represents top-level - references or cv-qualification (see section 5.2.8 in the C++ - standard). Unlike std::type_info, - boost::python::type_info instances are copyable, and - comparisons always work reliably across shared library boundaries. - -

Class type_info - synopsis

-
-namespace boost { namespace python
-{
-  class type_info : totally_ordered<type_info>
-  {
-   public:
-      // constructor
-      type_info(std::type_info const& = typeid(void));
-
-      // comparisons
-      bool operator<(type_info const& rhs) const;
-      bool operator==(type_info const& rhs) const;
-
-      // observers
-      char const* name() const;
-  };
-}}
-
- -

Class type_info - constructor

-
-type_info(std::type_info const& = typeid(void));
-
- -
-
Effects: constructs a type_info object - which identifies the same type as its argument. - -
Rationale: Since it is occasionally neccessary to make - an array of type_info objects a benign default - argument is supplied. Note: this - constructor does not correct for non-conformance of - compiler typeid() implementations. See type_id, below. -
- -

Class - type_info comparisons

-
-bool operator<(type_info const& rhs) const;
-
- -
-
Effects: yields a total order over - type_info objects. -
-
-bool operator==(type_info const& rhs) const;
-
- -
-
Returns: true iff the two values describe - the same type. -
- -
-
Note: The use of totally_ordered<type_info> - as a private base class supplies operators <=, - >=, >, and != -
- -

Class type_info - observers

-
-char const* name() const;
-
- -
-
Returns: The result of calling name() on - the argument used to construct the object. -
- -

Functions

-
-std::ostream& operator<<(std::ostream&s, type_info const&x);
-
- -
-
Effects: Writes a description of the type described by - to x into s. - -
Rationale: Not every C++ implementation provides a - truly human-readable type_info::name() string, but - for some we may be able to decode the string and produce a - reasonable representation. -
-
-template <class T> type_info type_id()
-
- -
-
Returns: type_info(typeid(T)) - -
Note: On some non-conforming C++ implementations, the - code is not actually as simple as described above; the semantics - are adjusted to work as-if the C++ implementation were - conforming. -
- -

Example

- The following example, though silly, illustrates how the - type_id facility might be used -
-#include <boost/python/type_id.hpp>
-
-// Returns true iff the user passes an int argument
-template <class T>
-bool is_int(T x)
-{
-   using boost::python::type_id;
-   return type_id<T>() == type_id<int>();
-}
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All - Rights Reserved. - diff --git a/doc/v2/with_custodian_and_ward.html b/doc/v2/with_custodian_and_ward.html deleted file mode 100644 index e6fc15df..00000000 --- a/doc/v2/with_custodian_and_ward.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - - Boost.Python - <boost/python/with_custodian_and_ward.hpp> - - - - - - - - -
-

- C++ Boost - -

-
-

- Boost.Python -

-

- Header <boost/python/with_custodian_and_ward.hpp> -

-
-


-

- Contents -

-
-
- Introduction -
-
- Classes -
-
-
-
- Class Template - with_custodian_and_ward -
-
-
-
- Class - Template with_custodian_and_ward synopsis -
-
- Class - with_custodian_and_ward static functions -
-
-
-
- Class Template - with_custodian_and_ward_postcall -
-
-
-
- Class - Template with_custodian_and_ward_postcall - synopsis -
-
- Class - with_custodian_and_ward_postcall static - functions -
-
-
-
-
-
- Example -
-
-
-

- Introduction -

This header provides faciliites for establishing a lifetime - dependency between two of a function's Python argument or result objects. - The ward object will not be destroyed until after the custodian as - long as the custodian object supports weak - references (Boost.Python extension classes all support weak - references). If the custodian object does not support weak - references and is not None, an appropriate exception will be - thrown. The two class templates with_custodian_and_ward and - with_custodian_and_ward_postcall differ in the point at - which they take effect. -

- In order to reduce the chance of inadvertently creating dangling - pointers, the default is to do lifetime binding before the - underlying C++ object is invoked. However, before invocation the result - object is not available, so - with_custodian_and_ward_postcall is provided to bind - lifetimes after invocation. Also, if a C++ exception is thrown after - with_custodian_and_ward<>::precall but before the - underlying C++ object actually stores a pointer, the lifetime of the - custodian and ward objects will be artificially bound together, so one - might choose with_custodian_and_ward_postcall instead, - depending on the semantics of the function being wrapped. -

-

- Please note that this is not the appropriate tool to use when - wrapping functions which transfer ownership of a raw pointer - across the function-call boundary. Please see the FAQ if you want to do that. -

-

- Classes -

-

- Class template - with_custodian_and_ward -

- - - - - - - - - - - - - - - - - - - - - - - - -
- with_custodian_and_ward template parameters -
- Parameter - - Requirements - - Description - - Default -
- custodian - - A positive compile-time constant of type std::size_t. - - The 1-based index of the parameter which is the dependency in the - lifetime relationship to be established. If used to wrap a member - function, parameter 1 is the target object (*this). - Note that if the target Python object type doesn't support weak - references, a Python TypeError exception will be - raised when the C++ object being wrapped is called. -
- ward - - A positive compile-time constant of type std::size_t. - - The 1-based index of the parameter which is the dependent in the - lifetime relationship to be established. If used to wrap a member - function, parameter 1 is the target object (*this). -
- Base - - A model of CallPolicies - - Used for policy - composition. - - default_call_policies -
-

- Class template - with_custodian_and_ward synopsis -

-
-namespace boost { namespace python
-{
-   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
-   struct with_custodian_and_ward : Base
-   {
-      static bool precall(PyObject* args);
-   };
-}}
-
-

- Class - with_custodian_and_ward static functions -

-
-bool precall(PyObject* args);
-
-
-
- Requires: PyTuple_Check(args) - != 0 -
-
- Effects: Makes the lifetime of the argument indicated by - ward dependent on the lifetime of the argument indicated - by custodian. -
-
- Returns: false and PyErr_Occurred() != 0 - upon failure, true otherwise. -
-
-

- Class template - with_custodian_and_ward_postcall -

- - - - - - - - - - - - - - - - - - - - - - - - -
- with_custodian_and_ward_postcall template - parameters -
- Parameter - - Requirements - - Description - - Default -
- custodian - - A compile-time constant of type std::size_t. - - The index of the parameter which is the dependency in the lifetime - relationship to be established. Zero indicates the result object; 1 - indicates the first argument. If used to wrap a member function, - parameter 1 is the target object (*this). Note that if - the target Python object type doesn't support weak references, a - Python TypeError exception will be raised when the C++ - object being wrapped is called. -
- ward - - A compile-time constant of type std::size_t. - - The index of the parameter which is the dependent in the lifetime - relationship to be established. Zero indicates the result object; 1 - indicates the first argument. If used to wrap a member function, - parameter 1 is the target object (*this). -
- Base - - A model of CallPolicies - - Used for policy - composition. - - default_call_policies -
-

- Class - template with_custodian_and_ward_postcall synopsis -

-
-namespace boost { namespace python
-{
-   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
-   struct with_custodian_and_ward_postcall : Base
-   {
-      static PyObject* postcall(PyObject* args, PyObject* result);
-   };
-}}
-
-

- Class - with_custodian_and_ward_postcall static functions -

-
-PyObject* postcall(PyObject* args, PyObject* result);
-
-
-
- Requires: PyTuple_Check(args) - != 0, result != 0. -
-
- Effects: Makes the lifetime of the object indicated by - ward dependent on the lifetime of the object indicated - by custodian. -
-
- Returns: 0 and PyErr_Occurred() != 0 - upon failure, true otherwise. -
-
-

- Example -

The following example shows how - with_custodian_and_ward_postcall is used by the library to - implement return_internal_reference - -
-template <std::size_t owner_arg = 1, class Base = default_call_policies>
-struct return_internal_reference
-    : with_custodian_and_ward_postcall<0, owner_arg, Base>
-{
-   typedef reference_existing_object result_converter;
-};
-
-

- Revised - - 13 November, 2002 - -

-

- © Copyright Dave - Abrahams 2002. All Rights Reserved. -

- - diff --git a/example/Attic/project.zip b/example/Attic/project.zip deleted file mode 100644 index d863defd..00000000 Binary files a/example/Attic/project.zip and /dev/null differ diff --git a/example/Jamfile b/example/Jamfile deleted file mode 100644 index 83664cc2..00000000 --- a/example/Jamfile +++ /dev/null @@ -1,61 +0,0 @@ -# Specify our location in the boost project hierarchy -subproject libs/python/example ; - -# Declares the following targets: -# -# 1. an extension module called "getting_started1", which is -# built from "getting_started1.cpp". Built by default -# -# 2. A test target called my-test.test which runs -# test_getting_started1.py with the extension module above. Built -# when out-of date, but only if invoked by name or if the global -# "test" target is invoked. -# -# 3. A test target called my-test.run wihch runs the above test -# unconditionally. Built only when invoked by name. -# -# To see verbose test output, add "-sPYTHON_TEST_ARGS=-v" to the bjam -# command-line before the first target. -# - -# Include definitions needed for Python modules -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -# ----- getting_started1 ------- - -# Declare a Python extension called getting_started1 -extension getting_started1 -: # sources - getting_started1.cpp - - # dependencies - ../build/boost_python - ; - -# Declare a test for the extension module -boost-python-runtest test1 - : # Python test driver - test_getting_started1.py - # extension modules to use - getting_started1 ; - - - -# ----- getting_started2 ------- - -# Declare a Python extension called getting_started2 -extension getting_started2 -: # sources - getting_started2.cpp - - # dependencies - ../build/boost_python - ; - -# Declare a test for the extension module -boost-python-runtest test2 - : # Python test driver - test_getting_started2.py - # extension modules to use - getting_started2 ; \ No newline at end of file diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 deleted file mode 100644 index cf7a2972..00000000 --- a/example/Jamfile.v2 +++ /dev/null @@ -1,12 +0,0 @@ - -use-project /boost/python : ../build ; - -project - : requirements @/boost/python/boost_python - ; - -python-extension getting_started1 : getting_started1.cpp : true ; -python-extension getting_started2 : getting_started2.cpp : true ; - -exe embedding_test : embedding_test.cpp : BOOST_PYTHON_DYNAMIC_LIB true ; - diff --git a/example/README b/example/README deleted file mode 100644 index ab22de54..00000000 --- a/example/README +++ /dev/null @@ -1,6 +0,0 @@ -To get started with the Boost Python Library, use the examples -getting_started1.cpp and getting_started2.cpp. - - bjam -sTOOLS=your-toolset test - -in this directory will build and run the examples. diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp deleted file mode 100644 index bdb79edc..00000000 --- a/example/getting_started1.cpp +++ /dev/null @@ -1,23 +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 -#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(getting_started1) -{ - // Add regular functions to the module. - python::def("greet", greet); - python::def("square", square); -} diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp deleted file mode 100644 index bec7447e..00000000 --- a/example/getting_started2.cpp +++ /dev/null @@ -1,40 +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 -#include -#include - -BOOST_PYTHON_MODULE(getting_started2) -{ - using namespace boost::python; - class_("hello", init()) - // Add a regular member function. - .def("greet", &hello::greet) - // Add invite() as a member of hello! - .def("invite", invite) - ; - - // Also add invite() as a regular function to the module. - def("invite", invite); -} diff --git a/example/project.zip b/example/project.zip deleted file mode 100644 index d863defd..00000000 Binary files a/example/project.zip and /dev/null differ diff --git a/example/tutorial/Jamfile b/example/tutorial/Jamfile deleted file mode 100644 index c05463c1..00000000 --- a/example/tutorial/Jamfile +++ /dev/null @@ -1,15 +0,0 @@ -# Hello World Example from the tutorial -# [Joel de Guzman 10/9/2002] - -# Specify our location in the boost project hierarchy -subproject libs/python/example/tutorial ; - -# Include definitions needed for Python modules -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -extension hello # Declare a Python extension called hello -: hello.cpp # source - ../../build/boost_python # dependencies - ; - diff --git a/example/tutorial/hello.cpp b/example/tutorial/hello.cpp deleted file mode 100644 index 01ed60c3..00000000 --- a/example/tutorial/hello.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Hello World Example from the tutorial -// [Joel de Guzman 10/9/2002] - -char const* greet() -{ - return "hello, world"; -} - -#include -#include -using namespace boost::python; - -BOOST_PYTHON_MODULE(hello) -{ - def("greet", greet); -} - diff --git a/include/boost/python/arg_from_python.hpp b/include/boost/python/arg_from_python.hpp deleted file mode 100755 index b30c70eb..00000000 --- a/include/boost/python/arg_from_python.hpp +++ /dev/null @@ -1,84 +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 ARG_FROM_PYTHON_DWA2002128_HPP -# define ARG_FROM_PYTHON_DWA2002128_HPP - -# include -# include - -namespace boost { namespace python { - -template -struct arg_from_python - : converter::select_arg_from_python::type -{ - typedef typename converter::select_arg_from_python::type base; - arg_from_python(PyObject*); -}; - -// specialization for PyObject* -template <> -struct arg_from_python -{ - typedef PyObject* result_type; - - arg_from_python(PyObject*) {} - bool convertible() const { return true; } - PyObject* operator()(PyObject* source) const { return source; } -}; - -template <> -struct arg_from_python -{ - typedef PyObject* const& result_type; - arg_from_python(PyObject*) {} - bool convertible() const { return true; } - PyObject*const& operator()(PyObject*const& source) const { return source; } -}; - -namespace detail -{ - // - // Meta-iterators for use with caller<> - // - - // temporary hack - template struct nullary : T - { - nullary(PyObject* x) : T(x), m_p(x) {} - typename T::result_type operator()() { return this->T::operator()(m_p); } - PyObject* m_p; - }; - - // An MPL metafunction class which returns arg_from_python - struct gen_arg_from_python - { - template struct apply - { - typedef nullary > type; - }; - }; - - // An MPL iterator over an endless sequence of gen_arg_from_python - struct args_from_python - { - typedef gen_arg_from_python type; - typedef args_from_python next; - }; -} - -// -// implementations -// -template -inline arg_from_python::arg_from_python(PyObject* source) - : base(source) -{ -} - -}} // namespace boost::python - -#endif // ARG_FROM_PYTHON_DWA2002128_HPP diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp deleted file mode 100644 index b2b76c87..00000000 --- a/include/boost/python/args.hpp +++ /dev/null @@ -1,112 +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 KEYWORDS_DWA2002323_HPP -# define KEYWORDS_DWA2002323_HPP - -# include -# include -# include -# include - -# include -# include -# include - -# include -# include -# include -# include - -# include -# include - -# include -# include - - -namespace boost { namespace python { - -namespace detail -{ - template - struct keywords - { - BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords); - - keyword_range range() const - { - return keyword_range(elements, elements + nkeywords); - } - - keyword elements[nkeywords]; - }; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct is_keywords - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; - - template - struct is_keywords > - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - template - struct is_reference_to_keywords - { - BOOST_STATIC_CONSTANT(bool, is_ref = is_reference::value); - typedef typename remove_reference::type deref; - typedef typename remove_cv::type key_t; - BOOST_STATIC_CONSTANT(bool, is_key = is_keywords::value); - BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key)); - - typedef mpl::bool_ type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) - }; -# else - typedef char (&yes_keywords_t)[1]; - typedef char (&no_keywords_t)[2]; - - no_keywords_t is_keywords_test(...); - - template - yes_keywords_t is_keywords_test(void (*)(keywords&)); - - template - yes_keywords_t is_keywords_test(void (*)(keywords const&)); - - template - class is_reference_to_keywords - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_keywords_test( (void (*)(T))0 )) - == sizeof(detail::yes_keywords_t))); - - typedef mpl::bool_ type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) - }; -# endif -} - -# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n; -# define BOOST_PP_LOCAL_MACRO(n) \ -inline detail::keywords args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \ -{ \ - detail::keywords result; \ - BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \ - return result; \ -} -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) -# include BOOST_PP_LOCAL_ITERATE() - -}} // namespace boost::python - - -# endif // KEYWORDS_DWA2002323_HPP diff --git a/include/boost/python/args_fwd.hpp b/include/boost/python/args_fwd.hpp deleted file mode 100644 index e310f761..00000000 --- a/include/boost/python/args_fwd.hpp +++ /dev/null @@ -1,47 +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 ARGS_FWD_DWA2002927_HPP -# define ARGS_FWD_DWA2002927_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - struct keyword - { - char const* name; - handle<> default_value; - }; - - template struct keywords; - - typedef std::pair keyword_range; - - template <> - struct keywords<0> - { - BOOST_STATIC_CONSTANT(std::size_t, size = 0); - static keyword_range range() { return keyword_range(); } - }; - - namespace error - { - template - struct more_keywords_than_function_arguments - { - typedef char too_many_keywords[keywords > function_args ? -1 : 1]; - }; - } -} - -}} // namespace boost::python - -#endif // ARGS_FWD_DWA2002927_HPP diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp deleted file mode 100644 index 75a14525..00000000 --- a/include/boost/python/back_reference.hpp +++ /dev/null @@ -1,101 +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 BACK_REFERENCE_DWA2002510_HPP -# define BACK_REFERENCE_DWA2002510_HPP - -# include -# include -# include - -namespace boost { namespace python { - -template -struct back_reference -{ - private: // types - typedef typename detail::dependent::type source_t; - public: - typedef T type; - - back_reference(PyObject*, T); - source_t const& source() const; - T get() const; - private: - source_t m_source; - T m_value; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class is_back_reference -{ - public: - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -class is_back_reference > -{ - public: - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -# else // no partial specialization - -}} // namespace boost::python - -#include - -namespace boost { namespace python { - -namespace detail -{ - typedef char (&yes_back_reference_t)[1]; - typedef char (&no_back_reference_t)[2]; - - no_back_reference_t is_back_reference_test(...); - - template - yes_back_reference_t is_back_reference_test(boost::type< back_reference >); -} - -template -class is_back_reference -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_back_reference_test(boost::type())) - == sizeof(detail::yes_back_reference_t))); -}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -// -// implementations -// -template -back_reference::back_reference(PyObject* p, T x) - : m_source(detail::borrowed_reference(p)) - , m_value(x) -{ -} - -template -typename back_reference::source_t const& back_reference::source() const -{ - return m_source; -} - -template -T back_reference::get() const -{ - return m_value; -} - -}} // namespace boost::python - -#endif // BACK_REFERENCE_DWA2002510_HPP diff --git a/include/boost/python/base_type_traits.hpp b/include/boost/python/base_type_traits.hpp deleted file mode 100755 index cae9ebc2..00000000 --- a/include/boost/python/base_type_traits.hpp +++ /dev/null @@ -1,36 +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 BASE_TYPE_TRAITS_DWA2002614_HPP -# define BASE_TYPE_TRAITS_DWA2002614_HPP - -namespace boost { namespace python { - -namespace detail -{ - struct unspecialized {}; -} - -// Derive from unspecialized so we can detect whether traits are -// specialized -template struct base_type_traits - : detail::unspecialized -{}; - -template <> -struct base_type_traits -{ - typedef PyObject type; -}; - -template <> -struct base_type_traits -{ - typedef PyObject type; -}; - -}} // namespace boost::python - -#endif // BASE_TYPE_TRAITS_DWA2002614_HPP diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp deleted file mode 100644 index 5b6ea8c3..00000000 --- a/include/boost/python/bases.hpp +++ /dev/null @@ -1,67 +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 BASES_DWA2002321_HPP -# define BASES_DWA2002321_HPP -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -# define BOOST_PYTHON_BASE_PARAMS BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, Base) - - // A type list for specifying bases - template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename Base, mpl::void_) > - struct bases : detail::type_list< BOOST_PYTHON_BASE_PARAMS >::type - {}; - - namespace detail - { -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template struct specifies_bases - : mpl::false_ - { - }; - - template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class Base) > - struct specifies_bases< bases< BOOST_PYTHON_BASE_PARAMS > > - : mpl::true_ - { - }; -# else - template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class Base) > - static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&); - - static char (& is_bases_helper(...) )[256]; - - template - struct specifies_bases - { - private: - static typename add_reference::type make(); - BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference::value); - public: - BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1)); - typedef mpl::bool_ type; - }; -# endif - template > - struct select_bases - : mpl::if_< - specifies_bases - , T - , Prev - > - { - }; - } -# undef BOOST_PYTHON_BASE_PARAMS -}} // namespace boost::python - -#endif // BASES_DWA2002321_HPP diff --git a/include/boost/python/borrowed.hpp b/include/boost/python/borrowed.hpp deleted file mode 100755 index 10b1b5d1..00000000 --- a/include/boost/python/borrowed.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 BORROWED_DWA2002614_HPP -# define BORROWED_DWA2002614_HPP -# include - -namespace boost { namespace python { - -template -inline python::detail::borrowed* borrowed(T* p) -{ - return (detail::borrowed*)p; -} - -}} // namespace boost::python - -#endif // BORROWED_DWA2002614_HPP diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp deleted file mode 100644 index d80cba3c..00000000 --- a/include/boost/python/call.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef CALL_DWA2002411_HPP -# define CALL_DWA2002411_HPP - -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \ - , converter::arg_to_python(a##n).get() - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET - -}} // namespace boost::python - -# endif // CALL_DWA2002411_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -# line BOOST_PP_LINE(__LINE__, call.hpp) - -# define N BOOST_PP_ITERATION() - -template < - class R - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > -typename detail::returnable::type -call(PyObject* callable - BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) - , boost::type* = 0 - ) -{ - converter::return_from_python converter; - return converter( - PyEval_CallFunction( - callable - , const_cast("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")") - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) - )); -} - -# undef N - -#endif diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp deleted file mode 100644 index 347f866c..00000000 --- a/include/boost/python/call_method.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -# ifndef CALL_METHOD_DWA2002411_HPP -# define CALL_METHOD_DWA2002411_HPP - -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \ - , converter::arg_to_python(a##n).get() - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET - -}} // namespace boost::python - -# endif // CALL_METHOD_DWA2002411_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -# line BOOST_PP_LINE(__LINE__, call_method.hpp) - -# define N BOOST_PP_ITERATION() - -template < - class R - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > -typename detail::returnable::type -call_method(PyObject* self, char const* name - BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) - , boost::type* = 0 - ) -{ - converter::return_from_python converter; - return converter( - PyEval_CallMethod( - self - , const_cast(name) - , const_cast("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")") - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) - )); -} - -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/cast.hpp b/include/boost/python/cast.hpp deleted file mode 100755 index d20cbd3a..00000000 --- a/include/boost/python/cast.hpp +++ /dev/null @@ -1,106 +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 CAST_DWA200269_HPP -# define CAST_DWA200269_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template inline Target* upcast_impl(Source*, Target*); - - template - inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*) - { - return p; - } - - template - inline Target* upcast(Source* p, no_convertible, no_convertible, Target*) - { - typedef typename base_type_traits::type base; - - return detail::upcast_impl((base*)p, (Target*)0); - } - - template - struct upcaster - { - template - static inline T* execute(T* x, T*) { return x; } - }; - - template <> - struct upcaster - { - template - static inline Target* execute(Source* x, Target*) - { - return detail::upcast( - x, detail::convertible::check(x) - , detail::convertible::check((Target*)0) - , (Target*)0); - } - }; - - - template - inline Target* downcast(Source* p, yes_convertible) - { - return static_cast(p); - } - - template - inline Target* downcast(Source* p, no_convertible, boost::type* = 0) - { - typedef typename base_type_traits::type base; - return (Target*)detail::downcast(p, convertible::check((base*)0)); - } - - template - inline void assert_castable(boost::type* = 0) - { - typedef char must_be_a_complete_type[sizeof(T)]; - } - - template - inline Target* upcast_impl(Source* x, Target*) - { - typedef typename add_cv::type src_t; - typedef typename add_cv::type target_t; - static bool const same = is_same::value; - - return detail::upcaster::execute(x, (Target*)0); - } -} - -template -inline Target* upcast(Source* x, Target* = 0) -{ - detail::assert_castable(); - detail::assert_castable(); - return detail::upcast_impl(x, (Target*)0); - -} - -template -inline Target* downcast(Source* x, Target* = 0) -{ - detail::assert_castable(); - detail::assert_castable(); - return detail::downcast(x, detail::convertible::check((Target*)0)); -} - -}} // namespace boost::python - -#endif // CAST_DWA200269_HPP diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp deleted file mode 100644 index fd1d7411..00000000 --- a/include/boost/python/class.hpp +++ /dev/null @@ -1,548 +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 -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -# include -# include - -namespace boost { namespace python { - -enum no_init_t { no_init }; - -namespace detail -{ - // This function object is used with mpl::for_each to write the id - // of the type a pointer to which is passed as its 2nd compile-time - // argument. into the iterator pointed to by its runtime argument - struct write_type_id - { - write_type_id(type_info**p) : p(p) {} - - // Here's the runtime behavior - template - void operator()(T*) const - { - *(*p)++ = type_id(); - } - - type_info** p; - }; - - template - struct select_held_type; - - template - struct has_noncopyable; - - template - struct operator_; - - // Register to_python converters for a class T. The first argument - // will be mpl::true_ unless noncopyable was specified as a - // class_<...> template parameter. The 2nd argument is a pointer to - // the type of holder that must be created. The 3rd argument is a - // reference to the Python type object to be created. - template - inline void register_class_to_python(mpl::true_ copyable, SelectHolder selector, T* = 0) - { - typedef typename SelectHolder::type holder; - force_instantiate(objects::class_cref_wrapper >()); - SelectHolder::register_(); - } - - template - inline void register_class_to_python(mpl::false_ copyable, SelectHolder selector, T* = 0) - { - SelectHolder::register_(); - } - - namespace error - { - // - // A meta-assertion mechanism which prints nice error messages and - // backtraces on lots of compilers. Usage: - // - // assertion::failed - // - // where C is an MPL metafunction class - // - - template struct assertion_failed { }; - template struct assertion_ok { typedef C failed; }; - - template - struct assertion - : mpl::if_, assertion_failed >::type - {}; - - // - // Checks for validity of arguments used to define virtual - // functions with default implementations. - // - - template - void not_a_derived_class_member(Default) {} - - template - struct virtual_function_default - { - template - static void - must_be_derived_class_member(Default const&) - { - typedef typename assertion > >::failed test0; -# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - typedef typename assertion >::failed test1; -# endif - typedef typename assertion >::failed test2; - not_a_derived_class_member(Fn()); - } - }; - } -} - -// This is the primary mechanism through which users will expose -// C++ classes to Python. -template < - class T // class being wrapped - , class X1 // = detail::not_specified - , class X2 // = detail::not_specified - , class X3 // = detail::not_specified - > -class class_ : public objects::class_base -{ - public: // types - typedef objects::class_base base; - typedef T wrapped_type; - - typedef class_ self; - BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); - - typedef typename detail::select_held_type< - X1, typename detail::select_held_type< - X2, typename detail::select_held_type< - X3 - >::type>::type>::type held_type; - - typedef objects::select_holder holder_selector; - - private: // types - - typedef typename detail::select_bases::type - >::type - >::type bases; - - - // A helper class which will contain an array of id objects to be - // passed to the base class constructor - struct id_vector - { - id_vector() - { - // Stick the derived class id into the first element of the array - ids[0] = type_id(); - - // Write the rest of the elements into succeeding positions. - type_info* p = ids + 1; - mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer*)0); - } - - BOOST_STATIC_CONSTANT( - std::size_t, size = mpl::size::value + 1); - type_info ids[size]; - }; - friend struct id_vector; - - public: // constructors - - // Construct with the class name, with or without docstring, and default __init__() function - class_(char const* name, char const* doc = 0); - - // Construct with class name, no docstring, and an uncallable __init__ function - class_(char const* name, no_init_t); - - // Construct with class name, docstring, and an uncallable __init__ function - class_(char const* name, char const* doc, no_init_t); - - // Construct with class name and init<> function - template - inline class_(char const* name, init_base const& i) - : base(name, id_vector::size, id_vector().ids) - { - this->register_(); - define_init(*this, i.derived()); - this->set_instance_size(holder_selector::additional_size()); - } - - // Construct with class name, docstring and init<> function - template - inline class_(char const* name, char const* doc, init_base const& i) - : base(name, id_vector::size, id_vector().ids, doc) - { - this->register_(); - define_init(*this, i.derived()); - this->set_instance_size(holder_selector::additional_size()); - } - - public: // member functions - - // Define additional constructors - template - self& def(init_base const& i) - { - define_init(*this, i.derived()); - return *this; - } - - // 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) - { - this->def_impl(name, f, detail::def_helper(0), &f); - return *this; - } - - template - self& def(char const* name, A1 a1, A2 const& a2) - { - this->def_maybe_overloads(name, a1, a2, &a2); - return *this; - } - - template - self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2) - { - // The arguments are definitely: - // def(name, function, policy, doc_string) - // def(name, function, doc_string, policy) - - this->def_impl( - name, fn - , detail::def_helper(a1,a2) - , &fn); - - return *this; - } - - template - self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3) - { - this->def_impl( - name, fn - , detail::def_helper(a1,a2,a3) - , &fn); - - return *this; - } - - template - self& def(detail::operator_ const& op) - { - typedef detail::operator_ op_t; - return this->def(op.name(), &op_t::template apply::execute); - } - - // - // Data member access - // - template - self& def_readonly(char const* name, D B::*pm_) - { - D T::*pm = pm_; - this->add_property(name, make_getter(pm)); - return *this; - } - - template - self& def_readwrite(char const* name, D B::*pm_) - { - D T::*pm = pm_; - return this->add_property(name, make_getter(pm), make_setter(pm)); - } - - // Property creation - template - self& add_property(char const* name, Get fget) - { - base::add_property( - name - , object( - detail::member_function_cast::stage1(fget).stage2((T*)0).stage3(fget) - ) - ); - - return *this; - } - - template - self& add_property(char const* name, Get fget, Set fset) - { - base::add_property( - name - , object( - detail::member_function_cast::stage1(fget).stage2((T*)0).stage3(fget) - ) - , object( - detail::member_function_cast::stage1(fset).stage2((T*)0).stage3(fset) - ) - ); - return *this; - } - - template - self& setattr(char const* name, U const& x) - { - this->base::setattr(name, object(x)); - return *this; - } - - // Pickle support - template - self& def_pickle(PickleSuiteType const& x) - { - error_messages::must_be_derived_from_pickle_suite(x); - detail::pickle_suite_finalize::register_( - *this, - &PickleSuiteType::getinitargs, - &PickleSuiteType::getstate, - &PickleSuiteType::setstate, - PickleSuiteType::getstate_manages_dict()); - return *this; - } - - self& staticmethod(char const* name) - { - this->make_method_static(name); - return *this; - } - private: // helper functions - - inline void register_() const; - - // - // These two overloads discriminate between def() as applied to - // things which are already wrapped into callable python::object - // instances and everything else. - // - template - inline void def_impl( - char const* name - , F f - , detail::def_helper const& helper - , object const*) - { - // It's too late to specify anything other than docstrings, if - // the callable object is already wrapped. - BOOST_STATIC_ASSERT( - (is_same::value - || detail::is_string_literal::value)); - - objects::add_to_namespace(*this, name, f, helper.doc()); - } - - template - inline void def_impl( - char const* name - , Fn fn - , Helper const& helper - , ...) - { - objects::add_to_namespace( - *this, name, - make_function( - // This bit of nastiness casts F to a member function of T if possible. - detail::member_function_cast::stage1(fn).stage2((T*)0).stage3(fn) - , helper.policies(), helper.keywords()) - , helper.doc()); - - this->def_default(name, fn, helper, mpl::bool_()); - } - - // - // These two overloads handle the definition of default - // implementation overloads for virtual functions. The second one - // handles the case where no default implementation was specified. - // - template - inline void def_default( - char const* name - , Fn fn - , Helper const& helper - , mpl::bool_) - { - detail::error::virtual_function_default::must_be_derived_class_member( - helper.default_implementation()); - - objects::add_to_namespace( - *this, name, - make_function( - helper.default_implementation(), helper.policies(), helper.keywords()) - ); - } - - template - inline void def_default(char const*, Fn, Helper const&, mpl::bool_) - { } - - // - // These two overloads discriminate between def() as applied to - // regular functions and def() as applied to the result of - // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to - // discriminate. - // - template - void def_maybe_overloads( - char const* name - , SigT sig - , OverloadsT const& overloads - , detail::overloads_base const*) - - { - // convert sig to a type_list (see detail::get_signature in signature.hpp) - // before calling detail::define_with_defaults. - detail::define_with_defaults( - name, overloads, *this, detail::get_signature(sig)); - } - - template - void def_maybe_overloads( - char const* name - , Fn fn - , A1 const& a1 - , ...) - { - this->def_impl( - name, fn - , detail::def_helper(a1) - , &fn); - - } -}; - - -// -// implementations -// - -// register converters -template -inline void class_::register_() const -{ - objects::register_class_from_python(); - - detail::register_class_to_python( - mpl::bool_() -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - , holder_selector::execute((held_type*)0) -# elif BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - , holder_selector::type() -# else - , typename holder_selector::type() -# endif - ); -} - -template -inline class_::class_(char const* name, char const* doc) - : base(name, id_vector::size, id_vector().ids, doc) -{ - this->register_(); - this->set_instance_size(holder_selector::additional_size()); -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - holder_selector::execute((held_type*)0).assert_default_constructible(); -# else - holder_selector::type::assert_default_constructible(); -# endif - this->def(init<>()); -} - -template -inline class_::class_(char const* name, no_init_t) - : base(name, id_vector::size, id_vector().ids) -{ - this->register_(); - this->def_no_init(); -} - -template -inline class_::class_(char const* name, char const* doc, no_init_t) - : base(name, id_vector::size, id_vector().ids, doc) -{ - this->register_(); - this->def_no_init(); -} - -namespace detail -{ - template - struct has_noncopyable - : mpl::or_< - is_same - , is_same - , is_same - > - {}; - - - template - struct select_held_type - : mpl::if_< - mpl::or_< - specifies_bases - , is_same - > - , Prev - , T - > - { - }; -} - -}} // namespace boost::python - -#endif // CLASS_DWA200216_HPP diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp deleted file mode 100644 index 8aaec6a6..00000000 --- a/include/boost/python/class_fwd.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 CLASS_FWD_DWA200222_HPP -# define CLASS_FWD_DWA200222_HPP -# include - -namespace boost { namespace python { - -template < - class T // class being wrapped - // arbitrarily-ordered optional arguments. Full qualification needed for MSVC6 - , class X1 = ::boost::python::detail::not_specified - , class X2 = ::boost::python::detail::not_specified - , class X3 = ::boost::python::detail::not_specified - > -class class_; - -}} // namespace boost::python - -#endif // CLASS_FWD_DWA200222_HPP diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp deleted file mode 100755 index b835e633..00000000 --- a/include/boost/python/converter/arg_from_python.hpp +++ /dev/null @@ -1,341 +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 ARG_FROM_PYTHON_DWA2002127_HPP -# define ARG_FROM_PYTHON_DWA2002127_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python -{ - template struct arg_from_python; -}} - -// This header defines Python->C++ function argument converters, -// parametrized on the argument type. - -namespace boost { namespace python { namespace converter { - -// -// lvalue converters -// -// These require that an lvalue of the type U is stored somewhere in -// the Python object being converted. - -// Used when T == U*const& -template -struct pointer_cref_arg_from_python -{ - typedef T result_type; - - pointer_cref_arg_from_python(PyObject*); - T operator()(PyObject*) const; - bool convertible() const; - - private: // storage for a U* - // needed because not all compilers will let us declare U* as the - // return type of operator() -- we return U*const& instead - typename python::detail::referent_storage::type m_result; -}; - -// Base class for pointer and reference converters -struct arg_lvalue_from_python_base -{ - public: // member functions - arg_lvalue_from_python_base(void* result); - bool convertible() const; - - protected: // member functions - void*const& result() const; - - private: // data members - void* m_result; -}; - -// Used when T == U* -template -struct pointer_arg_from_python : arg_lvalue_from_python_base -{ - typedef T result_type; - - pointer_arg_from_python(PyObject*); - T operator()(PyObject*) const; -}; - -// Used when T == U& and (T != V const& or T == W volatile&) -template -struct reference_arg_from_python : arg_lvalue_from_python_base -{ - typedef T result_type; - - reference_arg_from_python(PyObject*); - T operator()(PyObject*) const; -}; - -// =================== - -// -// rvalue converters -// -// These require only that an object of type T can be created from -// the given Python object, but not that the T object exist -// somewhere in storage. -// - -// Used when T is a plain value (non-pointer, non-reference) type or -// a (non-volatile) const reference to a plain value type. -template -struct arg_rvalue_from_python -{ - typedef typename boost::add_reference< - T - // We can't add_const here, or it would be impossible to pass - // auto_ptr args from Python to C++ - >::type result_type; - - arg_rvalue_from_python(PyObject*); - bool convertible() const; - -# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196 - typename arg_rvalue_from_python:: -# endif - result_type operator()(PyObject*); - - private: - rvalue_from_python_data m_data; -}; - - -// ================== - -// Converts to a (PyObject*,T) bundle, for when you need a reference -// back to the Python object -template -struct back_reference_arg_from_python - : boost::python::arg_from_python -{ - typedef T result_type; - - back_reference_arg_from_python(PyObject*); - T operator()(PyObject*); - private: - typedef boost::python::arg_from_python base; -}; - - -// ================== - -// This metafunction selects the appropriate arg_from_python converter -// type for an argument of type T. -template -struct select_arg_from_python -{ - BOOST_STATIC_CONSTANT( - bool, obj_mgr = is_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, obj_mgr_ref = is_reference_to_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ptr_cref - = boost::python::detail::is_reference_to_pointer::value - && boost::python::detail::is_reference_to_const::value - && !boost::python::detail::is_reference_to_volatile::value); - - - BOOST_STATIC_CONSTANT( - bool, ref = - boost::python::detail::is_reference_to_non_const::value - || boost::python::detail::is_reference_to_volatile::value); - - BOOST_STATIC_CONSTANT( - bool, back_ref = - boost::python::is_back_reference::value); - - typedef typename mpl::if_c< - obj_mgr - , object_manager_value_arg_from_python - , typename mpl::if_c< - obj_mgr_ref - , object_manager_ref_arg_from_python - , typename mpl::if_c< - ptr - , pointer_arg_from_python - , typename mpl::if_c< - ptr_cref - , pointer_cref_arg_from_python - , typename mpl::if_c< - ref - , reference_arg_from_python - , typename mpl::if_c< - back_ref - , back_reference_arg_from_python - , arg_rvalue_from_python - >::type - >::type - >::type - >::type - >::type - >::type type; -}; - -// ================== - -// -// implementations -// - -// arg_lvalue_from_python_base -// -inline arg_lvalue_from_python_base::arg_lvalue_from_python_base(void* result) - : m_result(result) -{ -} - -inline bool arg_lvalue_from_python_base::convertible() const -{ - return m_result != 0; -} - -inline void*const& arg_lvalue_from_python_base::result() const -{ - return m_result; -} - -// pointer_cref_arg_from_python -// -namespace detail -{ - // null_ptr_reference -- a function returning a reference to a null - // pointer of type U. Needed so that extractors for T*const& can - // convert Python's None. - template - struct null_ptr_owner - { - static T value; - }; - template T null_ptr_owner::value = 0; - - template - inline U& null_ptr_reference(U&(*)()) - { - return null_ptr_owner::value; - } -} - -template -inline pointer_cref_arg_from_python::pointer_cref_arg_from_python(PyObject* p) -{ - // T == U*const&: store a U* in the m_result storage. Nonzero - // indicates success. If find returns nonzero, it's a pointer to - // a U object. - python::detail::write_void_ptr_reference( - m_result.bytes - , p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee::converters) - , (T(*)())0); -} - -template -inline bool pointer_cref_arg_from_python::convertible() const -{ - return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0; -} -template -inline T pointer_cref_arg_from_python::operator()(PyObject* p) const -{ - return (p == Py_None) // None ==> 0 - ? detail::null_ptr_reference((T(*)())0) - // Otherwise, return a U*const& to the m_result storage. - : python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); -} - -// pointer_arg_from_python -// -template -inline pointer_arg_from_python::pointer_arg_from_python(PyObject* p) - : arg_lvalue_from_python_base( - p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee::converters)) -{ -} - -template -inline T pointer_arg_from_python::operator()(PyObject* p) const -{ - return (p == Py_None) ? 0 : T(result()); -} - -// reference_arg_from_python -// -template -inline reference_arg_from_python::reference_arg_from_python(PyObject* p) - : arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered::converters)) -{ -} - -template -inline T reference_arg_from_python::operator()(PyObject*) const -{ - return python::detail::void_ptr_to_reference(result(), (T(*)())0); -} - - -// arg_rvalue_from_python -// -template -inline arg_rvalue_from_python::arg_rvalue_from_python(PyObject* obj) - : m_data(converter::rvalue_from_python_stage1(obj, registered::converters)) -{ -} - -template -inline bool arg_rvalue_from_python::convertible() const -{ - return m_data.stage1.convertible != 0; -} - -template -inline typename arg_rvalue_from_python::result_type -arg_rvalue_from_python::operator()(PyObject* p) -{ - if (m_data.stage1.construct != 0) - m_data.stage1.construct(p, &m_data.stage1); - - return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); -} - -// back_reference_arg_from_python -// -template -back_reference_arg_from_python::back_reference_arg_from_python(PyObject* x) - : base(x) -{ -} - -template -inline T -back_reference_arg_from_python::operator()(PyObject* x) -{ - return T(x, base::operator()(x)); -} - -}}} // namespace boost::python::converter - -#endif // ARG_FROM_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp deleted file mode 100755 index 3d62eccd..00000000 --- a/include/boost/python/converter/arg_to_python.hpp +++ /dev/null @@ -1,262 +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 ARG_TO_PYTHON_DWA200265_HPP -# define ARG_TO_PYTHON_DWA200265_HPP - -# include -# include -# include - -# include -# include -# include -# include -// Bring in specializations -# include - -# include - -# include - -# include -# include -# include -# include - -# include -# include -# include - - -# include - -namespace boost { namespace python { namespace converter { - -template struct is_object_manager; - -namespace detail -{ - template - struct function_arg_to_python : handle<> - { - function_arg_to_python(T const& x); - }; - - template - struct reference_arg_to_python : handle<> - { - reference_arg_to_python(T& x); - private: - static PyObject* get_object(T& x); - }; - - template - struct shared_ptr_arg_to_python : handle<> - { - shared_ptr_arg_to_python(T const& x); - private: - static PyObject* get_object(T& x); - }; - - template - struct value_arg_to_python : arg_to_python_base - { - // Throw an exception if the conversion can't succeed - value_arg_to_python(T const&); - }; - - template - struct pointer_deep_arg_to_python : arg_to_python_base - { - // Throw an exception if the conversion can't succeed - pointer_deep_arg_to_python(Ptr); - }; - - template - struct pointer_shallow_arg_to_python : handle<> - { - // Throw an exception if the conversion can't succeed - pointer_shallow_arg_to_python(Ptr); - private: - static PyObject* get_object(Ptr p); - }; - - // Convert types that manage a Python object to_python - template - struct object_manager_arg_to_python - { - object_manager_arg_to_python(T const& x) : m_src(x) {} - - PyObject* get() const - { - return python::upcast(get_managed_object(m_src, tag)); - } - - private: - T const& m_src; - }; - - template - struct select_arg_to_python - { - typedef typename unwrap_reference::type unwrapped_referent; - typedef typename unwrap_pointer::type unwrapped_ptr; - - typedef typename mpl::if_< - // Special handling for char const[N]; interpret them as char - // const* for the sake of conversion - python::detail::is_string_literal - , arg_to_python - - , typename mpl::if_< - python::detail::value_is_shared_ptr - , shared_ptr_arg_to_python - - , typename mpl::if_< - mpl::or_< - is_function - , python::detail::is_pointer_to_function - , is_member_function_pointer - > - , function_arg_to_python - - , typename mpl::if_< - is_object_manager - , object_manager_arg_to_python - - , typename mpl::if_< - is_pointer - , pointer_deep_arg_to_python - - , typename mpl::if_< - is_pointer_wrapper - , pointer_shallow_arg_to_python - - , typename mpl::if_< - is_reference_wrapper - , reference_arg_to_python - , value_arg_to_python - >::type - >::type - >::type - >::type - >::type - >::type - >::type - - type; - }; -} - -template -struct arg_to_python - : detail::select_arg_to_python::type -{ - typedef typename detail::select_arg_to_python::type base; - public: // member functions - // Throw an exception if the conversion can't succeed - arg_to_python(T const& x); -}; - -// -// implementations -// -namespace detail -{ - // reject_raw_object_ptr -- cause a compile-time error if the user - // should pass a raw Python object pointer - using python::detail::yes_convertible; - using python::detail::no_convertible; - using python::detail::unspecialized; - - template struct cannot_convert_raw_PyObject; - - template - struct reject_raw_object_helper - { - static void error(Convertibility) - { - cannot_convert_raw_PyObject::to_python_use_handle_instead(); - } - static void error(...) {} - }; - - template - inline void reject_raw_object_ptr(T*) - { - reject_raw_object_helper::error( - python::detail::convertible::check((T*)0)); - - typedef typename remove_cv::type value_type; - - reject_raw_object_helper::error( - python::detail::convertible::check( - (base_type_traits*)0 - )); - } - // --------- - - template - inline function_arg_to_python::function_arg_to_python(T const& x) - : handle<>(python::objects::make_function_handle(x)) - { - } - - template - inline value_arg_to_python::value_arg_to_python(T const& x) - : arg_to_python_base(&x, registered::converters) - { - } - - template - inline pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr x) - : arg_to_python_base(x, registered_pointee::converters) - { - detail::reject_raw_object_ptr((Ptr)0); - } - - template - inline PyObject* reference_arg_to_python::get_object(T& x) - { - to_python_indirect convert; - return convert(x); - } - - template - inline reference_arg_to_python::reference_arg_to_python(T& x) - : handle<>(reference_arg_to_python::get_object(x)) - { - } - - template - inline shared_ptr_arg_to_python::shared_ptr_arg_to_python(T const& x) - : handle<>(shared_ptr_to_python(x)) - { - } - - template - inline pointer_shallow_arg_to_python::pointer_shallow_arg_to_python(Ptr x) - : handle<>(pointer_shallow_arg_to_python::get_object(x)) - { - detail::reject_raw_object_ptr((Ptr)0); - } - - template - inline PyObject* pointer_shallow_arg_to_python::get_object(Ptr x) - { - to_python_indirect convert; - return convert(x); - } -} - -template -inline arg_to_python::arg_to_python(T const& x) - : base(x) -{} - -}}} // namespace boost::python::converter - -#endif // ARG_TO_PYTHON_DWA200265_HPP diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp deleted file mode 100755 index 850da036..00000000 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARG_TO_PYTHON_BASE_DWA200237_HPP -# define ARG_TO_PYTHON_BASE_DWA200237_HPP -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -namespace detail -{ - struct BOOST_PYTHON_DECL arg_to_python_base -# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179 - : handle<> -# endif - { - arg_to_python_base(void const volatile* source, registration const&); -# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102179 - PyObject* get() const { return m_ptr.get(); } - PyObject* release() { return m_ptr.release(); } - private: - handle<> m_ptr; -# endif - }; -} - -}}} // namespace boost::python::converter - -#endif // ARG_TO_PYTHON_BASE_DWA200237_HPP diff --git a/include/boost/python/converter/as_to_python_function.hpp b/include/boost/python/converter/as_to_python_function.hpp deleted file mode 100644 index 3c2f97e5..00000000 --- a/include/boost/python/converter/as_to_python_function.hpp +++ /dev/null @@ -1,50 +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 AS_TO_PYTHON_FUNCTION_DWA2002121_HPP -# define AS_TO_PYTHON_FUNCTION_DWA2002121_HPP -# include - -namespace boost { namespace python { namespace converter { - -// Given a typesafe to_python conversion function, produces a -// to_python_function_t which can be registered in the usual way. -template -struct as_to_python_function -{ - // Assertion functions used to prevent wrapping of converters - // which take non-const reference parameters. The T* argument in - // the first overload ensures it isn't used in case T is a - // reference. - template - static int convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0); - template - static int convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...); - - static PyObject* convert(void const* x) - { - BOOST_STATIC_ASSERT( - sizeof( - convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L)) - == sizeof(int)); - - // Yes, the const_cast below opens a hole in const-correctness, - // but it's needed to convert auto_ptr to python. - // - // How big a hole is it? It allows ToPython::convert() to be - // a function which modifies its argument. The upshot is that - // client converters applied to const objects may invoke - // undefined behavior. The damage, however, is limited by the - // use of the assertion function. Thus, the only way this can - // modify its argument is if T is an auto_ptr-like type. There - // is still a const-correctness hole w.r.t. auto_ptr const, - // but c'est la vie. - return ToPython::convert(*const_cast(static_cast(x))); - } -}; - -}}} // namespace boost::python::converter - -#endif // AS_TO_PYTHON_FUNCTION_DWA2002121_HPP diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp deleted file mode 100644 index 9772079c..00000000 --- a/include/boost/python/converter/builtin_converters.hpp +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP -# define BUILTIN_CONVERTERS_DWA2002124_HPP -# include -# include -# include -# include -# include -# include - -// Since all we can use to decide how to convert an object to_python -// is its C++ type, there can be only one such converter for each -// type. Therefore, for built-in conversions we can bypass registry -// lookups using explicit specializations of arg_to_python and -// result_to_python. - -namespace boost { namespace python { - -namespace converter -{ - template struct arg_to_python; - BOOST_PYTHON_DECL PyObject* do_return_to_python(char); - BOOST_PYTHON_DECL PyObject* do_return_to_python(char const*); - BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject*); - BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject*); -} - -// Provide specializations of to_python_value -template struct to_python_value; - -namespace detail -{ - // Since there's no registry lookup, always report the existence of - // a converter. - struct builtin_to_python - { - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = false); - }; -} - -// Use expr to create the PyObject corresponding to x -# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - inline PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - inline PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; - -# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \ - namespace converter \ - { \ - template <> struct arg_to_python< T > \ - : handle<> \ - { \ - arg_to_python(T const& x) \ - : python::handle<>(expr) {} \ - }; \ - } - -// Specialize argument and return value converters for T using expr -# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ - BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \ - BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr) - -// Specialize converters for signed and unsigned T to Python Int -# 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 \ - , static_cast(x) > static_cast( \ - std::numeric_limits::max()) \ - ? PyLong_FromUnsignedLong(x) \ - : PyInt_FromLong(x)) - -// Bool is not signed. -BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x)) - -// note: handles signed char and unsigned char, but not char (see below) -BOOST_PYTHON_TO_INT(char) - -BOOST_PYTHON_TO_INT(short) -BOOST_PYTHON_TO_INT(int) -BOOST_PYTHON_TO_INT(long) - -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG -BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, PyLong_FromLongLong(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong(x)) -# endif - -# undef BOOST_TO_PYTHON_INT - -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromStringAndSize(x.c_str(),x.size())) -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_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) - -namespace converter -{ - - void initialize_builtin_converters(); - -} - -}} // namespace boost::python::converter - -#endif // BUILTIN_CONVERTERS_DWA2002124_HPP diff --git a/include/boost/python/converter/constructor_function.hpp b/include/boost/python/converter/constructor_function.hpp deleted file mode 100644 index f3c49bd4..00000000 --- a/include/boost/python/converter/constructor_function.hpp +++ /dev/null @@ -1,18 +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 CONSTRUCTOR_FUNCTION_DWA200278_HPP -# define CONSTRUCTOR_FUNCTION_DWA200278_HPP - -namespace boost { namespace python { namespace converter { - -// Declares the type of functions used to construct C++ objects for -// rvalue from_python conversions. -struct rvalue_from_python_stage1_data; -typedef void (*constructor_function)(PyObject* source, rvalue_from_python_stage1_data*); - -}}} // namespace boost::python::converter - -#endif // CONSTRUCTOR_FUNCTION_DWA200278_HPP diff --git a/include/boost/python/converter/convertible_function.hpp b/include/boost/python/converter/convertible_function.hpp deleted file mode 100644 index 98db1cfb..00000000 --- a/include/boost/python/converter/convertible_function.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 CONVERTIBLE_FUNCTION_DWA200278_HPP -# define CONVERTIBLE_FUNCTION_DWA200278_HPP - -namespace boost { namespace python { namespace converter { - -typedef void* (*convertible_function)(PyObject*); - -}}} // namespace boost::python::converter - -#endif // CONVERTIBLE_FUNCTION_DWA200278_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp deleted file mode 100644 index 32a7431e..00000000 --- a/include/boost/python/converter/from_python.hpp +++ /dev/null @@ -1,43 +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 FIND_FROM_PYTHON_DWA2002223_HPP -# define FIND_FROM_PYTHON_DWA2002223_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - - -BOOST_PYTHON_DECL void* get_lvalue_from_python( - PyObject* source, registration const&); - -BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python( - PyObject* source, registration const&); - -BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( - PyObject* source, registration const&); - -BOOST_PYTHON_DECL void* rvalue_from_python_stage2( - PyObject* source, rvalue_from_python_stage1_data&, registration const&); - -BOOST_PYTHON_DECL void* rvalue_result_from_python( - PyObject*, rvalue_from_python_stage1_data&); - -BOOST_PYTHON_DECL void* reference_result_from_python(PyObject*, registration const&); -BOOST_PYTHON_DECL void* pointer_result_from_python(PyObject*, registration const&); - -BOOST_PYTHON_DECL void void_result_from_python(PyObject*); - -BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject*, registration const&); -BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject*, registration const&); - -}}} // namespace boost::python::converter - -#endif // FIND_FROM_PYTHON_DWA2002223_HPP diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp deleted file mode 100644 index fd588f6b..00000000 --- a/include/boost/python/converter/implicit.hpp +++ /dev/null @@ -1,43 +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 IMPLICIT_DWA2002326_HPP -# define IMPLICIT_DWA2002326_HPP - -# include -# include -# include - -# include - -namespace boost { namespace python { namespace converter { - -template -struct implicit -{ - static void* convertible(PyObject* obj) - { - // Find a converter which can produce a Source instance from - // obj. The user has told us that Source can be converted to - // Target, and instantiating construct() below, ensures that - // at compile-time. - return implicit_rvalue_convertible_from_python(obj, registered::converters) - ? obj : 0; - } - - static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) - { - void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; - - new (storage) Target(extract(obj)()); - - // record successful construction - data->convertible = storage; - } -}; - -}}} // namespace boost::python::converter - -#endif // IMPLICIT_DWA2002326_HPP diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp deleted file mode 100644 index dfda753d..00000000 --- a/include/boost/python/converter/obj_mgr_arg_from_python.hpp +++ /dev/null @@ -1,122 +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 OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP -# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP - -# include -# include -# include -# include -# include -# include -# include - -// -// arg_from_python converters for Python type wrappers, to be used as -// base classes for specializations. -// -namespace boost { namespace python { namespace converter { - -template -struct object_manager_value_arg_from_python -{ - typedef T result_type; - - object_manager_value_arg_from_python(PyObject*); - bool convertible() const; - T operator()(PyObject*) const; - private: - PyObject* m_source; -}; - -// Used for converting reference-to-object-manager arguments from -// python. The process used here is a little bit odd. Upon -// construction, we build the object manager object in the m_result -// object, *forcing* it to accept the source Python object by casting -// its pointer to detail::borrowed_reference. This is supposed to -// bypass any type checking of the source object. The convertible -// check then extracts the owned object and checks it. If the check -// fails, nothing else in the program ever gets to touch this strange -// "forced" object. -template -struct object_manager_ref_arg_from_python -{ - typedef Ref result_type; - - object_manager_ref_arg_from_python(PyObject*); - bool convertible() const; - Ref operator()(PyObject*) const; - ~object_manager_ref_arg_from_python(); - private: - typename python::detail::referent_storage::type m_result; -}; - -// -// implementations -// - -template -inline object_manager_value_arg_from_python::object_manager_value_arg_from_python(PyObject* x) - : m_source(x) -{ -} - -template -inline bool object_manager_value_arg_from_python::convertible() const -{ - return object_manager_traits::check(m_source); -} - -template -inline T object_manager_value_arg_from_python::operator()(PyObject* x) const -{ - return T(python::detail::borrowed_reference(x)); -} - -template -inline object_manager_ref_arg_from_python::object_manager_ref_arg_from_python(PyObject* x) -{ -# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 - // needed for warning suppression - python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x); - python::detail::construct_referent(&m_result.bytes, x_); -# else - python::detail::construct_referent(&m_result.bytes, (python::detail::borrowed_reference)x); -# endif -} - -template -inline object_manager_ref_arg_from_python::~object_manager_ref_arg_from_python() -{ - python::detail::destroy_referent(this->m_result.bytes); -} - -namespace detail -{ - template - inline bool object_manager_ref_check(T const& x) - { - return object_manager_traits::check(get_managed_object(x, tag)); - } -} - -template -inline bool object_manager_ref_arg_from_python::convertible() const -{ - return detail::object_manager_ref_check( - python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0)); -} - -template -inline Ref object_manager_ref_arg_from_python::operator()(PyObject*) const -{ - return python::detail::void_ptr_to_reference( - this->m_result.bytes, (Ref(*)())0); -} - -}}} // namespace boost::python::converter - -#endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp deleted file mode 100755 index 7c8c9084..00000000 --- a/include/boost/python/converter/object_manager.hpp +++ /dev/null @@ -1,231 +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 OBJECT_MANAGER_DWA2002614_HPP -# define OBJECT_MANAGER_DWA2002614_HPP - -# include -# include -# include -# include -# include -# include -# include - -// Facilities for dealing with types which always manage Python -// objects. Some examples are object, list, str, et. al. Different -// to_python/from_python conversion rules apply here because in -// contrast to other types which are typically embedded inside a -// Python object, these are wrapped around a Python object. For most -// object managers T, a C++ non-const T reference argument does not -// imply the existence of a T lvalue embedded in the corresponding -// Python argument, since mutating member functions on T actually only -// modify the held Python object. -// -// handle is an object manager, though strictly speaking it should -// not be. In other words, even though mutating member functions of -// hanlde actually modify the handle and not the T object, -// handle& arguments of wrapped functions will bind to "rvalues" -// wrapping the actual Python argument, just as with other object -// manager classes. Making an exception for handle is simply not -// worth the trouble. -// -// borrowed cv* is an object manager so that we can use the general -// to_python mechanisms to convert raw Python object pointers to -// python, without the usual semantic problems of using raw pointers. - - -// Object Manager Concept requirements: -// -// T is an Object Manager -// p is a PyObject* -// x is a T -// -// * object_manager_traits::is_specialized == true -// -// * T(detail::borrowed_reference(p)) -// Manages p without checking its type -// -// * get_managed_object(x, boost::python::tag) -// Convertible to PyObject* -// -// Additional requirements if T can be converted from_python: -// -// * T(object_manager_traits::adopt(p)) -// steals a reference to p, or throws a TypeError exception if -// p doesn't have an appropriate type. May assume p is non-null -// -// * X::check(p) -// convertible to bool. True iff T(X::construct(p)) will not -// throw. - -// Forward declarations -// -namespace boost { namespace python -{ - namespace api - { - class object; - } -}} - -namespace boost { namespace python { namespace converter { - - -// Specializations for handle -template -struct handle_object_manager_traits - : pyobject_traits -{ - private: - typedef pyobject_traits base; - - public: - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - - // Initialize with a null_ok pointer for efficiency, bypassing the - // null check since the source is always non-null. - static null_ok* adopt(PyObject* p) - { - return python::allow_null(base::checked_downcast(p)); - } -}; - -template -struct default_object_manager_traits -{ - BOOST_STATIC_CONSTANT( - bool, is_specialized = python::detail::is_borrowed_ptr::value - ); -}; - -template -struct object_manager_traits - : mpl::if_c< - is_handle::value - , handle_object_manager_traits - , default_object_manager_traits - >::type -{ -}; - -// -// Traits for detecting whether a type is an object manager or a -// (cv-qualified) reference to an object manager. -// - -template -struct is_object_manager - : mpl::bool_::is_specialized> -{ -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_reference_to_object_manager - : mpl::false_ -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; -# else - -namespace detail -{ - typedef char (&yes_reference_to_object_manager)[1]; - typedef char (&no_reference_to_object_manager)[2]; - - // A number of nastinesses go on here in order to work around MSVC6 - // bugs. - template - struct is_object_manager_help - { - typedef typename mpl::if_< - is_object_manager - , yes_reference_to_object_manager - , no_reference_to_object_manager - >::type type; - - // If we just use the type instead of the result of calling this - // function, VC6 will ICE. - static type call(); - }; - - // A set of overloads for each cv-qualification. The same argument - // is passed twice: the first one is used to unwind the cv*, and the - // second one is used to avoid relying on partial ordering for - // overload resolution. - template - typename is_object_manager_help - is_object_manager_helper(U*, void*); - - template - typename is_object_manager_help - is_object_manager_helper(U const*, void const*); - - template - typename is_object_manager_help - is_object_manager_helper(U volatile*, void volatile*); - - template - typename is_object_manager_help - is_object_manager_helper(U const volatile*, void const volatile*); - - template - struct is_reference_to_object_manager_nonref - : mpl::false_ - { - }; - - template - struct is_reference_to_object_manager_ref - { - static T sample_object; - BOOST_STATIC_CONSTANT( - bool, value - = (sizeof(is_object_manager_helper(&sample_object, &sample_object).call()) - == sizeof(detail::yes_reference_to_object_manager) - ) - ); - typedef mpl::bool_ type; - }; -} - -template -struct is_reference_to_object_manager - : mpl::if_< - is_reference - , detail::is_reference_to_object_manager_ref - , detail::is_reference_to_object_manager_nonref - >::type -{ -}; -# endif - -}}} // namespace boost::python::converter - -#endif // OBJECT_MANAGER_DWA2002614_HPP diff --git a/include/boost/python/converter/pointer_type_id.hpp b/include/boost/python/converter/pointer_type_id.hpp deleted file mode 100644 index 01e55977..00000000 --- a/include/boost/python/converter/pointer_type_id.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef POINTER_TYPE_ID_DWA2002222_HPP -# define POINTER_TYPE_ID_DWA2002222_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - template - struct pointer_typeid_select - { - template - static inline type_info execute(T*(*)() = 0) - { - return type_id(); - } - }; - - template <> - struct pointer_typeid_select - { - template - static inline type_info execute(T* const volatile&(*)() = 0) - { - return type_id(); - } - - template - static inline type_info execute(T*volatile&(*)() = 0) - { - return type_id(); - } - - template - static inline type_info execute(T*const&(*)() = 0) - { - return type_id(); - } - - template - static inline type_info execute(T*&(*)() = 0) - { - return type_id(); - } - }; -} - -// Usage: pointer_type_id() -// -// Returns a type_info associated with the type pointed -// to by T, which may be a pointer or a reference to a pointer. -template -type_info pointer_type_id(T(*)() = 0) -{ - return detail::pointer_typeid_select< - is_reference::value - >::execute((T(*)())0); -} - -}}} // namespace boost::python::converter - -#endif // POINTER_TYPE_ID_DWA2002222_HPP diff --git a/include/boost/python/converter/pyobject_traits.hpp b/include/boost/python/converter/pyobject_traits.hpp deleted file mode 100644 index f975360c..00000000 --- a/include/boost/python/converter/pyobject_traits.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 PYOBJECT_TRAITS_DWA2002720_HPP -# define PYOBJECT_TRAITS_DWA2002720_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -template struct pyobject_traits; - -template <> -struct pyobject_traits -{ - // All objects are convertible to PyObject - static bool check(PyObject*) { return true; } - static PyObject* checked_downcast(PyObject* x) { return x; } -}; - -// -// Specializations -// - -# define BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(T) \ - template <> struct pyobject_traits \ - : pyobject_type {} - -// This is not an exhaustive list; should be expanded. -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple); - -}}} // namespace boost::python::converter - -#endif // PYOBJECT_TRAITS_DWA2002720_HPP diff --git a/include/boost/python/converter/pyobject_type.hpp b/include/boost/python/converter/pyobject_type.hpp deleted file mode 100644 index 59ff7244..00000000 --- a/include/boost/python/converter/pyobject_type.hpp +++ /dev/null @@ -1,37 +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 PYOBJECT_TYPE_DWA2002720_HPP -# define PYOBJECT_TYPE_DWA2002720_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*); - -// Used as a base class for specializations which need to provide -// Python type checking capability. -template -struct pyobject_type -{ - static bool check(PyObject* x) - { - return ::PyObject_IsInstance(x, (PyObject*)pytype); - } - - static Object* checked_downcast(PyObject* x) - { - return python::downcast( - (checked_downcast_impl)(x, pytype) - ); - } -}; - -}}} // namespace boost::python::converter - -#endif // PYOBJECT_TYPE_DWA2002720_HPP diff --git a/include/boost/python/converter/pytype_arg_from_python.hpp b/include/boost/python/converter/pytype_arg_from_python.hpp deleted file mode 100644 index ade4fd66..00000000 --- a/include/boost/python/converter/pytype_arg_from_python.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 PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP -# define PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP - -# include - -// -// arg_from_python converters for Python type wrappers, to be used as -// base classes for specializations. -// -namespace boost { namespace python { namespace converter { - -template -struct pytype_arg_from_python -{ - pytype_arg_from_python(PyObject*); - bool convertible() const; - private: - PyObject* m_src; -}; - -// rvalue converter base -template -struct pytype_wrapper_value_arg_from_python - : pytype_arg_from_python -{ - typedef Wrapper result_type; - - pytype_wrapper_value_arg_from_python(PyObject*); - Wrapper operator()(PyObject*) const; -}; - -// Special case for Wrapper& - must store an lvalue internally. This -// OK because the entire state of the object is actually in the Python -// object. -template -struct pytype_wrapper_ref_arg_from_python - : pytype_arg_from_python -{ - typedef Wrapper& result_type; - - pytype_wrapper_ref_arg_from_python(PyObject*); - Wrapper& operator()(PyObject*) const; - private: - mutable Wrapper m_result; -}; - -// -// implementations -// - -template -inline pytype_arg_from_python::pytype_arg_from_python(PyObject* x) - : m_src(x) -{ -} - -template -inline bool pytype_arg_from_python::convertible() const -{ - return PyObject_IsInstance(m_src, (PyObject*)python_type); -} - -template -pytype_wrapper_value_arg_from_python::pytype_wrapper_value_arg_from_python( - PyObject* p) - : pytype_arg_from_python(p) -{ -} - -template -Wrapper pytype_wrapper_value_arg_from_python::operator()( - PyObject* x) const -{ - return Wrapper(python::detail::borrowed_reference(x)); -} - -template -pytype_wrapper_ref_arg_from_python::pytype_wrapper_ref_arg_from_python( - PyObject* p) - : pytype_arg_from_python(p) - , m_result(python::detail::borrowed_reference(p)) -{ -} - -template -Wrapper& pytype_wrapper_ref_arg_from_python::operator()( - PyObject* x) const -{ - return m_result; -} - -}}} // namespace boost::python::converter - -#endif // PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP diff --git a/include/boost/python/converter/pytype_object_mgr_traits.hpp b/include/boost/python/converter/pytype_object_mgr_traits.hpp deleted file mode 100644 index 94cbae64..00000000 --- a/include/boost/python/converter/pytype_object_mgr_traits.hpp +++ /dev/null @@ -1,43 +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 PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP -# define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// Provide a forward declaration as a convenience for clients, who all -// need it. -template struct object_manager_traits; - -// Derive specializations of object_manager_traits from this class -// when T is an object manager for a particular Python type hierarchy. -// -template -struct pytype_object_manager_traits - : pyobject_type // provides check() -{ - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - static inline python::detail::new_reference adopt(PyObject*); -}; - -// -// implementations -// -template -inline python::detail::new_reference pytype_object_manager_traits::adopt(PyObject* x) -{ - return python::detail::new_reference(python::pytype_check(pytype, x)); -} - -}}} // namespace boost::python::converter - -#endif // PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP diff --git a/include/boost/python/converter/registered.hpp b/include/boost/python/converter/registered.hpp deleted file mode 100644 index 2d3daa99..00000000 --- a/include/boost/python/converter/registered.hpp +++ /dev/null @@ -1,54 +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 REGISTERED_DWA2002710_HPP -# define REGISTERED_DWA2002710_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -namespace detail -{ - template - struct registered_base - { - static registration const& converters; - }; -} - -template -struct registered - : detail::registered_base< - typename add_reference< - typename add_cv::type - >::type - > -{ -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -// collapses a few more types to the same static instance -template -struct registered : registered {}; -# endif - -// -// implementations -// -namespace detail -{ - template - registration const& registered_base::converters - = registry::lookup(type_id()); -} -}}} // namespace boost::python::converter - -#endif // REGISTERED_DWA2002710_HPP diff --git a/include/boost/python/converter/registered_pointee.hpp b/include/boost/python/converter/registered_pointee.hpp deleted file mode 100644 index 861cf724..00000000 --- a/include/boost/python/converter/registered_pointee.hpp +++ /dev/null @@ -1,63 +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 REGISTERED_POINTEE_DWA2002710_HPP -# define REGISTERED_POINTEE_DWA2002710_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct registered_pointee - : registered< - typename remove_pointer< - typename remove_cv< - typename remove_reference::type - >::type - >::type - > -{ -}; -# else -namespace detail -{ - template - struct registered_pointee_base - { - static registration const& converters; - }; -} - -template -struct registered_pointee - : detail::registered_pointee_base< - typename add_reference< - typename add_cv::type - >::type - > -{ -}; - -// -// implementations -// -namespace detail -{ - template - registration const& registered_pointee_base::converters - = registry::lookup(pointer_type_id()); -} - -# endif -}}} // namespace boost::python::converter - -#endif // REGISTERED_POINTEE_DWA2002710_HPP diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp deleted file mode 100644 index 973e052f..00000000 --- a/include/boost/python/converter/registrations.hpp +++ /dev/null @@ -1,85 +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 REGISTRATIONS_DWA2002223_HPP -# define REGISTRATIONS_DWA2002223_HPP - -# include - -# include -# include -# include - -# include - -# include - -namespace boost { namespace python { namespace converter { - -struct lvalue_from_python_chain -{ - convertible_function convert; - lvalue_from_python_chain* next; -}; - -struct rvalue_from_python_chain -{ - convertible_function convertible; - constructor_function construct; - rvalue_from_python_chain* next; -}; - -struct BOOST_PYTHON_DECL registration -{ - public: // member functions - explicit registration(type_info); - - // Convert the appropriately-typed data to Python - PyObject* to_python(void const volatile*) const; - - // Return the class object, or raise an appropriate Python - // exception if no class has been registered. - PyTypeObject* get_class_object() const; - - public: // data members. So sue me. - const python::type_info target_type; - - // The chain of eligible from_python converters when an lvalue is required - lvalue_from_python_chain* lvalue_chain; - - // The chain of eligible from_python converters when an rvalue is acceptable - rvalue_from_python_chain* rvalue_chain; - - // The class object associated with this type - PyTypeObject* m_class_object; - - // The unique to_python converter for the associated C++ type. - to_python_function_t m_to_python; - -# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - private: - void operator=(registration); // This is not defined, and just keeps MWCW happy. -# endif -}; - -// -// implementations -// -inline registration::registration(type_info target_type) - : target_type(target_type) - , lvalue_chain(0) - , rvalue_chain(0) - , m_class_object(0) - , m_to_python(0) -{} - -inline bool operator<(registration const& lhs, registration const& rhs) -{ - return lhs.target_type < rhs.target_type; -} - -}}} // namespace boost::python::converter - -#endif // REGISTRATIONS_DWA2002223_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp deleted file mode 100644 index b71c949a..00000000 --- a/include/boost/python/converter/registry.hpp +++ /dev/null @@ -1,52 +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 -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -// This namespace acts as a sort of singleton -namespace registry -{ - // Get the registration corresponding to the type, creating it if neccessary - BOOST_PYTHON_DECL registration const& lookup(type_info); - - // Return a pointer to the corresponding registration, if one exists - BOOST_PYTHON_DECL registration const* query(type_info); - - BOOST_PYTHON_DECL void insert(to_python_function_t, type_info); - - // Insert an lvalue from_python converter - BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info); - - // Insert an rvalue from_python converter - BOOST_PYTHON_DECL void insert( - convertible_function - , constructor_function - , type_info - ); - - // Insert an rvalue from_python converter at the tail of the - // chain. Used for implicit conversions - BOOST_PYTHON_DECL void push_back( - convertible_function - , constructor_function - , type_info - ); -} - -}}} // namespace boost::python::converter - -#endif // REGISTRY_DWA20011127_HPP diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp deleted file mode 100755 index 69c7a71b..00000000 --- a/include/boost/python/converter/return_from_python.hpp +++ /dev/null @@ -1,161 +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_FROM_PYTHON_DWA200265_HPP -# define RETURN_FROM_PYTHON_DWA200265_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -template struct is_object_manager; - -namespace detail -{ - template - struct return_pointer_from_python - { - typedef T result_type; - T operator()(PyObject*) const; - }; - - template - struct return_reference_from_python - { - typedef T result_type; - T operator()(PyObject*) const; - }; - - template - struct return_rvalue_from_python - { - typedef T result_type; - - return_rvalue_from_python(); - result_type operator()(PyObject*); - private: - rvalue_from_python_data m_data; - }; - - template - struct return_object_manager_from_python - { - typedef T result_type; - result_type operator()(PyObject*) const; - }; - - template - struct select_return_from_python - { - BOOST_STATIC_CONSTANT( - bool, obj_mgr = is_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ref = is_reference::value); - - typedef typename mpl::if_c< - obj_mgr - , return_object_manager_from_python - , typename mpl::if_c< - ptr - , return_pointer_from_python - , typename mpl::if_c< - ref - , return_reference_from_python - , return_rvalue_from_python - >::type - >::type - >::type type; - }; -} - -template -struct return_from_python - : detail::select_return_from_python::type -{ -}; - -// Specialization as a convenience for call and call_method -template <> -struct return_from_python -{ - typedef python::detail::returnable::type result_type; - - result_type operator()(PyObject* x) const - { - (void_result_from_python)(x); -# ifdef BOOST_NO_VOID_RETURNS - return result_type(); -# endif - } -}; - -// -// Implementations -// -namespace detail -{ - template - inline return_rvalue_from_python::return_rvalue_from_python() - : m_data( - const_cast(®istered::converters) - ) - { - } - - template - inline typename return_rvalue_from_python::result_type - return_rvalue_from_python::operator()(PyObject* obj) - { - // Take possession of the source object here. If the result is in - // fact going to be a copy of an lvalue embedded in the object, - // and we take possession inside rvalue_result_from_python, it - // will be destroyed too early. - handle<> holder(obj); - - return *(T*) - (rvalue_result_from_python)(obj, m_data.stage1); - } - - template - inline T return_reference_from_python::operator()(PyObject* obj) const - { - return python::detail::void_ptr_to_reference( - (reference_result_from_python)(obj, registered::converters) - , (T(*)())0); - } - - template - inline T return_pointer_from_python::operator()(PyObject* obj) const - { - return T( - (pointer_result_from_python)(obj, registered_pointee::converters) - ); - } - - template - inline T return_object_manager_from_python::operator()(PyObject* obj) const - { - return T( - object_manager_traits::adopt(expect_non_null(obj)) - ); - } -} - -}}} // namespace boost::python::converter - -#endif // RETURN_FROM_PYTHON_DWA200265_HPP diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp deleted file mode 100644 index 91b5afd8..00000000 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ /dev/null @@ -1,141 +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 -# include -# include -# include - -// Data management for potential rvalue conversions from Python to C++ -// types. When a client requests a conversion to T* or T&, we -// generally require that an object of type T exists in the source -// Python object, and the code here does not apply**. This implements -// conversions which may create new temporaries of type T. The classic -// example is a conversion which converts a Python tuple to a -// std::vector. Since no std::vector lvalue exists in the Python -// object -- it must be created "on-the-fly" by the converter, and -// which must manage the lifetime of the created object. -// -// Note that the client is not precluded from using a registered -// lvalue conversion to T in this case. In other words, we will -// happily accept a Python object which /does/ contain a std::vector -// lvalue, provided an appropriate converter is registered. So, while -// this is an rvalue conversion from the client's point-of-view, the -// converter registry may serve up lvalue or rvalue conversions for -// the target type. -// -// ** C++ argument from_python conversions to T const& are an -// exception to the rule for references: since in C++, const -// references can bind to temporary rvalues, we allow rvalue -// converters to be chosen when the target type is T const& for some -// T. -namespace boost { namespace python { namespace converter { - -// Conversions begin by filling in and returning a copy of this -// structure. The process looks up a converter in the rvalue converter -// registry for the target type. It calls the convertible() function -// of each registered converter, passing the source PyObject* as an -// argument, until a non-null result is returned. This result goes in -// the convertible field, and the converter's construct() function is -// stored in the construct field. -// -// If no appropriate converter is found, conversion fails and the -// convertible field is null. When used in argument conversion for -// wrapped C++ functions, it causes overload resolution to reject the -// current function but not to fail completely. If an exception is -// thrown, overload resolution stops and the exception propagates back -// through the caller. -// -// If an lvalue converter is matched, its convertible() function is -// expected to return a pointer to the stored T object; its -// construct() function will be NULL. The convertible() function of -// rvalue converters may return any non-singular pointer; the actual -// target object will only be available once the converter's -// construct() function is called. -struct rvalue_from_python_stage1_data -{ - void* convertible; - constructor_function construct; -}; - -// Augments rvalue_from_python_stage1_data by adding storage for -// constructing an object of remove_reference::type. The -// construct() function of rvalue converters (stored in m_construct -// above) will cast the rvalue_from_python_stage1_data to an -// appropriate instantiation of this template in order to access that -// storage. -template -struct rvalue_from_python_storage -{ - rvalue_from_python_stage1_data stage1; - - // Storage for the result, in case an rvalue must be constructed - typename python::detail::referent_storage< - typename add_reference::type - >::type storage; -}; - -// Augments rvalue_from_python_storage with a destructor. If -// stage1.convertible == storage.bytes, it indicates that an object of -// remove_reference::type has been constructed in storage and -// should will be destroyed in ~rvalue_from_python_data(). It is -// crucial that successful rvalue conversions establish this equality -// and that unsuccessful ones do not. -template -struct rvalue_from_python_data : rvalue_from_python_storage -{ -# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ - && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ - && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ - && !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */ - // This must always be a POD struct with m_data its first member. - BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage,stage1) == 0); -# endif - - // The usual constructor - rvalue_from_python_data(rvalue_from_python_stage1_data const&); - - // This constructor just sets m_convertible -- used by - // implicitly_convertible<> to perform the final step of the - // conversion, where the construct() function is already known. - rvalue_from_python_data(void* convertible); - - // Destroys any object constructed in the storage. - ~rvalue_from_python_data(); - private: - typedef typename add_reference::type>::type ref_type; -}; - -// -// Implementataions -// -template -inline rvalue_from_python_data::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1) -{ - this->stage1 = stage1; -} - -template -inline rvalue_from_python_data::rvalue_from_python_data(void* convertible) -{ - this->stage1.convertible = convertible; -} - -template -inline rvalue_from_python_data::~rvalue_from_python_data() -{ - if (this->stage1.convertible == this->storage.bytes) - python::detail::destroy_referent(this->storage.bytes); -} - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/converter/shared_ptr_deleter.hpp b/include/boost/python/converter/shared_ptr_deleter.hpp deleted file mode 100644 index f2ebfc40..00000000 --- a/include/boost/python/converter/shared_ptr_deleter.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 SHARED_PTR_DELETER_DWA2002121_HPP -# define SHARED_PTR_DELETER_DWA2002121_HPP - -namespace boost { namespace python { namespace converter { - -struct BOOST_PYTHON_DECL shared_ptr_deleter -{ - shared_ptr_deleter(handle<> owner); - ~shared_ptr_deleter(); - - void operator()(void const*); - - handle<> owner; -}; - -}}} // namespace boost::python::converter - -#endif // SHARED_PTR_DELETER_DWA2002121_HPP diff --git a/include/boost/python/converter/shared_ptr_from_python.hpp b/include/boost/python/converter/shared_ptr_from_python.hpp deleted file mode 100644 index 1535740a..00000000 --- a/include/boost/python/converter/shared_ptr_from_python.hpp +++ /dev/null @@ -1,53 +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 SHARED_PTR_FROM_PYTHON_DWA20021130_HPP -# define SHARED_PTR_FROM_PYTHON_DWA20021130_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -template -struct shared_ptr_from_python -{ - shared_ptr_from_python() - { - converter::registry::insert(&convertible, &construct, type_id >()); - } - - static shared_ptr_from_python const registration; - private: - static void* convertible(PyObject* p) - { - return p == Py_None - ? p - : converter::get_lvalue_from_python(p, registered::converters) - ; - } - - static void construct(PyObject* source, rvalue_from_python_stage1_data* data) - { - void* const storage = ((converter::rvalue_from_python_storage >*)data)->storage.bytes; - // Deal with the "None" case. - if (data->convertible == source) - new (storage) shared_ptr(); - else - new (storage) shared_ptr( - static_cast(data->convertible), - shared_ptr_deleter(handle<>(borrowed(source))) - ); - - data->convertible = storage; - } -}; - -template -shared_ptr_from_python const shared_ptr_from_python::registration; - -}}} // namespace boost::python::converter - -#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP diff --git a/include/boost/python/converter/shared_ptr_to_python.hpp b/include/boost/python/converter/shared_ptr_to_python.hpp deleted file mode 100644 index 0002fa91..00000000 --- a/include/boost/python/converter/shared_ptr_to_python.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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 SHARED_PTR_TO_PYTHON_DWA2003224_HPP -# define SHARED_PTR_TO_PYTHON_DWA2003224_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -template -PyObject* shared_ptr_to_python(shared_ptr const& x) -{ - if (shared_ptr_deleter* d = boost::get_deleter(x)) - return incref(d->owner.get()); - else - return converter::registered const&>::converters.to_python(&x); -} - -}}} // namespace boost::python::converter - -#endif // SHARED_PTR_TO_PYTHON_DWA2003224_HPP diff --git a/include/boost/python/converter/to_python_function_type.hpp b/include/boost/python/converter/to_python_function_type.hpp deleted file mode 100644 index b53ff649..00000000 --- a/include/boost/python/converter/to_python_function_type.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 TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP -# define TO_PYTHON_FUNCTION_TYPE_DWA200236_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_function_t)(void const*); - -}}} // namespace boost::python::converter - -#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP diff --git a/include/boost/python/copy_const_reference.hpp b/include/boost/python/copy_const_reference.hpp deleted file mode 100644 index 8eecd2ce..00000000 --- a/include/boost/python/copy_const_reference.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 COPY_CONST_REFERENCE_DWA2002131_HPP -# define COPY_CONST_REFERENCE_DWA2002131_HPP -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct copy_const_reference_expects_a_const_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template struct to_python_value; - -struct copy_const_reference -{ - template - struct apply - { - typedef typename mpl::if_c< - detail::is_reference_to_const::value - , to_python_value - , detail::copy_const_reference_expects_a_const_reference_return_type - >::type type; - }; -}; - - -}} // namespace boost::python - -#endif // COPY_CONST_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/copy_non_const_reference.hpp b/include/boost/python/copy_non_const_reference.hpp deleted file mode 100644 index 53c576e0..00000000 --- a/include/boost/python/copy_non_const_reference.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 COPY_NON_CONST_REFERENCE_DWA2002131_HPP -# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct copy_non_const_reference_expects_a_non_const_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template struct to_python_value; - -struct copy_non_const_reference -{ - template - struct apply - { - typedef typename mpl::if_c< - boost::python::detail::is_reference_to_non_const::value - , to_python_value - , detail::copy_non_const_reference_expects_a_non_const_reference_return_type - >::type type; - }; -}; - - -}} // namespace boost::python - -#endif // COPY_NON_CONST_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp deleted file mode 100644 index 9c4574b4..00000000 --- a/include/boost/python/data_members.hpp +++ /dev/null @@ -1,144 +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 DATA_MEMBERS_DWA2002328_HPP -# define DATA_MEMBERS_DWA2002328_HPP - -# include -# include -# include -# include - -# include - -# include - -# include -# include -# include - -# include -# include -# include - -# include - -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct member - { - static PyObject* get(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) - { - arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename Policies::result_converter result_converter; - typedef typename boost::add_reference::type source; - typename mpl::apply1::type cr; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (c0(PyTuple_GET_ITEM(args_, 0)))->*pm ); - - return policies.postcall(args_, result); - } - - static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) - { - // check that each of the arguments is convertible - arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - typedef typename add_const::type target1; - typedef typename add_reference::type target; - arg_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))).*pm = c1(PyTuple_GET_ITEM(args_, 1)); - - return policies.postcall(args_, detail::none()); - } - }; - - // If it's a regular class type (not an object manager or other - // type for which we have to_python specializations, use - // return_internal_reference so that we can do things like - // x.y.z = 1 - // and get the right result. - template - struct default_getter_policy - { - typedef typename add_reference< - typename add_const::type - >::type t_cref; - - BOOST_STATIC_CONSTANT( - bool, by_ref = to_python_value::uses_registry - && is_reference_to_class::value); - - typedef typename mpl::if_c< - by_ref - , return_internal_reference<> - , return_value_policy - >::type type; - }; -} - -template -object make_getter(D C::*pm) -{ - typedef typename detail::default_getter_policy::type policy; - - return objects::function_object( - ::boost::bind( - &detail::member::get, pm, _1, _2 - , policy()) - , 1); - -} - -template -object make_getter(D C::*pm, Policies const& policies) -{ - return objects::function_object( - ::boost::bind( - &detail::member::get, pm, _1, _2 - , policies) - , 1); -} - -template -object make_setter(D C::*pm) -{ - return objects::function_object( - ::boost::bind( - &detail::member::set, pm, _1, _2 - , default_call_policies()) - , 2); -} - -template -object make_setter(D C::*pm, Policies const& policies) -{ - return objects::function_object( - ::boost::bind( - &detail::member::set, pm, _1, _2 - , policies) - , 2); -} - - -}} // namespace boost::python - -#endif // DATA_MEMBERS_DWA2002328_HPP diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp deleted file mode 100644 index d0db5528..00000000 --- a/include/boost/python/def.hpp +++ /dev/null @@ -1,113 +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 DEF_DWA200292_HPP -# define DEF_DWA200292_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - namespace error - { - // Compile-time error messages - template struct multiple_functions_passed_to_def; - template <> struct multiple_functions_passed_to_def { typedef char type; }; - } - - // - // def_from_helper -- - // - // Use a def_helper to define a regular wrapped function in the current scope. - template - void def_from_helper( - char const* name, F const& fn, Helper const& helper) - { - // Must not try to use default implementations except with method definitions. - typedef typename error::multiple_functions_passed_to_def< - Helper::has_default_implementation - >::type assertion; - - detail::scope_setattr_doc( - name, boost::python::make_function( - fn - , helper.policies() - , helper.keywords()) - , helper.doc() - ); - } - - // - // These two overloads discriminate between def() as applied to - // regular functions and def() as applied to the result of - // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to - // discriminate. - // - template - void - def_maybe_overloads( - char const* name - , Fn fn - , A1 const& a1 - , ...) - { - detail::def_from_helper(name, fn, def_helper(a1)); - } - - template - void def_maybe_overloads( - char const* name - , SigT sig - , StubsT const& stubs - , detail::overloads_base const*) - { - scope current; - - detail::define_with_defaults( - name, stubs, current, detail::get_signature(sig)); - } - - template - object make_function1(T fn, ...) { return make_function(fn); } - - inline - object make_function1(object const& x, object const*) { return x; } -} - -template -void def(char const* name, Fn fn) -{ - detail::scope_setattr_doc(name, detail::make_function1(fn, &fn), 0); -} - -template -void def(char const* name, Arg1T arg1, Arg2T const& arg2) -{ - detail::def_maybe_overloads(name, arg1, arg2, &arg2); -} - -template -void def(char const* name, F f, A1 const& a1, A2 const& a2) -{ - detail::def_from_helper(name, f, detail::def_helper(a1,a2)); -} - -template -void def(char const* name, F f, A1 const& a1, A2 const& a2, A3 const& a3) -{ - detail::def_from_helper(name, f, detail::def_helper(a1,a2,a3)); -} - -}} // namespace boost::python - -#endif // DEF_DWA200292_HPP diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp deleted file mode 100644 index e796bee5..00000000 --- a/include/boost/python/default_call_policies.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP -# define DEFAULT_CALL_POLICIES_DWA2002131_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -template struct to_python_value; - -namespace detail -{ -// for "readable" error messages - template struct specify_a_return_value_policy_to_wrap_functions_returning -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -struct default_result_converter; - -struct default_call_policies -{ - // Nothing to do - static bool precall(PyObject*) - { - return true; - } - - // Pass the result through - static PyObject* postcall(PyObject*, PyObject* result) - { - return result; - } - - typedef default_result_converter result_converter; -}; - -struct default_result_converter -{ - template - struct apply - { - BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference::value || is_pointer::value); - - typedef typename mpl::if_c< - is_illegal - , detail::specify_a_return_value_policy_to_wrap_functions_returning - , boost::python::to_python_value< - typename add_reference::type>::type - > - >::type type; - }; -}; - -// Exceptions for c strings an PyObject*s -template <> -struct default_result_converter::apply -{ - typedef boost::python::to_python_value type; -}; - -template <> -struct default_result_converter::apply -{ - typedef boost::python::to_python_value type; -}; - -}} // namespace boost::python - -#endif // DEFAULT_CALL_POLICIES_DWA2002131_HPP diff --git a/include/boost/python/detail/aix_init_module.hpp b/include/boost/python/detail/aix_init_module.hpp deleted file mode 100644 index 06071c1f..00000000 --- a/include/boost/python/detail/aix_init_module.hpp +++ /dev/null @@ -1,27 +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 AIX_INIT_MODULE_DWA2002529_HPP -# define AIX_INIT_MODULE_DWA2002529_HPP -# ifdef _AIX -# include -# include -# ifdef __KCC -# include // this works around a problem in KCC 4.0f -# endif - -namespace boost { namespace python { namespace detail { - -extern "C" -{ - typedef PyObject* (*so_load_function)(char*,char*,FILE*); -} - -void aix_init_module(so_load_function, char const* name, void (*init_module)()); - -}}} // namespace boost::python::detail -# endif - -#endif // AIX_INIT_MODULE_DWA2002529_HPP diff --git a/include/boost/python/detail/api_placeholder.hpp b/include/boost/python/detail/api_placeholder.hpp deleted file mode 100644 index 38a0d029..00000000 --- a/include/boost/python/detail/api_placeholder.hpp +++ /dev/null @@ -1,19 +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 BOOST_PYTHON_API_PLACE_HOLDER_HPP -#define BOOST_PYTHON_API_PLACE_HOLDER_HPP - -namespace boost { namespace python { - - inline long len(object const& obj) - { - long result = PyObject_Length(obj.ptr()); - if (PyErr_Occurred()) throw_error_already_set(); - return result; - } -}} // namespace boost::python - -#endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP diff --git a/include/boost/python/detail/borrowed_ptr.hpp b/include/boost/python/detail/borrowed_ptr.hpp deleted file mode 100755 index 6b35c862..00000000 --- a/include/boost/python/detail/borrowed_ptr.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef BORROWED_PTR_DWA20020601_HPP -# define BORROWED_PTR_DWA20020601_HPP -// 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 - -namespace boost { namespace python { namespace detail { - -template class borrowed -{ - typedef T type; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_borrowed_ptr -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -# if !defined(__MWERKS__) || __MWERKS__ > 0x3000 -template -struct is_borrowed_ptr*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_borrowed_ptr const*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_borrowed_ptr volatile*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_borrowed_ptr const volatile*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; -# else -template -struct is_borrowed -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; -template -struct is_borrowed > -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; -template -struct is_borrowed_ptr - : is_borrowed::type> -{ -}; -# endif - -# else // no partial specialization - -typedef char (&yes_borrowed_ptr_t)[1]; -typedef char (&no_borrowed_ptr_t)[2]; - -no_borrowed_ptr_t is_borrowed_ptr_test(...); - -template -typename mpl::if_c< - is_pointer::value - , T - , int - >::type -is_borrowed_ptr_test1(boost::type); - -template -yes_borrowed_ptr_t is_borrowed_ptr_test(borrowed const volatile*); - -template -class is_borrowed_ptr -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_borrowed_ptr_test(is_borrowed_ptr_test1(boost::type()))) - == sizeof(detail::yes_borrowed_ptr_t))); -}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -} - -template -inline T* get_managed_object(detail::borrowed const volatile* p, tag_t) -{ - return (T*)p; -} - -}} // namespace boost::python::detail - -#endif // #ifndef BORROWED_PTR_DWA20020601_HPP diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp deleted file mode 100644 index 3477f64d..00000000 --- a/include/boost/python/detail/caller.hpp +++ /dev/null @@ -1,175 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// 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 CALLER_DWA20021121_HPP -# define CALLER_DWA20021121_HPP - -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include -# include -# include - -# include - -namespace boost { namespace python { namespace detail { - -// This "result converter" is really just used as -// a dispatch tag to invoke(...), selecting the appropriate -// implementation -typedef int void_result_to_python; - -// A metafunction taking an iterator FunctionIter to a metafunction -// class and an iterator ArgIter to an argument, which applies the -// result of dereferencing FunctionIter to the result of dereferencing -// ArgIter -template -struct apply_iter1 - : mpl::apply1 {}; - -// Given a model of CallPolicies and a C++ result type, this -// metafunction selects the appropriate converter to use for -// converting the result to python. -template -struct select_result_converter - : mpl::if_< - is_same - , void_result_to_python - , typename mpl::apply1::type* - > -{ -}; - - -template struct caller_arity; - -# define BOOST_PYTHON_NEXT(init,name,n) \ - typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n; - -# define BOOST_PYTHON_ARG_CONVERTER(n) \ - BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \ - BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \ - typedef typename apply_iter1::type c_t##n; \ - c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \ - if (!c##n.convertible()) \ - return 0; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY + 1, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_ARG_CONVERTER -# undef BOOST_PYTHON_NEXT - -// A metafunction returning the base class used for caller. -template -struct caller_base_select -{ - enum { arity = mpl::size::value - 1 }; - typedef typename caller_arity::template impl type; -}; - -// A function object type which wraps C++ objects as Python callable -// objects. -// -// Template Arguments: -// -// F - -// the C++ `function object' that will be called. Might -// actually be any data for which an appropriate invoke_tag() can -// be generated. invoke(...) takes care of the actual invocation syntax. -// -// ConverterGenerators - -// An MPL iterator type over a sequence of metafunction classes -// that can be applied to element 1...N of Sig to produce -// argument from_python converters for the arguments -// -// CallPolicies - -// The precall, postcall, and what kind of resultconverter to -// generate for mpl::front::type -// -// Sig - -// The `intended signature' of the function. An MPL sequence -// beginning with a result type and continuing with a list of -// argument types. -template -struct caller - : caller_base_select::type -{ - typedef typename caller_base_select< - F,ConverterGenerators,CallPolicies,Sig - >::type base; - - typedef PyObject* result_type; - - caller(F f, CallPolicies p) : base(f,p) {} -}; - - -}}} // namespace boost::python::detail - -# endif // CALLER_DWA20021121_HPP - -#else - -# define N BOOST_PP_ITERATION() - -template <> -struct caller_arity -{ - template - struct impl - { - impl(F f, Policies p) : m_data(f,p) {} - - PyObject* operator()(PyObject* args_, PyObject*) // eliminate - // this - // trailing - // keyword dict - { - typedef typename mpl::begin::type first; - typedef typename first::type result_t; - typedef typename select_result_converter::type result_converter; -# if N -# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i) -# define BOOST_PP_LOCAL_LIMITS (0, N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - // all converters have been checked. Now we can do the - // precall part of the policy - if (!m_data.second().precall(args_)) - return 0; - - typedef typename detail::invoke_tag::type tag; - - PyObject* result = detail::invoke( - tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c)); - - return m_data.second().postcall(args_, result); - } - private: - compressed_pair m_data; - }; -}; - - - -#endif // BOOST_PP_IS_ITERATING - - 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 4e2b85ab..00000000 --- a/include/boost/python/detail/config.hpp +++ /dev/null @@ -1,111 +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 - -# 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) // disable truncated debug symbols -# pragma warning (disable : 4251) // disable exported dll function -# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or 'false' -# pragma warning (disable : 4275) // non dll-interface class - -# elif defined(__ICL) && __ICL < 600 // Intel C++ 5 - -# pragma warning(disable: 985) // identifier was truncated in debug information - -# 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 - -/***************************************************************************** - * - * Set up dll import/export options: - * - ****************************************************************************/ - -// backwards compatibility: -#ifdef BOOST_PYTHON_STATIC_LIB -# define BOOST_PYTHON_STATIC_LINK -# elif !defined(BOOST_PYTHON_DYNAMIC_LIB) -# define BOOST_PYTHON_DYNAMIC_LIB -#endif - -#if defined(__MWERKS__) \ - || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \ - || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) -# define BOOST_PYTHON_NO_TEMPLATE_EXPORT -#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 - -// MinGW, at least, has some problems exporting template instantiations -# if defined(__GNUC__) && __GNUC__ < 3 && !defined(__CYGWIN__) -# define BOOST_PYTHON_NO_TEMPLATE_EXPORT -# endif - -#endif - -#ifndef BOOST_PYTHON_DECL -# define BOOST_PYTHON_DECL -#endif - -#ifndef BOOST_PYTHON_EXPORT -# define BOOST_PYTHON_EXPORT extern -#endif - -#if !defined(BOOST_PYTHON_NO_TEMPLATE_EXPORT) -# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL instantiation -#else -# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD -#endif - -#if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) -// Replace broken Tru64/cxx offsetof macro -# define BOOST_PYTHON_OFFSETOF(s_name, s_member) \ - ((size_t)__INTADDR__(&(((s_name *)0)->s_member))) -#else -# define BOOST_PYTHON_OFFSETOF offsetof -#endif - -#endif // CONFIG_DWA052200_H_ diff --git a/include/boost/python/detail/construct.hpp b/include/boost/python/detail/construct.hpp deleted file mode 100644 index f7b747f6..00000000 --- a/include/boost/python/detail/construct.hpp +++ /dev/null @@ -1,43 +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 CONSTRUCT_REFERENCE_DWA2002716_HPP -# define CONSTRUCT_REFERENCE_DWA2002716_HPP - -namespace boost { namespace python { namespace detail { - -template -void construct_pointee(void* storage, Arg& x -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - , T const volatile* -# else - , T const* -# endif - ) -{ - new (storage) T(x); -} - -template -void construct_referent_impl(void* storage, Arg& x, T&(*)()) -{ - construct_pointee(storage, x, (T*)0); -} - -template -void construct_referent(void* storage, Arg const& x, T(*tag)() = 0) -{ - construct_referent_impl(storage, x, tag); -} - -template -void construct_referent(void* storage, Arg& x, T(*tag)() = 0) -{ - construct_referent_impl(storage, x, tag); -} - -}}} // namespace boost::python::detail - -#endif // CONSTRUCT_REFERENCE_DWA2002716_HPP diff --git a/include/boost/python/detail/convertible.hpp b/include/boost/python/detail/convertible.hpp deleted file mode 100755 index 74440090..00000000 --- a/include/boost/python/detail/convertible.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 CONVERTIBLE_DWA2002614_HPP -# define CONVERTIBLE_DWA2002614_HPP - -# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241 -# include -# include -# endif - -// Supplies a runtime is_convertible check which can be used with tag -// dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible -namespace boost { namespace python { namespace detail { - -typedef char* yes_convertible; -typedef int* no_convertible; - -template -struct convertible -{ -# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 || __EDG_VERSION__ == 238 - static inline no_convertible check(...) { return 0; } - static inline yes_convertible check(Target) { return 0; } -# else - template - static inline typename mpl::if_c< - is_convertible::value - , yes_convertible - , no_convertible - >::type check(X const&) { return 0; } -# endif -}; - -}}} // namespace boost::python::detail - -#endif // CONVERTIBLE_DWA2002614_HPP diff --git a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp b/include/boost/python/detail/copy_ctor_mutates_rhs.hpp deleted file mode 100755 index b1613924..00000000 --- a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef COPY_CTOR_MUTATES_RHS_DWA2003219_HPP -# define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP - -#include -#include - -namespace boost { namespace python { namespace detail { - -template -struct copy_ctor_mutates_rhs - : is_auto_ptr -{ -}; - -}}} // namespace boost::python::detail - -#endif // COPY_CTOR_MUTATES_RHS_DWA2003219_HPP diff --git a/include/boost/python/detail/cv_category.hpp b/include/boost/python/detail/cv_category.hpp deleted file mode 100644 index f4ac4b92..00000000 --- a/include/boost/python/detail/cv_category.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CV_CATEGORY_DWA200222_HPP -# define CV_CATEGORY_DWA200222_HPP -# include - -namespace boost { namespace python { namespace detail { - -template -struct cv_tag -{ - BOOST_STATIC_CONSTANT(bool, is_const = is_const_); - BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_); -}; - -typedef cv_tag cv_unqualified; -typedef cv_tag const_; -typedef cv_tag volatile_; -typedef cv_tag const_volatile_; - -template -struct cv_category -{ - BOOST_STATIC_CONSTANT(bool, c = is_const::value); - BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); - typedef cv_tag type; -}; - -}}} // namespace boost::python::detail - -#endif // CV_CATEGORY_DWA200222_HPP diff --git a/include/boost/python/detail/decorated_type_id.hpp b/include/boost/python/detail/decorated_type_id.hpp deleted file mode 100755 index c43a4160..00000000 --- a/include/boost/python/detail/decorated_type_id.hpp +++ /dev/null @@ -1,77 +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 DECORATED_TYPE_ID_DWA2002517_HPP -# define DECORATED_TYPE_ID_DWA2002517_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -struct decorated_type_info : totally_ordered -{ - enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; - - decorated_type_info(type_info, decoration = decoration()); - - inline bool operator<(decorated_type_info const& rhs) const; - inline bool operator==(decorated_type_info const& rhs) const; - - friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); - - operator type_info const&() const; - private: // type - typedef type_info base_id_t; - - private: // data members - decoration m_decoration; - base_id_t m_base_type; -}; - -template -inline decorated_type_info decorated_type_id(boost::type* = 0) -{ - return decorated_type_info( - type_id() - , decorated_type_info::decoration( - (is_const::value || python::detail::is_reference_to_const::value - ? decorated_type_info::const_ : 0) - | (is_volatile::value || python::detail::is_reference_to_volatile::value - ? decorated_type_info::volatile_ : 0) - | (is_reference::value ? decorated_type_info::reference : 0) - ) - ); -} - -inline decorated_type_info::decorated_type_info(type_info base_t, decoration decoration) - : m_decoration(decoration) - , m_base_type(base_t) -{ -} - -inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const -{ - return m_decoration < rhs.m_decoration - || m_decoration == rhs.m_decoration - && m_base_type < rhs.m_base_type; -} - -inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const -{ - return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; -} - -inline decorated_type_info::operator type_info const&() const -{ - return m_base_type; -} - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); - -}}} // namespace boost::python::detail - -#endif // DECORATED_TYPE_ID_DWA2002517_HPP diff --git a/include/boost/python/detail/decref_guard.hpp b/include/boost/python/detail/decref_guard.hpp deleted file mode 100644 index 67455706..00000000 --- a/include/boost/python/detail/decref_guard.hpp +++ /dev/null @@ -1,22 +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 DECREF_GUARD_DWA20021220_HPP -# define DECREF_GUARD_DWA20021220_HPP - -namespace boost { namespace python { namespace detail { - -struct decref_guard -{ - decref_guard(PyObject* o) : obj(o) {} - ~decref_guard() { Py_XDECREF(obj); } - void cancel() { obj = 0; } - private: - PyObject* obj; -}; - -}}} // namespace boost::python::detail - -#endif // DECREF_GUARD_DWA20021220_HPP diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp deleted file mode 100644 index 98933bd4..00000000 --- a/include/boost/python/detail/def_helper.hpp +++ /dev/null @@ -1,212 +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 DEF_HELPER_DWA200287_HPP -# define DEF_HELPER_DWA200287_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -struct default_call_policies; - -namespace detail -{ - // tuple_extract::extract(t) returns the first - // element of a Tuple whose type E satisfies the given Predicate - // applied to add_reference. The Predicate must be an MPL - // metafunction class. - template - struct tuple_extract; - - // Implementation class for when the tuple's head type does not - // satisfy the Predicate - template - struct tuple_extract_impl - { - template - struct apply - { - typedef typename Tuple::head_type result_type; - - static typename Tuple::head_type extract(Tuple const& x) - { - return x.get_head(); - } - }; - }; - - // Implementation specialization for when the tuple's head type - // satisfies the predicate - template <> - struct tuple_extract_impl - { - template - struct apply - { - // recursive application of tuple_extract on the tail of the tuple - typedef tuple_extract next; - typedef typename next::result_type result_type; - - static result_type extract(Tuple const& x) - { - return next::extract(x.get_tail()); - } - }; - }; - - // A metafunction which selects a version of tuple_extract_impl to - // use for the implementation of tuple_extract - template - struct tuple_extract_base_select - { - typedef typename Tuple::head_type head_type; - typedef typename mpl::apply1::type>::type match_t; - BOOST_STATIC_CONSTANT(bool, match = match_t::value); - typedef typename tuple_extract_impl::template apply type; - }; - - template - struct tuple_extract - : tuple_extract_base_select< - Tuple - , typename mpl::lambda::type - >::type - { - }; - - - // - // Specialized extractors for the docstring, keywords, CallPolicies, - // and default implementation of virtual functions - // - - template - struct doc_extract - : tuple_extract< - Tuple - , mpl::not_< - mpl::or_< - is_reference_to_class - , is_reference_to_member_function_pointer - > - > - > - { - }; - - template - struct keyword_extract - : tuple_extract > - { - }; - - template - struct policy_extract - : tuple_extract< - Tuple - , mpl::and_< - mpl::not_ > - , is_reference_to_class - , mpl::not_ > - > - > - { - }; - - template - struct default_implementation_extract - : tuple_extract< - Tuple - , is_reference_to_member_function_pointer - > - { - }; - - // - // A helper class for decoding the optional arguments to def() - // invocations, which can be supplied in any order and are - // discriminated by their type properties. The template parameters - // are expected to be the types of the actual (optional) arguments - // passed to def(). - // - template - struct def_helper - { - // A tuple type which begins with references to the supplied - // arguments and ends with actual representatives of the default - // types. - typedef boost::tuples::tuple< - T1 const& - , T2 const& - , T3 const& - , T4 const& - , default_call_policies - , keywords<0> - , char const* - , void(not_specified::*)() // A function pointer type which is never an - // appropriate default implementation - > all_t; - - // Constructors; these initialize an member of the tuple type - // shown above. - def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {} - def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {} - def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {} - def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {} - - private: // types - typedef typename default_implementation_extract::result_type default_implementation_t; - - public: // Constants which can be used for static assertions. - - // Users must not supply a default implementation for non-class - // methods. - BOOST_STATIC_CONSTANT( - bool, has_default_implementation = ( - !is_same::value)); - - public: // Extractor functions which pull the appropriate value out - // of the tuple - char const* doc() const - { - return doc_extract::extract(m_all); - } - - typename keyword_extract::result_type keywords() const - { - return keyword_extract::extract(m_all); - } - - typename policy_extract::result_type policies() const - { - return policy_extract::extract(m_all); - } - - default_implementation_t default_implementation() const - { - return default_implementation_extract::extract(m_all); - } - - private: // data members - all_t m_all; - not_specified m_nil; // for filling in not_specified slots - }; -} - -}} // namespace boost::python::detail - -#endif // DEF_HELPER_DWA200287_HPP diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp deleted file mode 100644 index ac963cb6..00000000 --- a/include/boost/python/detail/defaults_def.hpp +++ /dev/null @@ -1,280 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 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. -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(BOOST_PP_IS_ITERATING) - -#ifndef DEFAULTS_DEF_JDG20020811_HPP -#define DEFAULTS_DEF_JDG20020811_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -namespace boost { namespace python { - -struct module; - -namespace objects -{ - struct class_base; -} - -namespace detail -{ - template struct member_function_cast; - - template - static void name_space_def( - NameSpaceT& name_space - , char const* name - , Func f - , keyword_range const& kw - , CallPolicies const& policies - , char const* doc - , objects::class_base* - ) - { - typedef typename NameSpaceT::wrapped_type wrapped_type; - - objects::add_to_namespace( - name_space, name, - detail::make_keyword_range_function( - // This bit of nastiness casts F to a member function of T if possible. - member_function_cast::stage1(f).stage2((wrapped_type*)0).stage3(f) - , policies, kw) - , doc); - } - - template - static void name_space_def( - object& name_space - , char const* name - , Func f - , keyword_range const& kw - , CallPolicies const& policies - , char const* doc - , ... - ) - { - scope within(name_space); - - detail::scope_setattr_doc( - name - , detail::make_keyword_range_function(f, policies, kw) - , doc); - } - - // For backward compatibility - template - static void name_space_def( - NameSpaceT& name_space - , char const* name - , Func f - , keyword_range const& kw // ignored - , CallPolicies const& policies - , char const* doc - , module* - ) - { - name_space.def(name, f, policies, doc); - } - - /////////////////////////////////////////////////////////////////////////////// - // - // This Boost PP code generates expansions for - // - // template - // inline void - // define_stub_function( - // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_) - // { - // name_space.def(name, &OverloadsT::func_N); - // } - // - // where N runs from 0 to BOOST_PYTHON_MAX_ARITY - // - // The set of overloaded functions (define_stub_function) expects: - // - // 1. char const* name: function name that will be visible to python - // 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) - // 3. NameSpaceT& name_space: a python::class_ or python::module instance - // 4. int_t: the Nth overloaded function (OverloadsT::func_N) - // (see defaults_gen.hpp) - // 5. char const* name: doc string - // - /////////////////////////////////////////////////////////////////////////////// - template - struct define_stub_function {}; - -#define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) - -#include BOOST_PP_ITERATE() - -/////////////////////////////////////////////////////////////////////////////// -// -// define_with_defaults_helper -// -// This helper template struct does the actual recursive definition. -// There's a generic version define_with_defaults_helper and a -// terminal case define_with_defaults_helper<0>. The struct and its -// specialization has a sole static member function def that expects: -// -// 1. char const* name: function name that will be visible to python -// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) -// 3. NameSpaceT& name_space: a python::class_ or python::module instance -// 4. char const* name: doc string -// -// The def static member function calls a corresponding -// define_stub_function. The general case recursively calls -// define_with_defaults_helper::def until it reaches the -// terminal case case define_with_defaults_helper<0>. -// -/////////////////////////////////////////////////////////////////////////////// - template - struct define_with_defaults_helper { - - template - static void - def( - char const* name, - StubsT stubs, - keyword_range kw, - CallPolicies const& policies, - NameSpaceT& name_space, - char const* doc) - { - // define the NTH stub function of stubs - define_stub_function::define(name, stubs, kw, policies, name_space, doc); - - if (kw.second > kw.first) - --kw.second; - - // call the next define_with_defaults_helper - define_with_defaults_helper::def(name, stubs, kw, policies, name_space, doc); - } - }; - -/////////////////////////////////////// - template <> - struct define_with_defaults_helper<0> { - - template - static void - def( - char const* name, - StubsT stubs, - keyword_range const& kw, - CallPolicies const& policies, - NameSpaceT& name_space, - char const* doc) - { - // define the Oth stub function of stubs - define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc); - // return - } - }; - -/////////////////////////////////////////////////////////////////////////////// -// -// define_with_defaults -// -// 1. char const* name: function name that will be visible to python -// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) -// 3. CallPolicies& policies: Call policies -// 4. NameSpaceT& name_space: a python::class_ or python::module instance -// 5. SigT sig: Function signature typelist (see defaults_gen.hpp) -// 6. char const* name: doc string -// -// This is the main entry point. This function recursively defines all -// stub functions of StubT (see defaults_gen.hpp) in NameSpaceT name_space which -// can be either a python::class_ or a python::module. The sig argument -// is a typelist that specifies the return type, the class (for member -// functions, and the arguments. Here are some SigT examples: -// -// int foo(int) mpl::list -// void bar(int, int) mpl::list -// void C::foo(int) mpl::list -// -/////////////////////////////////////////////////////////////////////////////// - template - inline void - define_with_defaults( - char const* name, - OverloadsT const& overloads, - NameSpaceT& name_space, - SigT const& sig) - { - typedef typename mpl::front::type return_type; - typedef typename OverloadsT::void_return_type void_return_type; - typedef typename OverloadsT::non_void_return_type non_void_return_type; - - typedef typename mpl::if_c< - boost::is_same::value - , void_return_type - , non_void_return_type - >::type stubs_type; - - BOOST_STATIC_ASSERT( - (stubs_type::max_args) <= mpl::size::value); - - typedef typename stubs_type::template gen gen_type; - define_with_defaults_helper::def( - name - , gen_type() - , overloads.keywords() - , overloads.call_policies() - , name_space - , overloads.doc_string()); - } - -} // namespace detail - -}} // namespace boost::python - -/////////////////////////////////////////////////////////////////////////////// -#endif // DEFAULTS_DEF_JDG20020811_HPP - -#else // defined(BOOST_PP_IS_ITERATING) -// PP vertical iteration code - - -template <> -struct define_stub_function { - template - static void define( - char const* name - , StubsT const& - , keyword_range const& kw - , CallPolicies const& policies - , NameSpaceT& name_space - , char const* doc) - { - detail::name_space_def( - name_space - , name - , &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()) - , kw - , policies - , doc - , &name_space); - } -}; - -#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp deleted file mode 100644 index f1a367a4..00000000 --- a/include/boost/python/detail/defaults_gen.hpp +++ /dev/null @@ -1,388 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 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 DEFAULTS_GEN_JDG20020807_HPP -#define DEFAULTS_GEN_JDG20020807_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace detail -{ - // overloads_base is used as a base class for all function - // stubs. This class holds the doc_string of the stubs. - struct overloads_base - { - overloads_base(char const* doc_) - : m_doc(doc_) {} - - overloads_base(char const* doc_, detail::keyword_range const& kw) - : m_doc(doc_), m_keywords(kw) {} - - char const* doc_string() const - { - return m_doc; - } - - detail::keyword_range const& keywords() const - { - return m_keywords; - } - - private: - char const* m_doc; - detail::keyword_range m_keywords; - }; - - // overloads_proxy is generated by the overloads_common operator[] (see - // below). This class holds a user defined call policies of the stubs. - template - struct overloads_proxy - : public overloads_base - { - typedef typename OverloadsT::non_void_return_type non_void_return_type; - typedef typename OverloadsT::void_return_type void_return_type; - - overloads_proxy( - CallPoliciesT const& policies_ - , char const* doc - , keyword_range const& kw - ) - : overloads_base(doc, kw) - , policies(policies_) - {} - - CallPoliciesT - call_policies() const - { - return policies; - } - - CallPoliciesT policies; - }; - - // overloads_common is our default function stubs base class. This - // class returns the default_call_policies in its call_policies() - // member function. It can generate a overloads_proxy however through - // its operator[] - template - struct overloads_common - : public overloads_base - { - overloads_common(char const* doc) - : overloads_base(doc) {} - - overloads_common(char const* doc, keyword_range const& kw) - : overloads_base(doc, kw) {} - - default_call_policies - call_policies() const - { - return default_call_policies(); - } - - template - overloads_proxy - operator[](CallPoliciesT const& policies) const - { - return overloads_proxy( - policies, this->doc_string(), this->keywords()); - } - }; - -}}} // namespace boost::python::detail - - -#define BOOST_PYTHON_TYPEDEF_GEN(z, index, data) \ - typedef typename ::boost::mpl::next::type \ - BOOST_PP_CAT(iter, BOOST_PP_INC(index)); \ - typedef typename ::boost::mpl::apply0::type \ - BOOST_PP_CAT(T, index); - -#define BOOST_PYTHON_FUNC_WRAPPER_GEN(z, index, data) \ - static RT BOOST_PP_CAT(func_, \ - BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \ - BOOST_PP_ENUM_BINARY_PARAMS_Z( \ - 1, index, T, arg)) \ - { \ - BOOST_PP_TUPLE_ELEM(3, 2, data) \ - BOOST_PP_TUPLE_ELEM(3, 0, data)( \ - BOOST_PP_ENUM_PARAMS( \ - index, \ - arg)); \ - } - -#define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ - struct fstubs_name \ - { \ - BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \ - BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \ - \ - template \ - struct gen \ - { \ - typedef typename ::boost::mpl::begin::type rt_iter; \ - typedef typename ::boost::mpl::apply0::type RT; \ - typedef typename ::boost::mpl::next::type iter0; \ - \ - BOOST_PP_REPEAT_2ND( \ - n_args, \ - BOOST_PYTHON_TYPEDEF_GEN, \ - 0) \ - \ - BOOST_PP_REPEAT_FROM_TO_2( \ - BOOST_PP_SUB_D(1, n_args, n_dflts), \ - BOOST_PP_INC(n_args), \ - BOOST_PYTHON_FUNC_WRAPPER_GEN, \ - (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \ - }; \ - }; \ - -/////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN(z, index, data) \ - static RT BOOST_PP_CAT(func_, \ - BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \ - ClassT obj BOOST_PP_COMMA_IF(index) \ - BOOST_PP_ENUM_BINARY_PARAMS_Z(1, index, T, arg) \ - ) \ - { \ - BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)( \ - BOOST_PP_ENUM_PARAMS(index, arg) \ - ); \ - } - -#define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ - struct fstubs_name \ - { \ - BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \ - BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \ - \ - template \ - struct gen \ - { \ - typedef typename ::boost::mpl::begin::type rt_iter; \ - typedef typename ::boost::mpl::apply0::type RT; \ - \ - typedef typename ::boost::mpl::next::type class_iter; \ - typedef typename ::boost::mpl::apply0::type ClassT; \ - typedef typename ::boost::mpl::next::type iter0; \ - \ - BOOST_PP_REPEAT_2ND( \ - n_args, \ - BOOST_PYTHON_TYPEDEF_GEN, \ - 0) \ - \ - BOOST_PP_REPEAT_FROM_TO_2( \ - BOOST_PP_SUB_D(1, n_args, n_dflts), \ - BOOST_PP_INC(n_args), \ - BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN, \ - (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \ - }; \ - }; - -#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - fstubs_name(char const* doc = 0) \ - : ::boost::python::detail::overloads_common(doc) {} \ - template \ - fstubs_name(char const* doc, Keywords const& keywords) \ - : ::boost::python::detail::overloads_common( \ - doc, keywords.range()) \ - { \ - typedef typename ::boost::python::detail:: \ - error::more_keywords_than_function_arguments< \ - Keywords::size,n_args>::too_many_keywords assertion; \ - } \ - template \ - fstubs_name(Keywords const& keywords, char const* doc = 0) \ - : ::boost::python::detail::overloads_common( \ - doc, keywords.range()) \ - { \ - typedef typename ::boost::python::detail:: \ - error::more_keywords_than_function_arguments< \ - Keywords::size,n_args>::too_many_keywords assertion; \ - } - -# if defined(BOOST_NO_VOID_RETURNS) - -# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - BOOST_PYTHON_GEN_FUNCTION( \ - fname, void_return_type, n_args, n_dflts, ;) \ - \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - -# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_MEM_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - BOOST_PYTHON_GEN_MEM_FUNCTION( \ - fname, void_return_type, n_args, n_dflts, ;) \ - \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - -# else // !defined(BOOST_NO_VOID_RETURNS) - -# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - \ - typedef non_void_return_type void_return_type; \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - - -# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_MEM_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - \ - typedef non_void_return_type void_return_type; \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - -# endif // !defined(BOOST_NO_VOID_RETURNS) - -/////////////////////////////////////////////////////////////////////////////// -// -// MAIN MACROS -// -// Given generator_name, fname, min_args and max_args, These macros -// generate function stubs that forward to a function or member function -// named fname. max_args is the arity of the function or member function -// fname. fname can have default arguments. min_args is the minimum -// arity that fname can accept. -// -// There are two versions: -// -// 1. BOOST_PYTHON_FUNCTION_OVERLOADS for free functions -// 2. BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for member functions. -// -// For instance, given a function: -// -// int -// foo(int a, char b = 1, unsigned c = 2, double d = 3) -// { -// return a + b + c + int(d); -// } -// -// The macro invocation: -// -// BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) -// -// Generates this code: -// -// struct foo_stubsNonVoid -// { -// static const int n_funcs = 4; -// static const int max_args = n_funcs; -// -// template -// struct gen -// { -// typedef typename ::boost::mpl::begin::type rt_iter; -// typedef typename rt_iter::type RT; -// typedef typename rt_iter::next iter0; -// typedef typename iter0::type T0; -// typedef typename iter0::next iter1; -// typedef typename iter1::type T1; -// typedef typename iter1::next iter2; -// typedef typename iter2::type T2; -// typedef typename iter2::next iter3; -// typedef typename iter3::type T3; -// typedef typename iter3::next iter4; -// -// static RT func_0(T0 arg0) -// { return foo(arg0); } -// -// static RT func_1(T0 arg0, T1 arg1) -// { return foo(arg0, arg1); } -// -// static RT func_2(T0 arg0, T1 arg1, T2 arg2) -// { return foo(arg0, arg1, arg2); } -// -// static RT func_3(T0 arg0, T1 arg1, T2 arg2, T3 arg3) -// { return foo(arg0, arg1, arg2, arg3); } -// }; -// }; -// -// struct foo_overloads -// : public boost::python::detail::overloads_common -// { -// typedef foo_overloadsNonVoid non_void_return_type; -// typedef foo_overloadsNonVoid void_return_type; -// -// foo_overloads(char const* doc = 0) -// : boost::python::detail::overloads_common(doc) {} -// }; -// -// The typedefs non_void_return_type and void_return_type are -// used to handle compilers that do not support void returns. The -// example above typedefs non_void_return_type and -// void_return_type to foo_overloadsNonVoid. On compilers that do -// not support void returns, there are two versions: -// foo_overloadsNonVoid and foo_overloadsVoid. The "Void" -// version is almost identical to the "NonVoid" version except -// for the return type (void) and the lack of the return keyword. -// -// See the overloads_common above for a description of the -// foo_overloads' base class. -// -/////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \ - BOOST_PYTHON_GEN_FUNCTION_STUB( \ - fname, \ - generator_name, \ - max_args, \ - BOOST_PP_SUB_D(1, max_args, min_args)) - -#define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \ - BOOST_PYTHON_GEN_MEM_FUNCTION_STUB( \ - fname, \ - generator_name, \ - max_args, \ - BOOST_PP_SUB_D(1, max_args, min_args)) - -// deprecated macro names (to be removed) -#define BOOST_PYTHON_FUNCTION_GENERATOR BOOST_PYTHON_FUNCTION_OVERLOADS -#define BOOST_PYTHON_MEM_FUN_GENERATOR BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - -/////////////////////////////////////////////////////////////////////////////// -#endif // DEFAULTS_GEN_JDG20020807_HPP - - diff --git a/include/boost/python/detail/dependent.hpp b/include/boost/python/detail/dependent.hpp deleted file mode 100644 index 4fc48766..00000000 --- a/include/boost/python/detail/dependent.hpp +++ /dev/null @@ -1,28 +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 DEPENDENT_DWA200286_HPP -# define DEPENDENT_DWA200286_HPP - -namespace boost { namespace python { namespace detail { - -// A way to turn a concrete type T into a type dependent on U. This -// keeps conforming compilers (those implementing proper 2-phase -// name lookup for templates) from complaining about incomplete -// types in situations where it would otherwise be inconvenient or -// impossible to re-order code so that all types are defined in time. - -// One such use is when we must return an incomplete T from a member -// function template (which must be defined in the class body to -// keep MSVC happy). -template -struct dependent -{ - typedef T type; -}; - -}}} // namespace boost::python::detail - -#endif // DEPENDENT_DWA200286_HPP diff --git a/include/boost/python/detail/destroy.hpp b/include/boost/python/detail/destroy.hpp deleted file mode 100644 index 7b107550..00000000 --- a/include/boost/python/detail/destroy.hpp +++ /dev/null @@ -1,83 +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 DESTROY_DWA2002221_HPP -# define DESTROY_DWA2002221_HPP - -# include -# include - -namespace boost { namespace python { namespace detail { - -template struct value_destroyer; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile* p) - { - p->T::~T(); - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(A*, T const volatile* const first) - { - for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p) - value_destroyer< - boost::is_array::value - ,boost::has_trivial_destructor::value - >::execute(p); - } - - template - static void execute(T const volatile* p) - { - execute(p, *p); - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile* p) - { - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile* p) - { - } -}; - -template -inline void destroy_referent_impl(void* p, T& (*)()) -{ - // note: cv-qualification needed for MSVC6 - // must come *before* T for metrowerks - value_destroyer< - (boost::is_array::value) - ,(boost::has_trivial_destructor::value) - >::execute((const volatile T*)p); -} - -template -inline void destroy_referent(void* p, T(*)() = 0) -{ - destroy_referent_impl(p, (T(*)())0); -} - -}}} // namespace boost::python::detail - -#endif // DESTROY_DWA2002221_HPP diff --git a/include/boost/python/detail/exception_handler.hpp b/include/boost/python/detail/exception_handler.hpp deleted file mode 100644 index 3e36a7a5..00000000 --- a/include/boost/python/detail/exception_handler.hpp +++ /dev/null @@ -1,49 +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 EXCEPTION_HANDLER_DWA2002810_HPP -# define EXCEPTION_HANDLER_DWA2002810_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -struct BOOST_PYTHON_DECL exception_handler; - -typedef function2 const&> handler_function; - -struct BOOST_PYTHON_DECL exception_handler -{ - private: // types - - public: - explicit exception_handler(handler_function const& impl); - - inline bool handle(function0 const& f) const; - - bool operator()(function0 const& f) const; - - static exception_handler* chain; - - private: - static exception_handler* tail; - - handler_function m_impl; - exception_handler* m_next; -}; - - -inline bool exception_handler::handle(function0 const& f) const -{ - return this->m_impl(*this, f); -} - -BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f); - -}}} // namespace boost::python::detail - -#endif // EXCEPTION_HANDLER_DWA2002810_HPP diff --git a/include/boost/python/detail/force_instantiate.hpp b/include/boost/python/detail/force_instantiate.hpp deleted file mode 100755 index 62446c32..00000000 --- a/include/boost/python/detail/force_instantiate.hpp +++ /dev/null @@ -1,33 +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 FORCE_INSTANTIATE_DWA200265_HPP -# define FORCE_INSTANTIATE_DWA200265_HPP - -namespace boost { namespace python { namespace detail { - -// Allows us to force the argument to be instantiated without -// incurring unused variable warnings - -# if !defined(BOOST_MSVC) || BOOST_MSVC == 1200 || _MSC_FULL_VER > 13102196 - -template -inline void force_instantiate(T const&) {} - -# else - -# pragma optimize("g", off) -inline void force_instantiate_impl(...) {} -# pragma optimize("", on) -template -inline void force_instantiate(T const& x) -{ - detail::force_instantiate_impl(&x); -} -# endif - -}}} // namespace boost::python::detail - -#endif // FORCE_INSTANTIATE_DWA200265_HPP diff --git a/include/boost/python/detail/if_else.hpp b/include/boost/python/detail/if_else.hpp deleted file mode 100644 index 6668617c..00000000 --- a/include/boost/python/detail/if_else.hpp +++ /dev/null @@ -1,117 +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 IF_ELSE_DWA2002322_HPP -# define IF_ELSE_DWA2002322_HPP -# include - -namespace boost { namespace python { namespace detail { - -template struct elif_selected; - -template -struct if_selected -{ - template - struct elif : elif_selected - { - }; - - template - struct else_ - { - typedef T type; - }; -}; - -# if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) -namespace msvc70_aux { - -template< bool > struct inherit_from -{ - template< typename T > struct result - { - typedef T type; - }; -}; - -template<> struct inherit_from -{ - template< typename T > struct result - { - struct type {}; - }; -}; - -template< typename T > -struct never_true -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -} // namespace msvc70_aux - -#endif // # if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) - -template -struct elif_selected -{ -# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) - template class then; -# elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300) - template - struct then : msvc70_aux::inherit_from< msvc70_aux::never_true::value > - ::template result< if_selected >::type - { - }; -# else - template - struct then : if_selected - { - }; -# endif -}; - -# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) -template -template -class elif_selected::then : public if_selected -{ -}; -# endif - -template struct if_ -{ - template - struct then : if_selected - { - }; -}; - -struct if_unselected -{ - template struct elif : if_ - { - }; - - template - struct else_ - { - typedef U type; - }; -}; - -template <> -struct if_ -{ - template - struct then : if_unselected - { - }; -}; - -}}} // namespace boost::python::detail - -#endif // IF_ELSE_DWA2002322_HPP diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp deleted file mode 100644 index 170f3662..00000000 --- a/include/boost/python/detail/indirect_traits.hpp +++ /dev/null @@ -1,483 +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 -# include -# include -# include -# include -# include -# include -# include - -# include - -# include -# if 0 && BOOST_WORKAROUND(__MWERKS__, <= 0x2407) -# include -# endif - -# include -# include -# include -# include -# include - -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# include -# endif - -namespace boost { namespace python { namespace detail { - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_reference_to_const : mpl::false_ -{ -}; - -template -struct is_reference_to_const : mpl::true_ -{ -}; - -# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround -template -struct is_reference_to_const : mpl::true_ -{ -}; -# endif - -template -struct is_reference_to_function : mpl::false_ -{ -}; - -template -struct is_reference_to_function : is_function -{ -}; - -template -struct is_pointer_to_function : mpl::false_ -{ -}; - -// There's no such thing as a pointer-to-cv-function, so we don't need -// specializations for those -template -struct is_pointer_to_function : is_function -{ -}; - -template -struct is_reference_to_member_function_pointer_impl : mpl::false_ -{ -}; - -template -struct is_reference_to_member_function_pointer_impl - : is_member_function_pointer::type> -{ -}; - - -template -struct is_reference_to_member_function_pointer - : is_reference_to_member_function_pointer_impl -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) -}; - -template -struct is_reference_to_function_pointer_aux - : mpl::and_< - is_reference - , is_pointer_to_function< - typename remove_cv< - typename remove_reference::type - >::type - > - > -{ - // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those -}; - -template -struct is_reference_to_function_pointer - : mpl::if_< - is_reference_to_function - , mpl::false_ - , is_reference_to_function_pointer_aux - >::type -{ -}; - -template -struct is_reference_to_non_const - : mpl::and_< - is_reference - , mpl::not_< - is_reference_to_const - > - > -{ -}; - -template -struct is_reference_to_volatile : mpl::false_ -{ -}; - -template -struct is_reference_to_volatile : mpl::true_ -{ -}; - -# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround -template -struct is_reference_to_volatile : mpl::true_ -{ -}; -# endif - - -template -struct is_reference_to_pointer : mpl::false_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_class - : mpl::and_< - is_reference - , is_class< - typename remove_cv< - typename remove_reference::type - >::type - > - > -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) -}; - -template -struct is_pointer_to_class - : mpl::and_< - is_pointer - , is_class< - typename remove_cv< - typename remove_pointer::type - >::type - > - > -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T)) -}; - -# 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::if_< - is_const - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_volatile_help -{ - typedef typename mpl::if_< - is_volatile - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_pointer_help -{ - typedef typename mpl::if_< - is_pointer - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_class_help -{ - typedef typename mpl::if_< - is_class - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_reference_to_function_aux -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); - }; - -template -struct is_reference_to_function - : mpl::if_, is_reference_to_function_aux, mpl::bool_ >::type -{ -}; - -template -struct is_pointer_to_function_aux -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); - typedef mpl::bool_ type; -}; - -template -struct is_pointer_to_function - : mpl::if_, is_pointer_to_function_aux, mpl::bool_ >::type -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) -}; - -struct false_helper1 -{ - template - struct apply - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; -}; - -template -typename is_const_help::type reference_to_const_helper(V&); -outer_no_type -reference_to_const_helper(...); - -struct true_helper1 -{ - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); - }; -}; - -template -struct is_reference_to_const_helper1 : true_helper1 -{ -# if 0 - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); - }; -# endif -}; - -template <> -struct is_reference_to_const_helper1 : false_helper1 -{ -}; - - -template -struct is_reference_to_const - : is_reference_to_const_helper1::value>::template apply -{ -}; - - - -template -struct is_reference_to_non_const_helper1 -{ - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); - }; -}; - -template <> -struct is_reference_to_non_const_helper1 : false_helper1 -{ -}; - - -template -struct is_reference_to_non_const - : is_reference_to_non_const_helper1::value>::template apply -{ -}; - - -template -typename is_volatile_help::type reference_to_volatile_helper(V&); -outer_no_type -reference_to_volatile_helper(...); - -template -struct is_reference_to_volatile_helper1 -{ - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); - }; -}; - -template <> -struct is_reference_to_volatile_helper1 : false_helper1 -{ -}; - - -template -struct is_reference_to_volatile - : is_reference_to_volatile_helper1::value>::template apply -{ -}; - -template -typename is_pointer_help::type reference_to_pointer_helper(V&); -outer_no_type reference_to_pointer_helper(...); - -template -struct is_reference_to_pointer -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_reference::value - && sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type)) - ); -}; - -template -struct is_reference_to_function_pointer - : mpl::if_< - is_reference - , is_pointer_to_function_aux - , mpl::bool_ - >::type -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) -}; - - -template -struct is_member_function_pointer_help - : mpl::if_, inner_yes_type, inner_no_type> -{}; - -template -typename is_member_function_pointer_help::type member_function_pointer_helper(V&); -outer_no_type member_function_pointer_helper(...); - -template -struct is_pointer_to_member_function_aux -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type)); - typedef mpl::bool_ type; -}; - -template -struct is_reference_to_member_function_pointer - : mpl::if_< - is_reference - , is_pointer_to_member_function_aux - , mpl::bool_ - >::type -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) -}; - -template -typename is_class_help::type reference_to_class_helper(V const volatile&); -outer_no_type reference_to_class_helper(...); - -template -struct is_reference_to_class -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_reference::value - & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) - ); - typedef mpl::bool_ type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) -}; - -template -typename is_class_help::type pointer_to_class_helper(V const volatile*); -outer_no_type pointer_to_class_helper(...); - -template -struct is_pointer_to_class -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_pointer::value - && sizeof(pointer_to_class_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/invoke.hpp b/include/boost/python/detail/invoke.hpp deleted file mode 100644 index b83c6e34..00000000 --- a/include/boost/python/detail/invoke.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// 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 INVOKE_DWA20021122_HPP -# define INVOKE_DWA20021122_HPP - -# include -# include -# include - -# include - -# include -# include -# include -# include -# include -# include - -// This file declares a series of overloaded invoke(...) functions, -// used to invoke wrapped C++ function (object)s from Python. Each one -// accepts: -// -// - a tag which identifies the invocation syntax (e.g. member -// functions must be invoked with a different syntax from regular -// functions) -// -// - a pointer to a result converter type, used solely as a way of -// transmitting the type of the result converter to the function (or -// an int, if the return type is void). -// -// - the "function", which may be a function object, a function or -// member function pointer, or a defaulted_virtual_fn. -// -// - The arg_from_python converters for each of the arguments to be -// passed to the function being invoked. - -namespace boost { namespace python { namespace detail { - -// This "result converter" is really just used as a dispatch tag to -// invoke(...), selecting the appropriate implementation -typedef int void_result_to_python; - -// Trait forward declaration. -template struct is_defaulted_virtual_fn; - -// Tag types describing invocation methods -struct fn_tag {}; -struct mem_fn_tag {}; - -// A metafunction returning the appropriate tag type for invoking an -// object of type T. -template -struct invoke_tag - : mpl::if_< - is_member_function_pointer - , mem_fn_tag - , fn_tag - > -{}; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}}} // namespace boost::python::detail - -# endif // INVOKE_DWA20021122_HPP -#else - -# define N BOOST_PP_ITERATION() - -template -inline PyObject* invoke(fn_tag, RC*, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - return RC()(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) )); -} - -template -inline PyObject* invoke(fn_tag, void_result_to_python, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ); - return none(); -} - -template -inline PyObject* invoke(mem_fn_tag, RC*, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - return RC()( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) ); -} - -template -inline PyObject* invoke(mem_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)); - return none(); -} - -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/is_auto_ptr.hpp b/include/boost/python/detail/is_auto_ptr.hpp deleted file mode 100644 index 986a6309..00000000 --- a/include/boost/python/detail/is_auto_ptr.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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 IS_AUTO_PTR_DWA2003224_HPP -# define IS_AUTO_PTR_DWA2003224_HPP - -# ifndef BOOST_NO_AUTO_PTR -# include -# include -# endif - -namespace boost { namespace python { namespace detail { - -# if !defined(BOOST_NO_AUTO_PTR) - -BOOST_PYTHON_IS_XXX_DEF(auto_ptr, std::auto_ptr, 1) - -# else - -template -struct is_auto_ptr : mpl::false_ -{ -}; - -# endif - -}}} // namespace boost::python::detail - -#endif // IS_AUTO_PTR_DWA2003224_HPP diff --git a/include/boost/python/detail/is_function_ref_tester.hpp b/include/boost/python/detail/is_function_ref_tester.hpp deleted file mode 100644 index c9ab4818..00000000 --- a/include/boost/python/detail/is_function_ref_tester.hpp +++ /dev/null @@ -1,136 +0,0 @@ - -// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, -// Aleksey Gurtovoy, Howard Hinnant & John Maddock 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. - -#if !defined(BOOST_PP_IS_ITERATING) - -///// header body - -#ifndef BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED -#define BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED - -#include "boost/type_traits/detail/yes_no_type.hpp" -#include "boost/type_traits/config.hpp" - -#if defined(BOOST_TT_PREPROCESSING_MODE) -# include "boost/preprocessor/iterate.hpp" -# include "boost/preprocessor/enum_params.hpp" -# include "boost/preprocessor/comma_if.hpp" -#endif - -namespace boost { -namespace python { -namespace detail { - -template -boost::type_traits::no_type BOOST_TT_DECL is_function_ref_tester(T& ...); - -#if !defined(BOOST_TT_PREPROCESSING_MODE) -// preprocessor-generated part, don't edit by hand! - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24), int); - -#else - -#define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, 25, "boost/type_traits/detail/is_function_ref_tester.hpp")) -#include BOOST_PP_ITERATE() - -#endif // BOOST_TT_PREPROCESSING_MODE - -} // namespace detail -} // namespace python -} // namespace boost - -#endif // BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED - -///// iteration - -#else -#define i BOOST_PP_FRAME_ITERATION(1) - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(BOOST_PP_ENUM_PARAMS(i,T)), int); - -#undef i -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/is_shared_ptr.hpp b/include/boost/python/detail/is_shared_ptr.hpp deleted file mode 100755 index d3579a6a..00000000 --- a/include/boost/python/detail/is_shared_ptr.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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 IS_SHARED_PTR_DWA2003224_HPP -# define IS_SHARED_PTR_DWA2003224_HPP - -# include -# include - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_IS_XXX_DEF(shared_ptr, shared_ptr, 1) - -}}} // namespace boost::python::detail - -#endif // IS_SHARED_PTR_DWA2003224_HPP diff --git a/include/boost/python/detail/is_xxx.hpp b/include/boost/python/detail/is_xxx.hpp deleted file mode 100644 index 0faea999..00000000 --- a/include/boost/python/detail/is_xxx.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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 IS_XXX_DWA2003224_HPP -# define IS_XXX_DWA2003224_HPP - -# include -# include -# include - -# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -# include -# include - -# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct is_##name \ -{ \ - typedef char yes; \ - typedef char (&no)[2]; \ - \ - static typename add_reference::type dummy; \ - \ - template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ - static yes test( \ - qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) >&, int \ - ); \ - \ - template \ - static no test(U&, ...); \ - \ - BOOST_STATIC_CONSTANT( \ - bool, value \ - = !is_reference::value \ - & (sizeof(test(dummy, 0)) == sizeof(yes))); \ - \ - typedef mpl::bool_ type; \ -}; - -# else - -# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct is_##name : mpl::false_ \ -{ \ -}; \ - \ -template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) > \ -struct is_##name< \ - qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) > \ -> \ - : mpl::true_ \ -{ \ -}; - -# endif - -#endif // IS_XXX_DWA2003224_HPP diff --git a/include/boost/python/detail/make_keyword_range_fn.hpp b/include/boost/python/detail/make_keyword_range_fn.hpp deleted file mode 100644 index 9c749292..00000000 --- a/include/boost/python/detail/make_keyword_range_fn.hpp +++ /dev/null @@ -1,55 +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 MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP -# define MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP - -# include -# include - -# include - -# include - - -namespace boost { namespace python { namespace detail { - -// Think of this as a version of make_function without a compile-time -// check that the size of kw is no greater than the expected arity of -// F. This version is needed when defining functions with default -// arguments, because compile-time information about the number of -// keywords is missing for all but the initial function definition. -template -object make_keyword_range_function(F f, Policies const& policies, keyword_range const& kw) -{ - return detail::make_function_aux( - f, policies, args_from_python(), detail::get_signature(f), kw, mpl::int_<0>()); -} - -// Builds an '__init__' function which inserts the given Holder type -// in a wrapped C++ class instance. ArgList is an MPL type sequence -// describing the C++ argument types to be passed to Holder's -// constructor. -// -// Holder and ArgList are intended to be explicitly specified. -template -object make_keyword_range_constructor( - CallPolicies const& policies // The CallPolicies with which to invoke the Holder's constructor - , detail::keyword_range const& kw // The (possibly empty) set of associated argument keywords - , Holder* = 0 - , ArgList* = 0) -{ - BOOST_STATIC_CONSTANT(unsigned, arity = mpl::size::value); - - return detail::make_keyword_range_function( - objects::make_holder - ::template apply::execute - , policies - , kw); -} - -}}} // namespace boost::python::detail - -#endif // MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP diff --git a/include/boost/python/detail/make_tuple.hpp b/include/boost/python/detail/make_tuple.hpp deleted file mode 100644 index 399498bc..00000000 --- a/include/boost/python/detail/make_tuple.hpp +++ /dev/null @@ -1,33 +0,0 @@ -# ifndef BOOST_PYTHON_SYNOPSIS -# // 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. - -# if !defined(BOOST_PP_IS_ITERATING) -# error Boost.Python - do not include this file! -# endif - -# define N BOOST_PP_ITERATION() - -# define BOOST_PYTHON_MAKE_TUPLE_ARG(z, N, ignored) \ - PyTuple_SET_ITEM( \ - result.ptr() \ - , N \ - , python::incref(python::object(a##N).ptr()) \ - ); - - template - tuple - make_tuple(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)) - { - tuple result((detail::new_reference)::PyTuple_New(N)); - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_MAKE_TUPLE_ARG, _) - return result; - } - -# undef BOOST_PYTHON_MAKE_TUPLE_ARG - -# undef N -# endif // BOOST_PYTHON_SYNOPSIS 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/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp deleted file mode 100644 index 568c13cc..00000000 --- a/include/boost/python/detail/member_function_cast.hpp +++ /dev/null @@ -1,118 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef MEMBER_FUNCTION_CAST_DWA2002311_HPP -# define MEMBER_FUNCTION_CAST_DWA2002311_HPP - -# include - -# include -# include - -# include -# include -# include - -# include -# include - -namespace boost { namespace python { namespace detail { - -template -struct cast_helper -{ - struct yes_helper - { - static FT stage3(FT x) { return x; } - }; - - struct no_helper - { - template - static T stage3(T x) { return x; } - }; - - static yes_helper stage2(S*) { return yes_helper(); } - static no_helper stage2(void*) { return no_helper(); } -}; - -struct non_member_function_cast_impl -{ - template - static non_member_function_cast_impl stage1(T) { return non_member_function_cast_impl(); } - - template - static non_member_function_cast_impl stage2(T) { return non_member_function_cast_impl(); } - - template - T stage3(T x) { return x; } -}; - -template -struct member_function_cast_impl -{ -# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - template - static non_member_function_cast_impl stage1(U) - { - return non_member_function_cast_impl(); - } -# endif - -// Member functions -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, )) -# include BOOST_PP_ITERATE() -}; - -template -struct member_function_cast -# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - : member_function_cast_impl -# else - : mpl::if_c< - is_member_function_pointer::value - , member_function_cast_impl - , non_member_function_cast_impl - >::type -# endif -{ -}; - -}}} // namespace boost::python::detail - -# endif // MEMBER_FUNCTION_CAST_DWA2002311_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -// outer over cv-qualifiers - -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 -# line BOOST_PP_LINE(__LINE__, member_function_cast.hpp) -// inner over arities - -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) -# define P BOOST_PP_ENUM_PARAMS_Z(1, N, A) - - template < - class S, class R - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > - static cast_helper - stage1(R (S::*)( P ) Q) - { - return cast_helper(); - } - -# undef P -# undef N -# undef Q - -#endif diff --git a/include/boost/python/detail/mpl_lambda.hpp b/include/boost/python/detail/mpl_lambda.hpp deleted file mode 100644 index 953bca63..00000000 --- a/include/boost/python/detail/mpl_lambda.hpp +++ /dev/null @@ -1,13 +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 MPL_LAMBDA_DWA2002122_HPP -# define MPL_LAMBDA_DWA2002122_HPP - -// this header should go away soon -# include -# define BOOST_PYTHON_MPL_LAMBDA_SUPPORT BOOST_MPL_AUX_LAMBDA_SUPPORT - -#endif // MPL_LAMBDA_DWA2002122_HPP diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp deleted file mode 100644 index 0139984b..00000000 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MSVC_TYPEINFO_DWA200222_HPP -# define MSVC_TYPEINFO_DWA200222_HPP - -#include -#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 <= 700 - -namespace boost { namespace python { namespace detail { - -typedef std::type_info const& typeinfo; - -template -static typeinfo typeid_nonref(T const volatile*) { return typeid(T); } - -template -inline typeinfo typeid_ref_1(T&(*)()) -{ - return detail::typeid_nonref((T*)0); -} - -// A non-reference -template -inline typeinfo typeid_ref(type*, T&(*)(type)) -{ - return detail::typeid_nonref((T*)0); -} - -// A reference -template -inline typeinfo typeid_ref(type*, ...) -{ - return detail::typeid_ref_1((T(*)())0); -} - -template< typename T > T&(* is_ref_tester1(type) )(type) { return 0; } -inline char BOOST_TT_DECL is_ref_tester1(...) { return 0; } - -template -inline typeinfo msvc_typeid(boost::type* = 0) -{ - return detail::typeid_ref( - (boost::type*)0, detail::is_ref_tester1(type()) - ); -} - -# ifndef NDEBUG -inline typeinfo assert_array_typeid_compiles() -{ - return msvc_typeid(), msvc_typeid(); -} -# endif - -}}} // 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/not_specified.hpp b/include/boost/python/detail/not_specified.hpp deleted file mode 100644 index ce1b280d..00000000 --- a/include/boost/python/detail/not_specified.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 NOT_SPECIFIED_DWA2002321_HPP -# define NOT_SPECIFIED_DWA2002321_HPP - -namespace boost { namespace python { namespace detail { - - struct not_specified {}; - -}}} // namespace boost::python::detail - -#endif // NOT_SPECIFIED_DWA2002321_HPP diff --git a/include/boost/python/detail/operator_id.hpp b/include/boost/python/detail/operator_id.hpp deleted file mode 100755 index 8edb310b..00000000 --- a/include/boost/python/detail/operator_id.hpp +++ /dev/null @@ -1,55 +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 OPERATOR_ID_DWA2002531_HPP -# define OPERATOR_ID_DWA2002531_HPP - -namespace boost { namespace python { namespace detail { - -enum operator_id -{ - op_add, - op_sub, - op_mul, - op_div, - op_mod, - op_divmod, - op_pow, - op_lshift, - op_rshift, - op_and, - op_xor, - op_or, - op_neg, - op_pos, - op_abs, - op_invert, - op_int, - op_long, - op_float, - op_str, - op_cmp, - op_gt, - op_ge, - op_lt, - op_le, - op_eq, - op_ne, - op_iadd, - op_isub, - op_imul, - op_idiv, - op_imod, - op_ilshift, - op_irshift, - op_iand, - op_ixor, - op_ior, - op_complex -}; - -}}} // namespace boost::python::detail - -#endif // OPERATOR_ID_DWA2002531_HPP diff --git a/include/boost/python/detail/overloads_fwd.hpp b/include/boost/python/detail/overloads_fwd.hpp deleted file mode 100644 index 94ec503f..00000000 --- a/include/boost/python/detail/overloads_fwd.hpp +++ /dev/null @@ -1,19 +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 OVERLOADS_FWD_DWA2002101_HPP -# define OVERLOADS_FWD_DWA2002101_HPP - -namespace boost { namespace python { namespace detail { - -// forward declarations -struct overloads_base; - -template -inline void define_with_defaults(char const* name, OverloadsT const&, NameSpaceT&, SigT const&); - -}}} // namespace boost::python::detail - -#endif // OVERLOADS_FWD_DWA2002101_HPP diff --git a/include/boost/python/detail/pointee.hpp b/include/boost/python/detail/pointee.hpp deleted file mode 100644 index 2af1535f..00000000 --- a/include/boost/python/detail/pointee.hpp +++ /dev/null @@ -1,36 +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 POINTEE_DWA2002323_HPP -# define POINTEE_DWA2002323_HPP - -# include - -namespace boost { namespace python { namespace detail { - -template -struct pointee_impl -{ - template struct apply : remove_pointer {}; -}; - -template <> -struct pointee_impl -{ - template struct apply - { - typedef typename T::element_type type; - }; -}; - -template -struct pointee - : pointee_impl::value>::template apply -{ -}; - -}}} // namespace boost::python::detail - -#endif // POINTEE_DWA2002323_HPP diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp deleted file mode 100644 index 45e307d4..00000000 --- a/include/boost/python/detail/preprocessor.hpp +++ /dev/null @@ -1,67 +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 PREPROCESSOR_DWA200247_HPP -# define PREPROCESSOR_DWA200247_HPP - -# include -# include -# include -# include - -// stuff that should be in the preprocessor library - -# define BOOST_PYTHON_APPLY(x) BOOST_PP_CAT(BOOST_PYTHON_APPLY_, x) - -# define BOOST_PYTHON_APPLY_BOOST_PYTHON_ITEM(v) v -# define BOOST_PYTHON_APPLY_BOOST_PYTHON_NIL - -// cv-qualifiers - -# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -# define BOOST_PYTHON_CV_COUNT 4 -# else -# define BOOST_PYTHON_CV_COUNT 1 -# endif - -# ifndef BOOST_PYTHON_MAX_ARITY -# define BOOST_PYTHON_MAX_ARITY 15 -# endif - -# ifndef BOOST_PYTHON_MAX_BASES -# define BOOST_PYTHON_MAX_BASES 10 -# endif - -# define BOOST_PYTHON_CV_QUALIFIER(i) \ - BOOST_PYTHON_APPLY( \ - BOOST_PP_TUPLE_ELEM(4, i, BOOST_PYTHON_CV_QUALIFIER_I) \ - ) - -# define BOOST_PYTHON_CV_QUALIFIER_I \ - ( \ - BOOST_PYTHON_NIL, \ - BOOST_PYTHON_ITEM(const), \ - BOOST_PYTHON_ITEM(volatile), \ - BOOST_PYTHON_ITEM(const volatile) \ - ) - -// enumerators -# define BOOST_PYTHON_UNARY_ENUM(c, text) BOOST_PP_REPEAT(c, BOOST_PYTHON_UNARY_ENUM_I, text) -# define BOOST_PYTHON_UNARY_ENUM_I(z, n, text) BOOST_PP_COMMA_IF(n) text ## n - -# define BOOST_PYTHON_BINARY_ENUM(c, a, b) BOOST_PP_REPEAT(c, BOOST_PYTHON_BINARY_ENUM_I, (a, b)) -# define BOOST_PYTHON_BINARY_ENUM_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, _), n) - -# define BOOST_PYTHON_ENUM_WITH_DEFAULT(c, text, def) BOOST_PP_REPEAT(c, BOOST_PYTHON_ENUM_WITH_DEFAULT_I, (text, def)) -# define BOOST_PYTHON_ENUM_WITH_DEFAULT_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) = BOOST_PP_TUPLE_ELEM(2, 1, _) - -// fixed text (no commas) -# define BOOST_PYTHON_FIXED(z, n, text) text - -// flags -# define BOOST_PYTHON_FUNCTION_POINTER 0x0001 -# define BOOST_PYTHON_POINTER_TO_MEMBER 0x0002 - -#endif // PREPROCESSOR_DWA200247_HPP diff --git a/include/boost/python/detail/python22_fixed.h b/include/boost/python/detail/python22_fixed.h deleted file mode 100644 index 74ba44e4..00000000 --- a/include/boost/python/detail/python22_fixed.h +++ /dev/null @@ -1,150 +0,0 @@ -// This file is a modified version of Python 2.2/2.2.1 Python.h. As -// such it is: -// -// Copyright (c) 2001, 2002 Python Software Foundation; All Rights -// Reserved -// -// Changes from the original: -// 1. #includes for Python 2.2.1 -// 2. Provides missing extern "C" wrapper for "iterobject.h" and "descrobject.h". -// - -// Changes marked with "Boost.Python modification" -#ifndef Py_PYTHON_H -#define Py_PYTHON_H -/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ - - -/* Enable compiler features; switching on C lib defines doesn't work - here, because the symbols haven't necessarily been defined yet. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -/* Forcing SUSv2 compatibility still produces problems on some - platforms, True64 and SGI IRIX begin two of them, so for now the - define is switched off. */ -#if 0 -#ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 500 -#endif -#endif - -/* Include nearly all Python header files */ - -#include "patchlevel.h" -#include "pyconfig.h" - -#ifdef HAVE_LIMITS_H -#include -#endif - -/* pyconfig.h may or may not define DL_IMPORT */ -#ifndef DL_IMPORT /* declarations for DLL import/export */ -#define DL_IMPORT(RTYPE) RTYPE -#endif -#ifndef DL_EXPORT /* declarations for DLL import/export */ -#define DL_EXPORT(RTYPE) RTYPE -#endif - -#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) -#define _SGI_MP_SOURCE -#endif - -#include -#ifndef NULL -# error "Python.h requires that stdio.h define NULL." -#endif - -#include -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#if PY_MICRO_VERSION == 1 // Boost.Python modification: emulate Python 2.2 -#ifdef HAVE_UNISTD_H -#include -#endif -#endif // Boost.Python modification: emulate Python 2.2 - -/* CAUTION: Build setups should ensure that NDEBUG is defined on the - * compiler command line when building Python in release mode; else - * assert() calls won't be removed. - */ -#include - -#include "pyport.h" - -#include "pymem.h" - -#include "object.h" -#include "objimpl.h" - -#include "pydebug.h" - -#include "unicodeobject.h" -#include "intobject.h" -#include "longobject.h" -#include "floatobject.h" -#ifndef WITHOUT_COMPLEX -#include "complexobject.h" -#endif -#include "rangeobject.h" -#include "stringobject.h" -#include "bufferobject.h" -#include "tupleobject.h" -#include "listobject.h" -#include "dictobject.h" -#include "methodobject.h" -#include "moduleobject.h" -#include "funcobject.h" -#include "classobject.h" -#include "fileobject.h" -#include "cobject.h" -#include "traceback.h" -#include "sliceobject.h" -#include "cellobject.h" -extern "C" { // Boost.Python modification: provide missing extern "C" -#include "iterobject.h" -#include "descrobject.h" -} // Boost.Python modification: provide missing extern "C" -#include "weakrefobject.h" - -#include "codecs.h" -#include "pyerrors.h" - -#include "pystate.h" - -#include "modsupport.h" -#include "pythonrun.h" -#include "ceval.h" -#include "sysmodule.h" -#include "intrcheck.h" -#include "import.h" - -#include "abstract.h" - -#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a)) -#define PyArg_NoArgs(v) PyArg_Parse(v, "") - -/* Convert a possibly signed character to a nonnegative int */ -/* XXX This assumes characters are 8 bits wide */ -#ifdef __CHAR_UNSIGNED__ -#define Py_CHARMASK(c) (c) -#else -#define Py_CHARMASK(c) ((c) & 0xff) -#endif - -#include "pyfpe.h" - -/* These definitions must match corresponding definitions in graminit.h. - There's code in compile.c that checks that they are the same. */ -#define Py_single_input 256 -#define Py_file_input 257 -#define Py_eval_input 258 - -#ifdef HAVE_PTH -/* GNU pth user-space thread support */ -#include -#endif -#endif /* !Py_PYTHON_H */ diff --git a/include/boost/python/detail/raw_pyobject.hpp b/include/boost/python/detail/raw_pyobject.hpp deleted file mode 100644 index e9d36901..00000000 --- a/include/boost/python/detail/raw_pyobject.hpp +++ /dev/null @@ -1,33 +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 RAW_PYOBJECT_DWA2002628_HPP -# define RAW_PYOBJECT_DWA2002628_HPP - -namespace boost { namespace python { namespace detail { - -// -// Define some types which we can use to get around the vagaries of -// PyObject*. We will use these to initialize object instances, and -// keep them in namespace detail to make sure they stay out of the -// hands of users. That is much simpler than trying to grant -// friendship to all the appropriate parties. -// - -// New references are normally checked for null -struct new_reference_t; -typedef new_reference_t* new_reference; - -// Borrowed references are assumed to be non-null -struct borrowed_reference_t; -typedef borrowed_reference_t* borrowed_reference; - -// New references which aren't checked for null -struct new_non_null_reference_t; -typedef new_non_null_reference_t* new_non_null_reference; - -}}} // namespace boost::python::detail - -#endif // RAW_PYOBJECT_DWA2002628_HPP diff --git a/include/boost/python/detail/referent_storage.hpp b/include/boost/python/detail/referent_storage.hpp deleted file mode 100644 index b93d888f..00000000 --- a/include/boost/python/detail/referent_storage.hpp +++ /dev/null @@ -1,75 +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 REFERENT_STORAGE_DWA200278_HPP -# define REFERENT_STORAGE_DWA200278_HPP -# include -# include - -namespace boost { namespace python { namespace detail { - -struct alignment_dummy; -typedef void (*function_ptr)(); -typedef int (alignment_dummy::*member_ptr); -typedef int (alignment_dummy::*member_function_ptr)(); - -# define BOOST_PYTHON_ALIGNER(T, n) \ - typename mpl::if_c< \ - sizeof(T) <= size, T, char>::type t##n - -// Storage for size bytes, aligned to all fundamental types no larger than size -template -union aligned_storage -{ - BOOST_PYTHON_ALIGNER(char, 0); - BOOST_PYTHON_ALIGNER(short, 1); - BOOST_PYTHON_ALIGNER(int, 2); - BOOST_PYTHON_ALIGNER(long, 3); - BOOST_PYTHON_ALIGNER(float, 4); - BOOST_PYTHON_ALIGNER(double, 5); - BOOST_PYTHON_ALIGNER(long double, 6); - BOOST_PYTHON_ALIGNER(void*, 7); - BOOST_PYTHON_ALIGNER(function_ptr, 8); - BOOST_PYTHON_ALIGNER(member_ptr, 9); - BOOST_PYTHON_ALIGNER(member_function_ptr, 10); - char bytes[size]; -}; - -# undef BOOST_PYTHON_ALIGNER - - // Compute the size of T's referent. We wouldn't need this at all, - // but sizeof() is broken in CodeWarriors <= 8.0 - template struct referent_size; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct referent_size - { - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(T)); - }; - -# else - - template struct referent_size - { - static T f(); - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f())); - }; - -# endif - -// A metafunction returning a POD type which can store U, where T == -// U&. If T is not a reference type, returns a POD which can store T. -template -struct referent_storage -{ - typedef aligned_storage::value> type; -}; - -}}} // namespace boost::python::detail - -#endif // REFERENT_STORAGE_DWA200278_HPP diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp deleted file mode 100755 index bb66f13a..00000000 --- a/include/boost/python/detail/result.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// 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 RESULT_DWA2002521_HPP -# define RESULT_DWA2002521_HPP - -# include - -# include - -# include -# include - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// Defines a family of overloaded function which, given x, a function -// pointer, member [function] pointer, or an AdaptableFunction object, -// returns a pointer to type*, where R is the result type of -// invoking the result of bind(x). -// -// In order to work around bugs in deficient compilers, if x might be -// an AdaptableFunction object, you must pass OL as a second argument -// to get this to work portably. - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) -# include BOOST_PP_ITERATE() - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) -# include BOOST_PP_ITERATE() - -template -boost::type* result(R (T::*), int = 0) { return 0; } - -# if (defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140) \ - || (defined(__GNUC__) && __GNUC__ < 3) \ - || (defined(__MWERKS__) && __MWERKS__ < 0x3000) -// This code actually works on all implementations, but why use it when we don't have to? -template -struct get_result_type -{ - typedef boost::type type; -}; - -struct void_type -{ - typedef void type; -}; - -template -struct result_result -{ - typedef typename mpl::if_c< - is_class::value - , get_result_type - , void_type - >::type t1; - - typedef typename t1::type* type; -}; - -template -typename result_result::type -result(X const&, short) { return 0; } - -# else // Simpler code for more-capable compilers -template -boost::type* -result(X const&, short = 0) { return 0; } - -# endif - -}}} // namespace boost::python::detail - -# endif // RESULT_DWA2002521_HPP - -/* --------------- function pointers --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER -# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers)) - -# define N BOOST_PP_ITERATION() - -template -boost::type* result(R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)), int = 0) -{ - return 0; -} - -# undef N - -/* --------------- pointers-to-members --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER -// Outer over cv-qualifiers - -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 -# line BOOST_PP_LINE(__LINE__, result.hpp(pointers-to-members)) -// Inner over arities - -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) - -template -boost::type* result(R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q, int = 0) -{ - return 0; -} - -# undef N -# undef Q - -#endif diff --git a/include/boost/python/detail/scope.hpp b/include/boost/python/detail/scope.hpp deleted file mode 100644 index 94528fa1..00000000 --- a/include/boost/python/detail/scope.hpp +++ /dev/null @@ -1,17 +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 SCOPE_DWA2002927_HPP -# define SCOPE_DWA2002927_HPP - -# include - -namespace boost { namespace python { namespace detail { - -void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc); - -}}} // namespace boost::python::detail - -#endif // SCOPE_DWA2002927_HPP diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp deleted file mode 100644 index ee8cc0b6..00000000 --- a/include/boost/python/detail/string_literal.hpp +++ /dev/null @@ -1,88 +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 STRING_LITERAL_DWA2002629_HPP -# define STRING_LITERAL_DWA2002629_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_string_literal : mpl::false_ -{ -}; - -# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -template -struct is_string_literal : mpl::true_ -{ -}; - -# if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) \ - || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) -// This compiler mistakenly gets the type of string literals as char* -// instead of char[NN]. -template <> -struct is_string_literal : mpl::true_ -{ -}; -# endif - -# else - -// CWPro7 has trouble with the array type deduction above -template -struct is_string_literal - : is_same -{ -}; -# endif -# else -template -struct string_literal_helper -{ - typedef char (&yes_string_literal)[1]; - typedef char (&no_string_literal)[2]; - - template - struct apply - { - typedef apply self; - static T x; - static yes_string_literal check(char const*); - static no_string_literal check(char*); - static no_string_literal check(void const volatile*); - - BOOST_STATIC_CONSTANT( - bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal)); - typedef mpl::bool_ type; - }; -}; - -template <> -struct string_literal_helper -{ - template - struct apply : mpl::false_ - { - }; -}; - -template -struct is_string_literal - : string_literal_helper::value>::apply -{ -}; -# endif - -}}} // namespace boost::python::detail - -#endif // STRING_LITERAL_DWA2002629_HPP diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp deleted file mode 100644 index 67007720..00000000 --- a/include/boost/python/detail/target.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// 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 TARGET_DWA2002521_HPP -# define TARGET_DWA2002521_HPP - -# include - -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) -# include BOOST_PP_ITERATE() - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) -# include BOOST_PP_ITERATE() - -template -boost::type* target(R (T::*)) { return 0; } - -}}} // namespace boost::python::detail - -# endif // TARGET_DWA2002521_HPP - -/* --------------- function pointers --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER -# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers)) - -# define N BOOST_PP_ITERATION() - -template -boost::type* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))) -{ - return 0; -} - -# undef N - -/* --------------- pointers-to-members --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER -// Outer over cv-qualifiers - -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 -# line BOOST_PP_LINE(__LINE__, target.hpp(pointers-to-members)) -// Inner over arities - -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) - -template -boost::type* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) -{ - return 0; -} - -# undef N -# undef Q - -#endif diff --git a/include/boost/python/detail/translate_exception.hpp b/include/boost/python/detail/translate_exception.hpp deleted file mode 100644 index 62f931a5..00000000 --- a/include/boost/python/detail/translate_exception.hpp +++ /dev/null @@ -1,48 +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 TRANSLATE_EXCEPTION_DWA2002810_HPP -# define TRANSLATE_EXCEPTION_DWA2002810_HPP - -# include - -# include -# include - -# include - -namespace boost { namespace python { namespace detail { - -// A ternary function object used to translate C++ exceptions of type -// ExceptionType into Python exceptions by invoking an object of type -// Translate. Typically the translate function will be curried with -// boost::bind(). -template -struct translate_exception -{ - typedef typename add_reference< - typename add_const::type - >::type exception_cref; - - inline bool operator()( - exception_handler const& handler - , function0 const& f - , typename call_traits::param_type translate) const - { - try - { - return handler(f); - } - catch(exception_cref e) - { - translate(e); - return true; - } - } -}; - -}}} // namespace boost::python::detail - -#endif // TRANSLATE_EXCEPTION_DWA2002810_HPP diff --git a/include/boost/python/detail/type_list.hpp b/include/boost/python/detail/type_list.hpp deleted file mode 100644 index 4a09c0be..00000000 --- a/include/boost/python/detail/type_list.hpp +++ /dev/null @@ -1,40 +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_LIST_DWA2002913_HPP -# define TYPE_LIST_DWA2002913_HPP - -# include -# include -# include - -# if BOOST_PYTHON_MAX_ARITY + 2 > BOOST_PYTHON_MAX_BASES -# define BOOST_PYTHON_LIST_SIZE BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY)) -# else -# define BOOST_PYTHON_BASE_LIST_SIZE BOOST_PYTHON_MAX_BASES -# endif - -// Compute the MPL list header to use for lists up to BOOST_PYTHON_LIST_SIZE in length -# if BOOST_PYTHON_LIST_SIZE > 48 -# error Arities above 48 not supported by Boost.Python due to MPL internal limit -# elif BOOST_PYTHON_LIST_SIZE > 38 -# include -# elif BOOST_PYTHON_LIST_SIZE > 28 -# include -# elif BOOST_PYTHON_LIST_SIZE > 18 -# include -# elif BOOST_PYTHON_LIST_SIZE > 8 -# include -# else -# include -# endif - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# include -# else -# include -# endif - -#endif // TYPE_LIST_DWA2002913_HPP diff --git a/include/boost/python/detail/type_list_impl.hpp b/include/boost/python/detail/type_list_impl.hpp deleted file mode 100644 index 50ab2446..00000000 --- a/include/boost/python/detail/type_list_impl.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef BOOST_PP_IS_ITERATING -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -# ifndef TYPE_LIST_IMPL_DWA2002913_HPP -# define TYPE_LIST_IMPL_DWA2002913_HPP - -# include - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -template -struct type_list - : BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE) -{ -}; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PP_DEC(BOOST_PYTHON_LIST_SIZE), )) -# include BOOST_PP_ITERATE() - - -}}} // namespace boost::python::detail - -# endif // TYPE_LIST_IMPL_DWA2002913_HPP - -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define BOOST_PYTHON_VOID_ARGS BOOST_PP_SUB_D(1,BOOST_PYTHON_LIST_SIZE,N) - -template < - BOOST_PP_ENUM_PARAMS_Z(1, N, class T) - > -struct type_list< - BOOST_PP_ENUM_PARAMS_Z(1, N, T) - BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM( - BOOST_PYTHON_VOID_ARGS, BOOST_PYTHON_FIXED, mpl::void_) - > - : BOOST_PP_CAT(mpl::list,N) -{ -}; - -# undef BOOST_PYTHON_VOID_ARGS -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp deleted file mode 100644 index 7c9d7fab..00000000 --- a/include/boost/python/detail/type_list_impl_no_pts.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef BOOST_PP_IS_ITERATING -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -# ifndef TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP -# define TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP - -# include - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -template< typename T > -struct is_list_arg -{ - enum { value = true }; -}; - -template<> -struct is_list_arg -{ - enum { value = false }; -}; - -template struct type_list_impl_chooser; - -# define BOOST_PYTHON_LIST_ACTUAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,T) -# define BOOST_PYTHON_LIST_FORMAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,class T) - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_LIST_SIZE, )) -# include BOOST_PP_ITERATE() - -# define BOOST_PYTHON_PLUS() + -# define BOOST_PYTHON_IS_LIST_ARG(z, n, data) \ - BOOST_PP_IF(n, BOOST_PYTHON_PLUS, BOOST_PP_EMPTY)() \ - is_list_arg< BOOST_PP_CAT(T,n) >::value - -template< - BOOST_PYTHON_LIST_FORMAL_PARAMS - > -struct type_list_count_args -{ - enum { value = - BOOST_PP_REPEAT_1(BOOST_PYTHON_LIST_SIZE, BOOST_PYTHON_IS_LIST_ARG, _) - }; -}; - -template< - BOOST_PYTHON_LIST_FORMAL_PARAMS - > -struct type_list_impl -{ - typedef type_list_count_args< BOOST_PYTHON_LIST_ACTUAL_PARAMS > arg_num_; - typedef typename detail::type_list_impl_chooser< arg_num_::value > - ::template result_< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type type; -}; - -template< - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_) - > -struct type_list - : detail::type_list_impl< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type -{ - typedef typename detail::type_list_impl< - BOOST_PYTHON_LIST_ACTUAL_PARAMS - >::type type; -}; - -# undef BOOST_PYTHON_IS_LIST_ARG -# undef BOOST_PYTHON_PLUS -# undef BOOST_PYTHON_LIST_FORMAL_PARAMS -# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS - -}}} // namespace boost::python::detail - -# endif // TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP - -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() - -template<> -struct type_list_impl_chooser -{ - template< - BOOST_PYTHON_LIST_FORMAL_PARAMS - > - struct result_ - { - typedef typename BOOST_PP_CAT(mpl::list,N)< - BOOST_PP_ENUM_PARAMS(N, T) - >::type type; - }; -}; - -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp deleted file mode 100644 index 878b6cc1..00000000 --- a/include/boost/python/detail/unwind_type.hpp +++ /dev/null @@ -1,151 +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 UNWIND_TYPE_DWA200222_HPP -# define UNWIND_TYPE_DWA200222_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -template -inline typename Generator::result_type -unwind_type_cv(U* p, cv_unqualified, Generator* = 0) -{ - return Generator::execute(p); -} - -template -inline typename Generator::result_type -unwind_type_cv(U const* p, const_, Generator* = 0) -{ - return unwind_type(const_cast(p), (Generator*)0); -} - -template -inline typename Generator::result_type -unwind_type_cv(U volatile* p, volatile_, Generator* = 0) -{ - return unwind_type(const_cast(p), (Generator*)0); -} - -template -inline typename Generator::result_type -unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0) -{ - return unwind_type(const_cast(p), (Generator*)0); -} - -template -inline typename Generator::result_type -unwind_ptr_type(U* p, Generator* = 0) -{ - typedef typename cv_category::type tag; - return unwind_type_cv(p, tag()); -} - -template -struct unwind_helper -{ - template - static typename Generator::result_type - execute(U p, Generator* = 0) - { - return unwind_ptr_type(p, (Generator*)0); - } -}; - -template <> -struct unwind_helper -{ - template - static typename Generator::result_type - execute(U& p, Generator* = 0) - { - return unwind_ptr_type(&p, (Generator*)0); - } -}; - -template -inline typename Generator::result_type -unwind_type(U const& p, Generator* = 0) -{ - return unwind_helper::value>::execute(p, (Generator*)0); -} - -enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 }; -template struct unwind_helper2; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U(*)(), Generator* = 0) - { - return unwind_ptr_type((U*)0, (Generator*)0); - } -}; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U*(*)(), Generator* = 0) - { - return unwind_ptr_type((U*)0, (Generator*)0); - } -}; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U&(*)(), Generator* = 0) - { - return unwind_ptr_type((U*)0, (Generator*)0); - } -}; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U&(*)(), Generator* = 0) - { - return unwind_ptr_type(U(0), (Generator*)0); - } -}; - -// Call this one with both template parameters explicitly specified -// and no function arguments: -// -// return unwind_type(); -// -// Doesn't work if T is an array type; we could handle that case, but -// why bother? -template -inline typename Generator::result_type -unwind_type(boost::type*p = 0, Generator* = 0) -{ - BOOST_STATIC_CONSTANT(int, indirection - = (is_pointer::value ? pointer_ : 0) - + (is_reference_to_pointer::value - ? reference_to_pointer_ - : is_reference::value - ? reference_ - : 0)); - - return unwind_helper2::execute((U(*)())0,(Generator*)0); -} - -}}} // namespace boost::python::detail - -#endif // UNWIND_TYPE_DWA200222_HPP diff --git a/include/boost/python/detail/value_is_shared_ptr.hpp b/include/boost/python/detail/value_is_shared_ptr.hpp deleted file mode 100644 index 5d2c8abe..00000000 --- a/include/boost/python/detail/value_is_shared_ptr.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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_IS_SHARED_PTR_DWA2003224_HPP -# define VALUE_IS_SHARED_PTR_DWA2003224_HPP - -# include -# include - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_VALUE_IS_XXX_DEF(shared_ptr, shared_ptr, 1) - -}}} // namespace boost::python::detail - -#endif // VALUE_IS_SHARED_PTR_DWA2003224_HPP diff --git a/include/boost/python/detail/value_is_xxx.hpp b/include/boost/python/detail/value_is_xxx.hpp deleted file mode 100644 index f0a9a11c..00000000 --- a/include/boost/python/detail/value_is_xxx.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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_IS_XXX_DWA2003224_HPP -# define VALUE_IS_XXX_DWA2003224_HPP - -# include -# include -# include - -# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -# include -# include - -# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct value_is_##name \ -{ \ - typedef char yes; \ - typedef char (&no)[2]; \ - \ - static typename add_reference::type dummy; \ - \ - template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ - static yes test( \ - qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) > const&, int \ - ); \ - \ - template \ - static no test(U&, ...); \ - \ - BOOST_STATIC_CONSTANT( \ - bool, value \ - = (sizeof(test(dummy, 0)) == sizeof(yes))); \ - \ - typedef mpl::bool_ type; \ -}; - -# else - -# include -# include -# include - -# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct value_is_##name \ -{ \ - BOOST_PYTHON_IS_XXX_DEF(name,qualified_name,nargs) \ - BOOST_STATIC_CONSTANT(bool, value = is_##name< \ - typename remove_cv< \ - typename remove_reference::type \ - >::type \ - >::value); \ - typedef mpl::bool_ type; \ - \ -}; - -# endif - -#endif // VALUE_IS_XXX_DWA2003224_HPP diff --git a/include/boost/python/detail/void_ptr.hpp b/include/boost/python/detail/void_ptr.hpp deleted file mode 100644 index 676a5cac..00000000 --- a/include/boost/python/detail/void_ptr.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VOID_PTR_DWA200239_HPP -# define VOID_PTR_DWA200239_HPP - -namespace boost { namespace python { namespace detail { - -template -inline U& void_ptr_to_reference(void const volatile* p, U&(*)()) -{ - return *(U*)p; -} - -template -inline void write_void_ptr(void const volatile* storage, void* ptr, T*) -{ - *(T**)storage = (T*)ptr; -} - -// writes U(ptr) into the storage -template -inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)()) -{ - // stripping CV qualification suppresses warnings on older EDGs - typedef typename remove_cv::type u_stripped; - write_void_ptr(storage, ptr, u_stripped(0)); -} - -}}} // namespace boost::python::detail - -#endif // VOID_PTR_DWA200239_HPP diff --git a/include/boost/python/detail/void_return.hpp b/include/boost/python/detail/void_return.hpp deleted file mode 100644 index 512aa636..00000000 --- a/include/boost/python/detail/void_return.hpp +++ /dev/null @@ -1,43 +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 VOID_RETURN_DWA200274_HPP -# define VOID_RETURN_DWA200274_HPP - -# include - -namespace boost { namespace python { namespace detail { - -struct void_return -{ - void_return() {} - private: - void operator=(void_return const&); -}; - -template -struct returnable -{ - typedef T type; -}; - -# ifdef BOOST_NO_VOID_RETURNS -template <> -struct returnable -{ - typedef void_return type; -}; - -# ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS -template <> struct returnable : returnable {}; -template <> struct returnable : returnable {}; -template <> struct returnable : returnable {}; -# endif - -# endif // BOOST_NO_VOID_RETURNS - -}}} // namespace boost::python::detail - -#endif // VOID_RETURN_DWA200274_HPP diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp deleted file mode 100644 index 6cb8dee2..00000000 --- a/include/boost/python/detail/wrap_python.hpp +++ /dev/null @@ -1,157 +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) - -// -// Python's LongObject.h helpfully #defines ULONGLONG_MAX for us, -// which confuses Boost's config -// -#include -#ifndef ULONG_MAX -# define BOOST_PYTHON_ULONG_MAX_UNDEFINED -#endif -#ifndef LONGLONG_MAX -# define BOOST_PYTHON_LONGLONG_MAX_UNDEFINED -#endif -#ifndef ULONGLONG_MAX -# define BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED -#endif - -// -// Get ahold of Python's version number -// -#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__) - -# define SIZEOF_LONG 4 - -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 - -typedef int pid_t; - -# define WORD_BIT 32 -# define hypot _hypot -# include - -# if PY_MAJOR_VERSION < 2 -# define HAVE_CLOCK -# define HAVE_STRFTIME -# define HAVE_STRERROR -# endif - -# define NT_THREADS - -# 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 -# endif - -#endif // _WIN32 - -#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2 && PY_MICRO_VERSION < 2 -# include -#else -# include -#endif - -#ifdef BOOST_PYTHON_ULONG_MAX_UNDEFINED -# undef ULONG_MAX -# undef BOOST_PYTHON_ULONG_MAX_UNDEFINED -#endif - -#ifdef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED -# undef LONGLONG_MAX -# undef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED -#endif - -#ifdef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED -# undef ULONGLONG_MAX -# undef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED -#endif - -#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/dict.hpp b/include/boost/python/dict.hpp deleted file mode 100644 index c1565bcc..00000000 --- a/include/boost/python/dict.hpp +++ /dev/null @@ -1,151 +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 DICT_20020706_HPP -#define DICT_20020706_HPP - -#include -#include -#include -#include - -namespace boost { namespace python { - -class dict; - -namespace detail -{ - struct BOOST_PYTHON_DECL dict_base : object - { - // D.clear() -> None. Remove all items from D. - void clear(); - - // D.copy() -> a shallow copy of D - dict copy(); - - // D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None. - object get(object_cref k) const; - - object get(object_cref k, object_cref d) const; - - // D.has_key(k) -> 1 if D has a key k, else 0 - bool has_key(object_cref k) const; - - // D.items() -> list of D's (key, value) pairs, as 2-tuples - list items() const; - - // D.iteritems() -> an iterator over the (key, value) items of D - object iteritems() const; - - // D.iterkeys() -> an iterator over the keys of D - object iterkeys() const; - - // D.itervalues() -> an iterator over the values of D - object itervalues() const; - - // D.keys() -> list of D's keys - list keys() const; - - // D.popitem() -> (k, v), remove and return some (key, value) pair as a - // 2-tuple; but raise KeyError if D is empty - tuple popitem(); - - // D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k) - object setdefault(object_cref k); - - object setdefault(object_cref k, object_cref d); - - // D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k] - void update(object_cref E); - - // D.values() -> list of D's values - list values() const; - - protected: - // dict() -> new empty dictionary. - // dict(mapping) -> new dictionary initialized from a mapping object's - // (key, value) pairs. - // dict(seq) -> new dictionary initialized as if via: - dict_base(); // new dict - explicit dict_base(object_cref data); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict_base, object) - private: - static detail::new_reference call(object const&); - }; -} - -class dict : public detail::dict_base -{ - typedef detail::dict_base base; - public: - // dict() -> new empty dictionary. - // dict(mapping) -> new dictionary initialized from a mapping object's - // (key, value) pairs. - // dict(seq) -> new dictionary initialized as if via: - dict() {} // new dict - - template - explicit dict(T const& data) - : base(object(data)) - { - } - - template - object get(T const& k) const - { - return base::get(object(k)); - } - - template - object get(T1 const& k, T2 const& d) const - { - return base::get(object(k),object(d)); - } - - template - bool has_key(T const& k) const - { - return base::has_key(object(k)); - } - - template - object setdefault(T const& k) - { - return base::setdefault(object(k)); - } - - template - object setdefault(T1 const& k, T2 const& d) - { - return base::setdefault(object(k),object(d)); - } - - template - void update(T const& E) - { - base::update(object(E)); - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyDict_Type,dict> - { - }; -} - -}} // namespace boost::python - -#endif - diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp deleted file mode 100644 index 02092510..00000000 --- a/include/boost/python/enum.hpp +++ /dev/null @@ -1,101 +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 ENUM_DWA200298_HPP -# define ENUM_DWA200298_HPP - -# include -# include -# include - -namespace boost { namespace python { - -template -struct enum_ : public objects::enum_base -{ - typedef objects::enum_base base; - - // Declare a new enumeration type in the current scope() - enum_(char const* name); - - // Add a new enumeration value with the given name and value. - inline enum_& value(char const* name, T); - - // Add all of the defined enumeration values to the current scope with the - // same names used here. - inline enum_& export_values(); - private: - static PyObject* to_python(void const* x); - static void* convertible_from_python(PyObject* obj); - static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data); -}; - -template -inline enum_::enum_(char const* name) - : base( - name - , &enum_::to_python - , &enum_::convertible_from_python - , &enum_::construct - , type_id()) -{ -} - -// This is the conversion function that gets registered for converting -// these enums to Python. -template -PyObject* enum_::to_python(void const* x) -{ - return base::to_python( - converter::registered::converters.m_class_object - , static_cast(*(T const*)x)); -} - -// -// The following two static functions serve as the elements of an -// rvalue from_python converter for the enumeration type. -// - -// This checks that a given Python object can be converted to the -// enumeration type. -template -void* enum_::convertible_from_python(PyObject* obj) -{ - return PyObject_IsInstance( - obj - , upcast( - converter::registered::converters.m_class_object)) - - ? obj : 0; -} - -// Constructs an instance of the enumeration type in the from_python -// data. -template -void enum_::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data) -{ - T x = static_cast(PyInt_AS_LONG(obj)); - void* const storage = ((converter::rvalue_from_python_storage*)data)->storage.bytes; - new (storage) T(x); - data->convertible = storage; -} - -template -inline enum_& enum_::value(char const* name, T x) -{ - this->add_value(name, static_cast(x)); - return *this; -} - -template -inline enum_& enum_::export_values() -{ - this->base::export_values(); - return *this; -} - -}} // namespace boost::python - -#endif // ENUM_DWA200298_HPP diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp deleted file mode 100644 index cd0b3586..00000000 --- a/include/boost/python/errors.hpp +++ /dev/null @@ -1,55 +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 BOOST_PYTHON_DECL error_already_set {}; -struct BOOST_PYTHON_DECL argument_error : error_already_set {}; - -// Handles exceptions caught just before returning to Python code. -// Returns true iff an exception was caught. -BOOST_PYTHON_DECL bool handle_exception_impl(function0); - -template -bool handle_exception(T f) -{ - return handle_exception_impl(function0(boost::ref(f))); -} - -namespace detail { inline void rethrow() { throw; } } - -inline void handle_exception() -{ - handle_exception(detail::rethrow); -} - -BOOST_PYTHON_DECL void throw_argument_error(); -BOOST_PYTHON_DECL void throw_error_already_set(); - -template -inline T* expect_non_null(T* x) -{ - if (x == 0) - throw_error_already_set(); - return x; -} - -// Return source if it is an instance of pytype; throw an appropriate -// exception otherwise. -BOOST_PYTHON_DECL PyObject* pytype_check(PyTypeObject* pytype, PyObject* source); - -}} // namespace boost::python - -#endif // ERRORS_DWA052500_H_ diff --git a/include/boost/python/exception_translator.hpp b/include/boost/python/exception_translator.hpp deleted file mode 100644 index c7581780..00000000 --- a/include/boost/python/exception_translator.hpp +++ /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. -#ifndef EXCEPTION_TRANSLATOR_DWA2002810_HPP -# define EXCEPTION_TRANSLATOR_DWA2002810_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -template -void register_exception_translator(Translate const& translate, boost::type* = 0) -{ - detail::register_exception_handler( - bind(detail::translate_exception(), _1, _2, translate) - ); -} - -}} // namespace boost::python - -#endif // EXCEPTION_TRANSLATOR_DWA2002810_HPP diff --git a/include/boost/python/extract.hpp b/include/boost/python/extract.hpp deleted file mode 100644 index 27a0b60d..00000000 --- a/include/boost/python/extract.hpp +++ /dev/null @@ -1,246 +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 EXTRACT_DWA200265_HPP -# define EXTRACT_DWA200265_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace converter -{ - template - struct extract_pointer - { - typedef Ptr result_type; - extract_pointer(PyObject*); - - bool check() const; - Ptr operator()() const; - - private: - PyObject* m_source; - void* m_result; - }; - - template - struct extract_reference - { - typedef Ref result_type; - extract_reference(PyObject*); - - bool check() const; - Ref operator()() const; - - private: - PyObject* m_source; - void* m_result; - }; - - template - struct extract_rvalue : private noncopyable - { - typedef typename mpl::if_< - python::detail::copy_ctor_mutates_rhs - , T& - , typename call_traits::param_type - >::type result_type; - - extract_rvalue(PyObject*); - - bool check() const; - result_type operator()() const; - private: - PyObject* m_source; - mutable rvalue_from_python_data m_data; - }; - - template - struct extract_object_manager - { - typedef T result_type; - extract_object_manager(PyObject*); - - bool check() const; - result_type operator()() const; - private: - PyObject* m_source; - }; - - template - struct select_extract - { - BOOST_STATIC_CONSTANT( - bool, obj_mgr = is_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ref = is_reference::value); - - typedef typename mpl::if_c< - obj_mgr - , extract_object_manager - , typename mpl::if_c< - ptr - , extract_pointer - , typename mpl::if_c< - ref - , extract_reference - , extract_rvalue - >::type - >::type - >::type type; - }; -} - -template -struct extract - : converter::select_extract::type -{ - private: - typedef typename converter::select_extract::type base; - public: - typedef typename base::result_type result_type; - - operator result_type() const - { - return (*this)(); - } - - extract(PyObject*); - extract(object const&); -}; - -// -// Implementations -// -template -inline extract::extract(PyObject* o) - : base(o) -{ -} - -template -inline extract::extract(object const& o) - : base(o.ptr()) -{ -} - -namespace converter -{ - template - inline extract_rvalue::extract_rvalue(PyObject* x) - : m_source(x) - , m_data( - (rvalue_from_python_stage1)(x, registered::converters) - ) - { - } - - template - inline bool - extract_rvalue::check() const - { - return m_data.stage1.convertible; - } - - template - inline typename extract_rvalue::result_type - extract_rvalue::operator()() const - { - return *(T*)( - // Only do the stage2 conversion once - m_data.stage1.convertible == m_data.storage.bytes - ? m_data.storage.bytes - : (rvalue_from_python_stage2)(m_source, m_data.stage1, registered::converters) - ); - } - - template - inline extract_reference::extract_reference(PyObject* obj) - : m_source(obj) - , m_result( - (get_lvalue_from_python)(obj, registered::converters) - ) - { - } - - template - inline bool extract_reference::check() const - { - return m_result != 0; - } - - template - inline Ref extract_reference::operator()() const - { - if (m_result == 0) - (throw_no_reference_from_python)(m_source, registered::converters); - - return python::detail::void_ptr_to_reference(m_result, (Ref(*)())0); - } - - template - inline extract_pointer::extract_pointer(PyObject* obj) - : m_source(obj) - , m_result( - obj == Py_None ? 0 : (get_lvalue_from_python)(obj, registered_pointee::converters) - ) - { - } - - template - inline bool extract_pointer::check() const - { - return m_source == Py_None || m_result != 0; - } - - template - inline Ptr extract_pointer::operator()() const - { - if (m_result == 0 && m_source != Py_None) - (throw_no_pointer_from_python)(m_source, registered_pointee::converters); - - return Ptr(m_result); - } - - template - inline extract_object_manager::extract_object_manager(PyObject* obj) - : m_source(obj) - { - } - - template - inline bool extract_object_manager::check() const - { - return object_manager_traits::check(m_source); - } - - template - inline T extract_object_manager::operator()() const - { - return T( - object_manager_traits::adopt(python::incref(m_source)) - ); - } -} - -}} // namespace boost::python::converter - -#endif // EXTRACT_DWA200265_HPP diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp deleted file mode 100755 index 98534944..00000000 --- a/include/boost/python/handle.hpp +++ /dev/null @@ -1,249 +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 HANDLE_DWA200269_HPP -# define HANDLE_DWA200269_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template struct null_ok; - -template -inline null_ok* allow_null(T* p) -{ - return (null_ok*)p; -} - -namespace detail -{ - template - inline T* manage_ptr(detail::borrowed >* p, int) - { - return python::xincref((T*)p); - } - - template - inline T* manage_ptr(null_ok >* p, int) - { - return python::xincref((T*)p); - } - - template - inline T* manage_ptr(detail::borrowed* p, long) - { - return python::incref(expect_non_null((T*)p)); - } - - template - inline T* manage_ptr(null_ok* p, long) - { - return (T*)p; - } - - template - inline T* manage_ptr(T* p, ...) - { - return expect_non_null(p); - } -} - -template -class handle -{ - typedef T* (handle::* bool_type )() const; - - public: // types - typedef T element_type; - - public: // member functions - handle(); - ~handle(); - - template - explicit handle(Y* p) - : m_p( - python::upcast( - detail::manage_ptr(p, 0) - ) - ) - { - } - - handle& operator=(handle const& r); - -#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) - - template - handle& operator=(handle const & r) // never throws - { - python::xdecref(m_p); - m_p = python::xincref(python::upcast(r.get())); - return *this; - } - -#endif - - template - handle(handle const& r) - : m_p(python::xincref(python::upcast(r.get()))) - { - } - - handle(handle const& r) - : m_p(python::xincref(r.m_p)) - { - } - - T* operator-> () const; - T& operator* () const; - T* get() const; - T* release(); - void reset(); - - operator bool_type() const // never throws - { - return m_p ? &handle::get : 0; - } - bool operator! () const; // never throws - - public: // implementation details -- do not touch - // Defining this in the class body suppresses a VC7 link failure - inline handle(detail::borrowed_reference x) - : m_p( - python::incref( - downcast((PyObject*)x) - )) - { - } - - private: // data members - T* m_p; -}; - -typedef handle type_handle; - -// -// Compile-time introspection -// -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class is_handle -{ - public: - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -class is_handle > -{ - public: - BOOST_STATIC_CONSTANT(bool, value = true); -}; -# else -namespace detail -{ - typedef char (&yes_handle_t)[1]; - typedef char (&no_handle_t)[2]; - - no_handle_t is_handle_test(...); - - template - yes_handle_t is_handle_test(boost::type< handle >); -} - -template -class is_handle -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_handle_test(boost::type())) - == sizeof(detail::yes_handle_t))); -}; -# endif - -// -// implementations -// -template -inline handle::handle() - : m_p(0) -{ -} - -template -inline handle::~handle() -{ - python::xdecref(m_p); -} - -template -inline handle& handle::operator=(handle const& r) -{ - python::xdecref(m_p); - m_p = python::xincref(r.m_p); - return *this; -} - -template -inline T* handle::operator->() const -{ - return m_p; -} - -template -inline T& handle::operator*() const -{ - return *m_p; -} - -template -inline T* handle::get() const -{ - return m_p; -} - -template -inline bool handle::operator!() const -{ - return m_p == 0; -} - -template -inline T* handle::release() -{ - T* result = m_p; - m_p = 0; - return result; -} - -template -inline void handle::reset() -{ - python::xdecref(m_p); - m_p = 0; -} - -// Because get_managed_object must return a non-null PyObject*, we -// return Py_None if the handle is null. -template -inline PyObject* get_managed_object(handle const& h, tag_t) -{ - return h.get() ? python::upcast(h.get()) : Py_None; -} - -}} // namespace boost::python - - -#endif // HANDLE_DWA200269_HPP diff --git a/include/boost/python/handle_fwd.hpp b/include/boost/python/handle_fwd.hpp deleted file mode 100755 index afcce163..00000000 --- a/include/boost/python/handle_fwd.hpp +++ /dev/null @@ -1,17 +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 HANDLE_FWD_DWA2002615_HPP -# define HANDLE_FWD_DWA2002615_HPP - -# include - -namespace boost { namespace python { - -template class handle; - -}} // namespace boost::python - -#endif // HANDLE_FWD_DWA2002615_HPP diff --git a/include/boost/python/has_back_reference.hpp b/include/boost/python/has_back_reference.hpp deleted file mode 100644 index 95a3ae9a..00000000 --- a/include/boost/python/has_back_reference.hpp +++ /dev/null @@ -1,22 +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 HAS_BACK_REFERENCE_DWA2002323_HPP -# define HAS_BACK_REFERENCE_DWA2002323_HPP - -namespace boost { namespace python { - -// traits class which users can specialize to indicate that a class -// contains a back-reference to its owning PyObject* -template -struct has_back_reference -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - - -}} // namespace boost::python - -#endif // HAS_BACK_REFERENCE_DWA2002323_HPP diff --git a/include/boost/python/implicit.hpp b/include/boost/python/implicit.hpp deleted file mode 100644 index a6e73eba..00000000 --- a/include/boost/python/implicit.hpp +++ /dev/null @@ -1,28 +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 IMPLICIT_DWA2002325_HPP -# define IMPLICIT_DWA2002325_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -template -void implicitly_convertible(boost::type* = 0, boost::type* = 0) -{ - typedef converter::implicit functions; - - converter::registry::push_back( - &functions::convertible - , &functions::construct - , type_id()); -} - -}} // namespace boost::python - -#endif // IMPLICIT_DWA2002325_HPP diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp deleted file mode 100644 index 39bf4ac7..00000000 --- a/include/boost/python/init.hpp +++ /dev/null @@ -1,446 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 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 INIT_JDG20020820_HPP -#define INIT_JDG20020820_HPP - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -# include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -/////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT \ - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ - BOOST_PYTHON_MAX_ARITY, \ - class T, \ - mpl::void_) \ - -#define BOOST_PYTHON_OVERLOAD_TYPES \ - BOOST_PP_ENUM_PARAMS_Z(1, \ - BOOST_PYTHON_MAX_ARITY, \ - class T) \ - -#define BOOST_PYTHON_OVERLOAD_ARGS \ - BOOST_PP_ENUM_PARAMS_Z(1, \ - BOOST_PYTHON_MAX_ARITY, \ - T) \ - -/////////////////////////////////////////////////////////////////////////////// -namespace boost { namespace python { - -template -class init; // forward declaration - - -template -struct optional; // forward declaration - -namespace detail -{ - namespace error - { - template - struct more_keywords_than_init_arguments - { - typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1]; - }; - } - - /////////////////////////////////////////////////////////////////////////// - // - // is_optional::value - // - // This metaprogram checks if T is an optional - // - /////////////////////////////////////////////////////////////////////////// - #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - - template - struct is_optional { - - private: - - template - static boost::type_traits::yes_type f(optional); - static boost::type_traits::no_type f(...); - static T t(); - - public: - - BOOST_STATIC_CONSTANT( - bool, value = - sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); - typedef mpl::bool_ type; - - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) - }; - - /////////////////////////////////////// - #else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - - template - struct is_optional_impl { - - BOOST_STATIC_CONSTANT(bool, value = false); - }; - - template - struct is_optional_impl > { - - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template - struct is_optional : is_optional_impl - { - typedef mpl::bool_::value> type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) - }; - #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -} // namespace detail - -template -struct init_base -{ - init_base(char const* doc_, detail::keyword_range const& keywords_) - : m_doc(doc_), m_keywords(keywords_) - {} - - init_base(char const* doc_) - : m_doc(doc_) - {} - - DerivedT const& derived() const - { - return *static_cast(this); - } - - char const* doc_string() const - { - return m_doc; - } - - detail::keyword_range const& keywords() const - { - return m_keywords; - } - - static default_call_policies call_policies() - { - return default_call_policies(); - } - - private: // data members - char const* m_doc; - detail::keyword_range m_keywords; -}; - -template -class init_with_call_policies - : public init_base > -{ - typedef init_base > base; - public: - BOOST_STATIC_CONSTANT(int, n_arguments = InitT::n_arguments); - BOOST_STATIC_CONSTANT(int, n_defaults = InitT::n_defaults); - - typedef typename InitT::reversed_args reversed_args; - - init_with_call_policies( - CallPoliciesT const& policies_ - , char const* doc_ - , detail::keyword_range const& keywords - ) - : base(doc_, keywords) - , m_policies(policies_) - {} - - CallPoliciesT const& call_policies() const - { - return this->m_policies; - } - - private: // data members - CallPoliciesT m_policies; -}; - -template -class init : public init_base > -{ - typedef init_base > base; - public: - typedef init self_t; - - init(char const* doc_ = 0) - : base(doc_) - { - } - - template - init(char const* doc_, Keywords const& kw) - : base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size)) - { - typedef typename detail::error::more_keywords_than_init_arguments< - Keywords::size, n_arguments - >::too_many_keywords assertion; - } - - template - init(Keywords const& kw, char const* doc_ = 0) - : base(doc_, kw.range()) - { - typedef typename detail::error::more_keywords_than_init_arguments< - Keywords::size, n_arguments - >::too_many_keywords assertion; - } - - template - init_with_call_policies - operator[](CallPoliciesT const& policies) const - { - return init_with_call_policies( - policies, this->doc_string(), this->keywords()); - } - - typedef detail::type_list signature_; - typedef typename mpl::end::type finish; - - // Find the optional<> element, if any - typedef typename mpl::find_if< - signature_, detail::is_optional - >::type opt; - - - // Check to make sure the optional<> element, if any, is the last one - typedef typename mpl::apply_if< - is_same - , mpl::identity - , mpl::next - >::type expected_finish; - BOOST_STATIC_ASSERT((is_same::value)); - - typedef typename mpl::apply_if< - is_same - , mpl::list0<> - , opt - >::type optional_args; - - // Count the number of default args - BOOST_STATIC_CONSTANT(int, n_defaults = mpl::size::value); - - typedef typename mpl::iterator_range< - typename mpl::begin::type - , opt - >::type required_args; - - // Build a reverse image of all the args, including optionals - typedef typename mpl::fold< - required_args - , mpl::list0<> - , mpl::push_front<> - >::type reversed_required; - - typedef typename mpl::fold< - optional_args - , reversed_required - , mpl::push_front<> - >::type reversed_args; - - // Count the maximum number of arguments - BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); -}; - -/////////////////////////////////////////////////////////////////////////////// -// -// optional -// -// optional::type returns a typelist. -// -/////////////////////////////////////////////////////////////////////////////// -template -struct optional - : detail::type_list -{ -}; - -namespace detail -{ - template - void def_init_reversed( - ClassT& cl - , ReversedArgs const& - , CallPoliciesT const& policies - , char const* doc - , detail::keyword_range const& keywords_ - ) - { - typedef typename mpl::fold< - ReversedArgs - , mpl::list0<> - , mpl::push_front<> - >::type args; - - typedef typename ClassT::holder_selector holder_selector_t; -# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - typedef typename holder_selector_t::type selector_t; -# endif - typedef typename ClassT::held_type held_type_t; - - cl.def( - "__init__", - detail::make_keyword_range_constructor( - policies - , keywords_ -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - // Using runtime type selection works around a CWPro7 bug. - , holder_selector_t::execute((held_type_t*)0).get() -# else - , selector_t::get() -# endif - ) - , doc - ); - } - - /////////////////////////////////////////////////////////////////////////////// - // - // define_class_init_helper::apply - // - // General case - // - // Accepts a class_ and an arguments list. Defines a constructor - // for the class given the arguments and recursively calls - // define_class_init_helper::apply with one less arguments (the - // rightmost argument is shaved off) - // - /////////////////////////////////////////////////////////////////////////////// - template - struct define_class_init_helper { - - template - static void apply( - ClassT& cl - , CallPoliciesT const& policies - , ReversedArgs const& args - , char const* doc - , detail::keyword_range keywords) - { - def_init_reversed(cl, args, policies, doc, keywords); - - if (keywords.second > keywords.first) - --keywords.second; - - typename mpl::pop_front::type next; - define_class_init_helper::apply(cl, policies, next, doc, keywords); - } - }; - - /////////////////////////////////////////////////////////////////////////////// - // - // define_class_init_helper<0>::apply - // - // Terminal case - // - // Accepts a class_ and an arguments list. Defines a constructor - // for the class given the arguments. - // - /////////////////////////////////////////////////////////////////////////////// - template <> - struct define_class_init_helper<0> { - - template - static void apply( - ClassT& cl - , CallPoliciesT const& policies - , ReversedArgs const& args - , char const* doc - , detail::keyword_range const& keywords) - { - def_init_reversed(cl, args, policies, doc, keywords); - } - }; -} - -/////////////////////////////////////////////////////////////////////////////// -// -// define_init -// -// Accepts a class_ and an init-list. Defines a set of constructors for -// the class given the arguments. The init list (see init above) has -// n_defaults (number of default arguments and n_arguments (number of -// actual arguments). This function defines n_defaults + 1 constructors -// for the class. Each constructor after the first has one less argument -// to its right. Example: -// -// init -// -// Defines: -// -// __init__(int, char, long, double) -// __init__(int, char, long) -// __init__(int, char) -// __init__(int) -// -/////////////////////////////////////////////////////////////////////////////// -template -void -define_init(ClassT& cl, InitT const& i) -{ - typedef typename InitT::reversed_args reversed_args; - detail::define_class_init_helper::apply( - cl, i.call_policies(), reversed_args(), i.doc_string(), i.keywords()); -} - -}} // namespace boost::python - -#undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT -#undef BOOST_PYTHON_OVERLOAD_TYPES -#undef BOOST_PYTHON_OVERLOAD_ARGS -#undef BOOST_PYTHON_IS_OPTIONAL_VALUE -#undef BOOST_PYTHON_APPEND_TO_INIT - -/////////////////////////////////////////////////////////////////////////////// -#endif // INIT_JDG20020820_HPP - - - - - - - - diff --git a/include/boost/python/instance_holder.hpp b/include/boost/python/instance_holder.hpp deleted file mode 100755 index 28aa02e8..00000000 --- a/include/boost/python/instance_holder.hpp +++ /dev/null @@ -1,57 +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 INSTANCE_HOLDER_DWA2002517_HPP -# define INSTANCE_HOLDER_DWA2002517_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -// Base class for all holders -struct BOOST_PYTHON_DECL instance_holder : private noncopyable -{ - public: - instance_holder(); - virtual ~instance_holder(); - - // return the next holder in a chain - instance_holder* next() const; - - virtual void* holds(type_info) = 0; - - void install(PyObject* inst) throw(); - - // These functions should probably be located elsewhere. - - // Allocate storage for an object of the given size at the given - // offset in the Python instance<> object if bytes are available - // there. Otherwise allocate size bytes of heap memory. - static void* allocate(PyObject*, std::size_t offset, std::size_t size); - - // Deallocate storage from the heap if it was not carved out of - // the given Python object by allocate(), above. - static void deallocate(PyObject*, void* storage) throw(); - private: - instance_holder* m_next; -}; - -// This macro is needed for implementation of derived holders -# define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward::type)(a##N) - -// -// implementation -// -inline instance_holder* instance_holder::next() const -{ - return m_next; -} - -}} // namespace boost::python - -#endif // INSTANCE_HOLDER_DWA2002517_HPP diff --git a/include/boost/python/iterator.hpp b/include/boost/python/iterator.hpp deleted file mode 100644 index 3f477034..00000000 --- a/include/boost/python/iterator.hpp +++ /dev/null @@ -1,115 +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 ITERATOR_DWA2002512_HPP -# define ITERATOR_DWA2002512_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // Adds an additional layer of binding to - // objects::make_iterator(...), which allows us to pass member - // function and member data pointers. - template - inline object make_iterator( - Accessor1 get_start, Accessor2 get_finish, boost::type* target = 0, NextPolicies* = 0) - { - return objects::make_iterator_function( - boost::protect(boost::bind(get_start, _1)) - , boost::protect(boost::bind(get_finish, _1)) - ); - } - - // Guts of template class iterators<>, below. - template - struct iterators_impl - { - template - struct apply - { - typedef typename T::iterator iterator; - static iterator begin(T& x) { return x.begin(); } - static iterator end(T& x) { return x.end(); } - }; - }; - - template <> - struct iterators_impl - { - template - struct apply - { - typedef typename T::const_iterator iterator; - static iterator begin(T& x) { return x.begin(); } - static iterator end(T& x) { return x.end(); } - }; - }; -} - -// An "ordinary function generator" which contains static begin(x) and -// end(x) functions that invoke T::begin() and T::end(), respectively. -template -struct iterators - : detail::iterators_impl< - boost::is_const::value - >::template apply -{ -}; - -// Create an iterator-building function which uses the given -// accessors. Deduce the Target type from the accessors. The iterator -// returns copies of the inderlying elements. -template -object range(Accessor1 start, Accessor2 finish) -{ - return detail::make_iterator( - start, finish - , detail::target(start)); -} - -// Create an iterator-building function which uses the given accessors -// and next() policies. Deduce the Target type. -template -object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) -{ - return detail::make_iterator(start, finish, detail::target(start)); -} - -// Create an iterator-building function which uses the given accessors -// and next() policies, operating on the given Target type -template -object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) -{ - typedef typename add_reference::type target; - return detail::make_iterator(start, finish); -} - -// A Python callable object which produces an iterator traversing -// [x.begin(), x.end()), where x is an instance of the Container -// type. NextPolicies are used as the CallPolicies for the iterator's -// next() function. -template -struct iterator : object -{ - iterator() - : object( - python::range( - &iterators::begin, &iterators::end - )) - { - } -}; - -}} // namespace boost::python - -#endif // ITERATOR_DWA2002512_HPP diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp deleted file mode 100644 index ce6cfab4..00000000 --- a/include/boost/python/list.hpp +++ /dev/null @@ -1,140 +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 LIST_DWA2002627_HPP -# define LIST_DWA2002627_HPP - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - struct BOOST_PYTHON_DECL list_base : object - { - void append(object_cref); // append object to end - - long count(object_cref value) const; // return number of occurrences of value - - void extend(object_cref sequence); // extend list by appending sequence elements - - long index(object_cref value) const; // return index of first occurrence of value - - void insert(int index, object_cref); // insert object before index - void insert(object const& index, object_cref); - - object pop(); // remove and return item at index (default last) - object pop(long index); - object pop(object const& index); - - void remove(object_cref value); // remove first occurrence of value - - void reverse(); // reverse *IN PLACE* - - void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 - void sort(object_cref cmpfunc); - - - protected: - list_base(); // new list - explicit list_base(object_cref sequence); // new list initialized from sequence's items - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list_base, object) - private: - static detail::new_non_null_reference call(object const&); - }; -} - -class list : public detail::list_base -{ - typedef detail::list_base base; - public: - list() {} // new list - - template - explicit list(T const& sequence) - : base(object(sequence)) - { - } - - template - void append(T const& x) - { - base::append(object(x)); - } - - template - long count(T const& value) const - { - return base::count(object(value)); - } - - template - void extend(T const& x) - { - base::extend(object(x)); - } - - template - long index(T const& x) const - { - return base::index(object(x)); - } - - template - void insert(int index, T const& x) // insert object before index - { - base::insert(index, object(x)); - } - - template - void insert(object const& index, T const& x) // insert object before index - { - base::insert(index, object(x)); - } - - object pop() { return base::pop(); } - object pop(long index) { return base::pop(index); } - - template - object pop(T const& index) - { - return base::pop(object(index)); - } - - template - void remove(T const& value) - { - base::remove(object(value)); - } - - void sort() { base::sort(); } - - template - void sort(T const& value) - { - base::sort(object(value)); - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyList_Type,list> - { - }; -} - -}} // namespace boost::python - -#endif // LIST_DWA2002627_HPP diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp deleted file mode 100644 index 284296be..00000000 --- a/include/boost/python/long.hpp +++ /dev/null @@ -1,67 +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 LONG_DWA2002627_HPP -# define LONG_DWA2002627_HPP - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - struct BOOST_PYTHON_DECL long_base : object - { - protected: - long_base(); // new long_ - explicit long_base(object_cref rhs); - explicit long_base(object_cref rhs, object_cref base); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_base, object) - - private: - static detail::new_non_null_reference call(object const&); - static detail::new_non_null_reference call(object const&, object const&); - }; -} - -class long_ : public detail::long_base -{ - typedef detail::long_base base; - public: - long_() {} // new long_ - - template - explicit long_(T const& rhs) - : base(object(rhs)) - { - } - - template - explicit long_(T const& rhs, U const& base) - : base(object(rhs), object(base)) - { - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyLong_Type,long_> - { - }; -} - -}} // namespace boost::python - -#endif // LONG_DWA2002627_HPP diff --git a/include/boost/python/lvalue_from_pytype.hpp b/include/boost/python/lvalue_from_pytype.hpp deleted file mode 100755 index ae01a6bd..00000000 --- a/include/boost/python/lvalue_from_pytype.hpp +++ /dev/null @@ -1,104 +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 LVALUE_FROM_PYTYPE_DWA2002130_HPP -# define LVALUE_FROM_PYTYPE_DWA2002130_HPP - -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // Given a pointer-to-function of 1 parameter returning a reference - // type, return the type_id of the function's return type. - template - inline type_info extractor_type_id(T&(*)(U)) - { - return type_id(); - } - - // A function generator whose static execute() function is an lvalue - // from_python converter using the given Extractor. U is expected to - // be the actual type of the PyObject instance from which the result - // is being extracted. - template - struct normalized_extractor - { - static inline void* execute(PyObject* op) - { - typedef typename boost::add_reference::type param; - return &Extractor::execute( - boost::python::detail::void_ptr_to_reference( - op, (param(*)())0 ) - ); - } - }; - - // Given an Extractor type and a pointer to its execute function, - // return a new object whose static execute function does the same - // job but is a conforming lvalue from_python conversion function. - // - // usage: normalize(&Extractor::execute) - template - inline normalized_extractor - normalize(T(*)(U), Extractor* = 0) - { - return normalized_extractor(); - } -} - -// An Extractor which extracts the given member from a Python object -// whose instances are stored as InstanceType. -template -struct extract_member -{ - static MemberType& execute(InstanceType& c) - { - (void)c.ob_type; // static assertion - return c.*member; - } -}; - -// An Extractor which simply extracts the entire python object -// instance of InstanceType. -template -struct extract_identity -{ - static InstanceType& execute(InstanceType& c) - { - (void)c.ob_type; // static assertion - return c; - } -}; - -// Registers a from_python conversion which extracts lvalues using -// Extractor's static execute function from Python objects whose type -// object is python_type. -template -struct lvalue_from_pytype -{ - lvalue_from_pytype() - { - converter::registry::insert( - &extract, detail::extractor_type_id(&Extractor::execute)); - } - private: - static void* extract(PyObject* op) - { - return PyObject_TypeCheck(op, const_cast(python_type)) - ? const_cast( - static_cast( - detail::normalize(&Extractor::execute).execute(op))) - : 0 - ; - } -}; - -}} // namespace boost::python - -#endif // LVALUE_FROM_PYTYPE_DWA2002130_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp deleted file mode 100644 index 9632bbd5..00000000 --- a/include/boost/python/make_function.hpp +++ /dev/null @@ -1,103 +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 - -namespace boost { namespace python { - -namespace detail -{ - // make_function_aux -- - // - // These helper functions for make_function (below) do the raw work - // of constructing a Python object from some invokable entity. See - // for more information about how - // the ConverterGenerators and Sig arguments are used. - template - object make_function_aux( - F f // An object that can be invoked by detail::invoke() - , CallPolicies const& p // CallPolicies to use in the invocation - , ConverterGenerators const& // An MPL iterator over a sequence of arg_from_python generators - , Sig const& // An MPL sequence of argument types expected by F - ) - { - return objects::function_object( - detail::caller(f, p) - , mpl::size::value - 1); - } - - // As above, except that it accepts argument keywords. NumKeywords - // is used only for a compile-time assertion to make sure the user - // doesn't pass more keywords than the function can accept. To - // disable all checking, pass mpl::int_<0> for NumKeywords. - template - object make_function_aux( - F f - , CallPolicies const& p - , ConverterGenerators const& - , Sig const& - , detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names - , NumKeywords // An MPL integral type wrapper: the size of kw - ) - { - enum { arity = mpl::size::value - 1 }; - - typedef typename detail::error::more_keywords_than_function_arguments< - NumKeywords::value, arity - >::too_many_keywords assertion; - - return objects::function_object( - detail::caller(f, p) - , arity - , kw); - } -} - -// make_function -- -// -// These overloaded functions wrap a function or member function -// pointer as a Python object, using optional CallPolicies and -// Keywords. -template -object make_function(F f) -{ - return detail::make_function_aux( - f,default_call_policies(),detail::args_from_python(), detail::get_signature(f)); -} - -template -object make_function(F f, CallPolicies const& policies) -{ - return detail::make_function_aux( - f,policies,detail::args_from_python(), detail::get_signature(f)); -} - -template -object make_function(F f, CallPolicies const& policies, Keywords const& keywords) -{ - return detail::make_function_aux( - f - , policies - , detail::args_from_python() - , detail::get_signature(f) - , keywords.range() - , mpl::int_() - ); -} - -}} - - -#endif // MAKE_FUNCTION_DWA20011221_HPP diff --git a/include/boost/python/manage_new_object.hpp b/include/boost/python/manage_new_object.hpp deleted file mode 100644 index 0acbbec8..00000000 --- a/include/boost/python/manage_new_object.hpp +++ /dev/null @@ -1,40 +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 MANAGE_NEW_OBJECT_DWA200222_HPP -# define MANAGE_NEW_OBJECT_DWA200222_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct manage_new_object_requires_a_pointer_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -struct manage_new_object -{ - template - struct apply - { - typedef typename mpl::if_c< - boost::is_pointer::value - , to_python_indirect - , detail::manage_new_object_requires_a_pointer_return_type - >::type type; - }; -}; - -}} // namespace boost::python - -#endif // MANAGE_NEW_OBJECT_DWA200222_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp deleted file mode 100644 index d259d2da..00000000 --- a/include/boost/python/module.hpp +++ /dev/null @@ -1,12 +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 -# define BOOST_PYTHON_MODULE BOOST_PYTHON_MODULE_INIT - -#endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/module_init.hpp b/include/boost/python/module_init.hpp deleted file mode 100644 index adc259f3..00000000 --- a/include/boost/python/module_init.hpp +++ /dev/null @@ -1,61 +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 MODULE_INIT_DWA20020722_HPP -# define MODULE_INIT_DWA20020722_HPP - -# include -# include - -# ifndef BOOST_PYTHON_MODULE_INIT - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_DECL void init_module(char const* name, void(*)()); - -}}} - -# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE) - -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" __declspec(dllexport) void init##name() \ -{ \ - boost::python::detail::init_module( \ - #name,&init_module_##name); \ -} \ -void init_module_##name() - -# elif defined(_AIX) && !defined(BOOST_PYTHON_STATIC_MODULE) - -# include -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" \ -{ \ - extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ - void init##name() \ - { \ - boost::python::detail::aix_init_module( \ - _PyImport_LoadDynamicModule, #name, &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::detail::init_module(#name, &init_module_##name); \ -} \ -void init_module_##name() - -# endif - -# endif - -#endif // MODULE_INIT_DWA20020722_HPP diff --git a/include/boost/python/numeric.hpp b/include/boost/python/numeric.hpp deleted file mode 100644 index c7563b09..00000000 --- a/include/boost/python/numeric.hpp +++ /dev/null @@ -1,231 +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 NUMARRAY_DWA2002922_HPP -# define NUMARRAY_DWA2002922_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace numeric { - -namespace aux -{ - struct BOOST_PYTHON_DECL array_base : object - { -# define BOOST_PP_LOCAL_MACRO(n) \ - array_base(BOOST_PP_ENUM_PARAMS_Z(1, n, object const& x)); -# define BOOST_PP_LOCAL_LIMITS (1, 7) -# include BOOST_PP_LOCAL_ITERATE() - - object argmax(long axis=-1); - object argmin(long axis=-1); - object argsort(long axis=-1); - object astype(object const& type = object()); - void byteswap(); - object copy() const; - object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const; - void info() const; - bool is_c_array() const; - bool isbyteswapped() const; - object new_(object type) const; - void sort(); - object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const; - object type() const; - char typecode() const; - - object factory(object const& buffer=object() - , object const& type=object() - , object const& shape=object() - , bool copy = true - , bool savespace = false - , object typecode = object()); - - object getflat() const; - long getrank() const; - object getshape() const; - bool isaligned() const; - bool iscontiguous() const; - long itemsize() const; - long nelements() const; - object nonzero() const; - - void put(object const& indices, object const& values); - - void ravel(); - - object repeat(object const& repeats, long axis=0); - - void resize(object const& shape); - - void setflat(object const& flat); - void setshape(object const& shape); - - void swapaxes(long axis1, long axis2); - - object take(object const& sequence, long axis = 0) const; - - void tofile(object const& file) const; - - str tostring() const; - - void transpose(object const& axes = object()); - - object view() const; - - public: // implementation detail - do not touch. - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array_base, object); - }; - - struct BOOST_PYTHON_DECL array_object_manager_traits - { - static bool check(PyObject* obj); - static detail::new_non_null_reference adopt(PyObject* obj); - }; -} // namespace aux - -class array : public aux::array_base -{ - typedef aux::array_base base; - public: - - object astype() { return base::astype(); } - - template - object astype(Type const& type_) - { - return base::astype(object(type_)); - } - - template - object new_(Type const& type_) const - { - return base::new_(object(type_)); - } - - template - void resize(Sequence const& x) - { - base::resize(object(x)); - } - -# define BOOST_PP_LOCAL_MACRO(n) \ - void resize(BOOST_PP_ENUM_PARAMS_Z(1, n, long x)) \ - { \ - resize(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x))); \ - } -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) -# include BOOST_PP_LOCAL_ITERATE() - - template - void setshape(Sequence const& x) - { - base::setshape(object(x)); - } - -# define BOOST_PP_LOCAL_MACRO(n) \ - void setshape(BOOST_PP_ENUM_PARAMS_Z(1, n, long x)) \ - { \ - setshape(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x))); \ - } -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) -# include BOOST_PP_LOCAL_ITERATE() - - template - void put(Indices const& indices, Values const& values) - { - base::put(object(indices), object(values)); - } - - template - object take(Sequence const& sequence, long axis = 0) - { - return base::take(object(sequence), axis); - } - - template - void tofile(File const& f) const - { - base::tofile(object(f)); - } - - object factory() - { - return base::factory(); - } - - template - object factory(Buffer const& buffer) - { - return base::factory(object(buffer)); - } - - template - object factory( - Buffer const& buffer - , Type const& type_) - { - return base::factory(object(buffer), object(type_)); - } - - template - object factory( - Buffer const& buffer - , Type const& type_ - , Shape const& shape - , bool copy = true - , bool savespace = false) - { - return base::factory(object(buffer), object(type_), object(shape), copy, savespace); - } - - template - object factory( - Buffer const& buffer - , Type const& type_ - , Shape const& shape - , bool copy - , bool savespace - , char typecode) - { - return base::factory(object(buffer), object(type_), object(shape), copy, savespace, object(typecode)); - } - -# define BOOST_PYTHON_ENUM_AS_OBJECT(z, n, x) object(BOOST_PP_CAT(x,n)) -# define BOOST_PP_LOCAL_MACRO(n) \ - template \ - explicit array(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, n, T, const& x)) \ - : base(BOOST_PP_ENUM_1(n, BOOST_PYTHON_ENUM_AS_OBJECT, x)) \ - {} -# define BOOST_PP_LOCAL_LIMITS (1, 7) -# include BOOST_PP_LOCAL_ITERATE() -# undef BOOST_PYTHON_AS_OBJECT - - static BOOST_PYTHON_DECL void set_module_and_type(char const* package_name = 0, char const* type_attribute_name = 0); - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array, base); -}; - -} // namespace boost::python::numeric - -namespace converter -{ - template <> - struct object_manager_traits< numeric::array > - : numeric::aux::array_object_manager_traits - { - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - }; -} - -}} // namespace boost::python - -#endif // NUMARRAY_DWA2002922_HPP diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp deleted file mode 100755 index dbdb7c0a..00000000 --- a/include/boost/python/object.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 OBJECT_DWA2002612_HPP -# define OBJECT_DWA2002612_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - - class type_; // XXX temporary work-around - class string; - -}} // namespace boost::python - -#endif // OBJECT_DWA2002612_HPP diff --git a/include/boost/python/object/add_to_namespace.hpp b/include/boost/python/object/add_to_namespace.hpp deleted file mode 100644 index e075bafd..00000000 --- a/include/boost/python/object/add_to_namespace.hpp +++ /dev/null @@ -1,25 +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 ADD_TO_NAMESPACE_DWA200286_HPP -# define ADD_TO_NAMESPACE_DWA200286_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -// -// A setattr that's "smart" about function overloading (and docstrings). -// -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute); - -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc); - -}}} // namespace boost::python::objects - -#endif // ADD_TO_NAMESPACE_DWA200286_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp deleted file mode 100644 index 78cf06b5..00000000 --- a/include/boost/python/object/class.hpp +++ /dev/null @@ -1,61 +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 - -namespace boost { namespace python { - -namespace objects { - -struct BOOST_PYTHON_DECL class_base : python::api::object -{ - // 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 - , type_info const*const types // this is wrapping. The rest are the types of - // any bases. - - , char const* doc = 0 // Docstring, if any. - ); - - - // Implementation detail. Hiding this in the private section would - // require use of template friend declarations. - void enable_pickling(bool getstate_manages_dict); - - protected: - // Retrieve the underlying object - void add_property(char const* name, object const& fget); - void add_property(char const* name, object const& fget, object const& fset); - void setattr(char const* name, object const&); - - // Set a special attribute in the class which tells Boost.Python - // to allocate extra bytes for embedded C++ objects in Python - // instances. - void set_instance_size(std::size_t bytes); - - // Set an __init__ function which throws an appropriate exception - // for abstract classes. - void def_no_init(); - - // Effects: - // setattr(self, staticmethod(getattr(self, method_name))) - void make_method_static(const char *method_name); -}; - -}}} // 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 e902a40f..00000000 --- a/include/boost/python/object/class_converters.hpp +++ /dev/null @@ -1,85 +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 - -# include - -# include - -namespace boost { namespace python { namespace objects { - -////////////////////////////////////////////////////////////////////// -// -// 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 -{ - // Here's the runtime part: - template - void operator()(Base*) const - { - // Register the Base class - register_dynamic_id(); - // Register the up-cast - register_conversion(false); - - // Register the down-cast, if appropriate. - mpl::if_c< - is_polymorphic::value - , register_downcast - , do_nothing - >::type::execute(); - } -}; - -// Brings into existence all converters associated with a class. Bases -// is expected to be an mpl sequence of base types. -template -inline void register_class_from_python(Derived* = 0, Bases* = 0) -{ - python::detail::force_instantiate(converter::shared_ptr_from_python::registration); - - // register all up/downcasts here - register_dynamic_id(); - - // register each base in the sequence - mpl::for_each(register_base_of(), (Bases*)0, (add_pointer*)0); -} - -}}} // namespace boost::python::object - -#endif // CLASS_CONVERTERS_DWA2002119_HPP diff --git a/include/boost/python/object/class_detail.hpp b/include/boost/python/object/class_detail.hpp deleted file mode 100644 index f4d4d51e..00000000 --- a/include/boost/python/object/class_detail.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 CLASS_DETAIL_DWA200295_HPP -# define CLASS_DETAIL_DWA200295_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL type_handle registered_class_object(type_info id); -BOOST_PYTHON_DECL type_handle class_metatype(); -BOOST_PYTHON_DECL type_handle class_type(); - -}}} // namespace boost::python::object - -#endif // CLASS_DETAIL_DWA200295_HPP diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp deleted file mode 100644 index f0fad309..00000000 --- a/include/boost/python/object/class_wrapper.hpp +++ /dev/null @@ -1,43 +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 - -namespace boost { namespace python { namespace objects { - -// -// These two classes adapt the static execute function of a class -// MakeInstance execute() function returning a new PyObject* -// reference. The first one is used for class copy constructors, and -// the second one is used to handle smart pointers. -// - -template -struct class_cref_wrapper - : to_python_converter > -{ - static PyObject* convert(Src const& x) - { - return MakeInstance::execute(boost::ref(x)); - } -}; - -template -struct class_value_wrapper - : to_python_converter > -{ - static PyObject* convert(Src x) - { - return MakeInstance::execute(x); - } -}; - -}}} // namespace boost::python::objects - -#endif // CLASS_WRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/enum_base.hpp b/include/boost/python/object/enum_base.hpp deleted file mode 100644 index 8e4a7301..00000000 --- a/include/boost/python/object/enum_base.hpp +++ /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. -#ifndef ENUM_BASE_DWA200298_HPP -# define ENUM_BASE_DWA200298_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -struct BOOST_PYTHON_DECL enum_base : python::api::object -{ - protected: - enum_base( - char const* name - , converter::to_python_function_t - , converter::convertible_function - , converter::constructor_function - , type_info); - - void add_value(char const* name, long value); - void export_values(); - - static PyObject* to_python(PyTypeObject* type, long x); -}; - -}}} // namespace boost::python::object - -#endif // ENUM_BASE_DWA200298_HPP diff --git a/include/boost/python/object/find_instance.hpp b/include/boost/python/object/find_instance.hpp deleted file mode 100644 index 113b622d..00000000 --- a/include/boost/python/object/find_instance.hpp +++ /dev/null @@ -1,19 +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 FIND_INSTANCE_DWA2002312_HPP -# define FIND_INSTANCE_DWA2002312_HPP - -# include - -namespace boost { namespace python { namespace 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*, type_info); - -}}} // namespace boost::python::objects - -#endif // FIND_INSTANCE_DWA2002312_HPP diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp deleted file mode 100644 index 789dfd23..00000000 --- a/include/boost/python/object/forward.hpp +++ /dev/null @@ -1,112 +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 FORWARD_DWA20011215_HPP -# define FORWARD_DWA20011215_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -// Very much like boost::reference_wrapper, except that in this -// case T can be a reference already without causing a -// reference-to-reference error. -template -struct reference_to_value -{ - typedef typename add_reference::type>::type reference; - - reference_to_value(reference x) : m_value(x) {} - operator reference() const { return m_value; } - private: - reference m_value; -}; - -// A little metaprogram which selects the type to pass through an -// intermediate forwarding function when the destination argument type -// is T. -template -struct forward - : mpl::if_c< - is_scalar::value - , T - , reference_to_value > -{ -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class unforward -{ - public: - typedef typename unwrap_reference::type& type; -}; - -template -class unforward > -{ - public: - typedef T type; -}; -# else // no partial specialization - -namespace detail -{ - typedef char (&yes_reference_to_value_t)[1]; - typedef char (&no_reference_to_value_t)[2]; - - no_reference_to_value_t is_reference_to_value_test(...); - - template - yes_reference_to_value_t is_reference_to_value_test(boost::type< reference_to_value >); - - template - struct unforwarder - { - template - struct apply - { - typedef typename unwrap_reference::type& type; - }; - }; - - template<> - struct unforwarder - { - template - struct apply - { - typedef typename T::reference type; - }; - }; - - template - class is_reference_to_value - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(is_reference_to_value_test(boost::type())) - == sizeof(yes_reference_to_value_t))); - }; -} - -template -class unforward - : public detail::unforwarder< - detail::is_reference_to_value::value - >::template apply -{}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}}} // 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 1a3c3f5f..00000000 --- a/include/boost/python/object/function.hpp +++ /dev/null @@ -1,80 +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 -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -struct BOOST_PYTHON_DECL function : PyObject -{ - function( - py_function const& - , unsigned min_arity - , unsigned max_arity - , python::detail::keyword const* names_and_defaults - , unsigned num_keywords); - - ~function(); - - PyObject* call(PyObject*, PyObject*) const; - - // Add an attribute to 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( - object const& name_space, char const* name, object const& attribute); - - static void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc); - - object const& doc() const; - void doc(object const& x); - - object const& name() const; - - private: // helper functions - void argument_error(PyObject* args, PyObject* keywords) const; - void add_overload(handle const&); - - private: // data members - py_function m_fn; - unsigned m_min_arity; - unsigned m_max_arity; - handle m_overloads; - object m_name; - object m_doc; - object m_arg_names; -}; - -// -// implementations -// -inline object const& function::doc() const -{ - return this->m_doc; -} - -inline void function::doc(object const& x) -{ - this->m_doc = x; -} - -inline object const& function::name() const -{ - return this->m_name; -} - -}}} // namespace boost::python::objects - -#endif // FUNCTION_DWA20011214_HPP diff --git a/include/boost/python/object/function_handle.hpp b/include/boost/python/object/function_handle.hpp deleted file mode 100644 index 29efa2be..00000000 --- a/include/boost/python/object/function_handle.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 FUNCTION_HANDLE_DWA2002725_HPP -# define FUNCTION_HANDLE_DWA2002725_HPP -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL handle<> function_handle_impl(py_function const& f, unsigned min_args, unsigned max_args = 0); - -// Just like function_object, but returns a handle<> instead. Using -// this for arg_to_python<> allows us to break a circular dependency -// between object and arg_to_python. -template -inline handle<> function_handle(F const& f, Signature) -{ - enum { n_arguments = mpl::size::value - 1 }; - - return objects::function_handle_impl( - python::detail::caller< - F,python::detail::args_from_python,default_call_policies,Signature>( - f, default_call_policies()) - , n_arguments, n_arguments); -} - -// Just like make_function, but returns a handle<> intead. Same -// reasoning as above. -template -handle<> make_function_handle(F f) -{ - return objects::function_handle(f, python::detail::get_signature(f)); -} - -}}} // namespace boost::python::objects - -#endif // FUNCTION_HANDLE_DWA2002725_HPP diff --git a/include/boost/python/object/function_object.hpp b/include/boost/python/object/function_object.hpp deleted file mode 100644 index d3661563..00000000 --- a/include/boost/python/object/function_object.hpp +++ /dev/null @@ -1,43 +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 FUNCTION_OBJECT_DWA2002725_HPP -# define FUNCTION_OBJECT_DWA2002725_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace objects -{ - BOOST_PYTHON_DECL api::object function_object( - py_function const& f - , unsigned min_arity, unsigned max_arity - , python::detail::keyword_range const&); - - BOOST_PYTHON_DECL api::object function_object( - py_function const& f - , unsigned arity - , python::detail::keyword_range const&); - - BOOST_PYTHON_DECL api::object function_object(py_function const& f, unsigned arity); - - // Add an attribute to the name_space with the given name. If it is - // a Boost.Python function object - // (boost/python/object/function.hpp), and an existing function is - // already there, add it as an overload. - BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute); - - BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc); -} - -}} // namespace boost::python::objects - -#endif // FUNCTION_OBJECT_DWA2002725_HPP diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp deleted file mode 100644 index 610f458c..00000000 --- a/include/boost/python/object/inheritance.hpp +++ /dev/null @@ -1,154 +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 -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -typedef type_info class_id; -using python::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); - -// -// 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_, python::type_id()); - } -}; - -// Now the generalized selector -template -struct dynamic_id_generator -{ - typedef typename mpl::if_c< - 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( - python::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 -{ - // It's OK to return false, since we can always cast up with - // dynamic_cast<> if neccessary. -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - BOOST_STATIC_CONSTANT(bool, is_upcast = false); -# else - BOOST_STATIC_CONSTANT( - bool, is_upcast = ( - is_base_and_derived::value - )); -# endif - - typedef typename mpl::if_c< - is_upcast -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - // 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(python::type_id() - , python::type_id() - , &generator::execute - , is_downcast); -} - -}}} // namespace boost::python::object - -#endif // INHERITANCE_DWA200216_HPP diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp deleted file mode 100644 index b258a2a0..00000000 --- a/include/boost/python/object/instance.hpp +++ /dev/null @@ -1,51 +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 INSTANCE_DWA200295_HPP -# define INSTANCE_DWA200295_HPP - -# include -# include -# include - -namespace boost { namespace python -{ - struct BOOST_PYTHON_DECL instance_holder; -}} // namespace boost::python - -namespace boost { namespace python { namespace objects { - -// Each extension instance will be one of these -template -struct instance -{ - PyObject_VAR_HEAD - PyObject* dict; - PyObject* weakrefs; - instance_holder* objects; - - BOOST_STATIC_CONSTANT(std::size_t, alignment = alignment_of::value); - typedef typename type_with_alignment::type align_t; - - union - { - align_t align; - char bytes[sizeof(Data)]; - } storage; -}; - -template -struct additional_instance_size -{ - typedef instance instance_data; - typedef instance instance_char; - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(instance_data) - - BOOST_PYTHON_OFFSETOF(instance_char,storage)); -}; - -}}} // namespace boost::python::object - -#endif // INSTANCE_DWA200295_HPP diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp deleted file mode 100644 index c97c3994..00000000 --- a/include/boost/python/object/iterator.hpp +++ /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. -#ifndef ITERATOR_DWA2002510_HPP -# define ITERATOR_DWA2002510_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -// CallPolicies for the next() method of iterators. We don't want -// users to have to explicitly specify that the references returned by -// iterators are copied, so we just replace the result_converter from -// the default_iterator_call_policies with a permissive one which -// always copies the result. -typedef return_value_policy default_iterator_call_policies; - -// Instantiations of these are wrapped to produce Python iterators. -template -struct iterator_range -{ - iterator_range(object sequence, Iterator start, Iterator finish); - - object m_sequence; // Keeps the sequence alive while iterating. - Iterator m_start; - Iterator m_finish; -}; - -namespace detail -{ - // Guts of the iterator's next() function. We can't just wrap an - // ordinary function because we don't neccessarily know the result - // type of dereferencing the iterator. This also saves us from - // throwing C++ exceptions to indicate end-of-sequence. - template - struct iterator_next - { - static PyObject* execute(PyObject* args_, PyObject* kw, Policies const& policies) - { - typedef iterator_range range_; - - PyObject* py_self = PyTuple_GET_ITEM(args_, 0); - arg_from_python c0(py_self); - range_* self = c0(py_self); - - // Done iterating? - if (self->m_start == self->m_finish) - { - objects::set_stop_iteration_error(); - return 0; - } - - // note: precall happens before we can check for the result - // converter in this case, to ensure it happens before the - // iterator is dereferenced. However, the arity is 1 so - // there's not much risk that this will amount to anything. - if (!policies.precall(args_)) return 0; - - PyObject* result = iterator_next::convert_result(*self->m_start); - ++self->m_start; - - return policies.postcall(args_, result); - } - private: - // Convert the result of dereferencing the iterator. Dispatched - // here because we can't neccessarily get the value_type of the - // iterator without PTS. This way, we deduce the value type by - // dereferencing. - template - static PyObject* convert_result(ValueType& x) - { - typedef typename Policies::result_converter result_converter; - typename mpl::apply1::type cr; - - return cr(x); - } - template - static PyObject* convert_result(ValueType const& x) - { - typedef typename Policies::result_converter result_converter; - typename mpl::apply1::type cr; - - return cr(x); - } - }; - - // Get a Python class which contains the given iterator and - // policies, creating it if neccessary. Requires: NextPolicies is - // default-constructible. - template - object demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies()) - { - typedef iterator_range range_; - - // Check the registry. If one is already registered, return it. - handle<> class_obj( - objects::registered_class_object(python::type_id())); - - if (class_obj.get() != 0) - return object(class_obj); - - // Make a callable object which can be used as the iterator's next() function. - object next_function = - objects::function_object( - bind(&detail::iterator_next::execute, _1, _2, policies) - , 1); - - return class_(name, no_init) - .def("__iter__", identity_function()) - .setattr("next", next_function) - ; - } - - // This class template acts as a generator for an ordinary function - // which builds a Python iterator. - template - struct make_iterator_help - { - // Extract an object x of the Target type from the first Python - // argument, and invoke get_start(x)/get_finish(x) to produce - // iterators, which are used to construct a new iterator_range<> - // object that gets wrapped into a Python iterator. - static PyObject* create( - Accessor1 const& get_start, Accessor2 const& get_finish - , PyObject* args_, PyObject* /*kw*/) - { - // Make sure the Python class is instantiated. - detail::demand_iterator_class("iterator", (Iterator*)0, NextPolicies()); - - to_python_value > cr; - - // Extract x from the first argument - PyObject* arg0 = PyTuple_GET_ITEM(args_, 0); - arg_from_python c0(arg0); - if (!c0.convertible()) return 0; - typename arg_from_python::result_type x = c0(arg0); - - // Build and convert the iterator_range<>. - return cr( - iterator_range( - object((python::detail::borrowed_reference)arg0) - , get_start(x), get_finish(x))); - } - }; - - template - inline object make_iterator_function( - Accessor1 const& get_start, Accessor2 const& get_finish, Iterator const& (*)(), boost::type*, NextPolicies*, int) - { - return - objects::function_object( - boost::bind( - &make_iterator_help< - Target,Iterator,Accessor1,Accessor2,NextPolicies - >::create - , get_start, get_finish, _1, _2) - , 1 ); - } - - template - inline object make_iterator_function( - Accessor1 const& get_start, Accessor2 const& get_finish, Iterator& (*)(), boost::type*, NextPolicies*, ...) - { - return make_iterator_function( - get_start, get_finish, (Iterator const&(*)())0 - , (boost::type*)0, (NextPolicies*)0, 0); - } - -} - -// Create a Python callable object which accepts a single argument -// convertible to the C++ Target type and returns a Python -// iterator. The Python iterator uses get_start(x) and get_finish(x) -// (where x is an instance of Target) to produce begin and end -// iterators for the range, and an instance of NextPolicies is used as -// CallPolicies for the Python iterator's next() function. -template -inline object make_iterator_function( - Accessor1 const& get_start, Accessor2 const& get_finish - , boost::type* = 0, NextPolicies* = 0) -{ - typedef typename Accessor1::result_type iterator; - typedef typename add_const::type iterator_const; - typedef typename add_reference::type iterator_cref; - - return detail::make_iterator_function( - get_start, get_finish - , (iterator_cref(*)())0 - , (boost::type*)0 - , (NextPolicies*)0 - , 0 - ); -} - -// -// implementation -// -template -inline iterator_range::iterator_range( - object sequence, Iterator start, Iterator finish) - : m_sequence(sequence), m_start(start), m_finish(finish) -{ -} - -}}} // namespace boost::python::objects - -#endif // ITERATOR_DWA2002510_HPP diff --git a/include/boost/python/object/iterator_core.hpp b/include/boost/python/object/iterator_core.hpp deleted file mode 100644 index 655fc71e..00000000 --- a/include/boost/python/object/iterator_core.hpp +++ /dev/null @@ -1,19 +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 ITERATOR_CORE_DWA2002512_HPP -# define ITERATOR_CORE_DWA2002512_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL object const& identity_function(); -BOOST_PYTHON_DECL void set_stop_iteration_error(); - -}}} // namespace boost::python::object - -#endif // ITERATOR_CORE_DWA2002512_HPP diff --git a/include/boost/python/object/life_support.hpp b/include/boost/python/object/life_support.hpp deleted file mode 100644 index 5d9587db..00000000 --- a/include/boost/python/object/life_support.hpp +++ /dev/null @@ -1,17 +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 LIFE_SUPPORT_DWA200222_HPP -# define LIFE_SUPPORT_DWA200222_HPP -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient); - -}}} // namespace boost::python::object - -#endif // LIFE_SUPPORT_DWA200222_HPP diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp deleted file mode 100644 index a2c013c4..00000000 --- a/include/boost/python/object/make_holder.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// 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 -# include -# include - -# include -# include -# include -# include -# include - -# include - -namespace boost { namespace python { namespace objects { - -template struct make_holder; - -# define BOOST_PYTHON_DO_FORWARD_ARG(z, index, _) , f##index(a##index) - -// specializations... -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_DO_FORWARD_ARG - -}}} // namespace boost::python::objects - -# endif // MAKE_HOLDER_DWA20011215_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -# line BOOST_PP_LINE(__LINE__, make_holder.hpp) - -# define N BOOST_PP_ITERATION() - -template <> -struct make_holder -{ - template - struct apply - { -# if N - // Unrolled iteration through each argument type in ArgList, - // choosing the type that will be forwarded on to the holder's - // templated constructor. - typedef typename mpl::begin::type iter0; - -# define BOOST_PP_LOCAL_MACRO(n) \ - typedef typename mpl::apply0::type t##n; \ - typedef typename forward::type f##n; \ - typedef typename mpl::next::type \ - BOOST_PP_CAT(iter,BOOST_PP_INC(n)); // Next iterator type - -# define BOOST_PP_LOCAL_LIMITS (0, N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - - static void execute( - PyObject* p - BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a)) - { - typedef instance instance_t; - - void* memory = Holder::allocate(p, offsetof(instance_t, storage), sizeof(Holder)); - try { - (new (memory) Holder( - p BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p); - } - catch(...) { - Holder::deallocate(p, memory); - throw; - } - } - }; -}; - -# undef N - -#endif diff --git a/include/boost/python/object/make_instance.hpp b/include/boost/python/object/make_instance.hpp deleted file mode 100644 index eb420d2f..00000000 --- a/include/boost/python/object/make_instance.hpp +++ /dev/null @@ -1,71 +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 MAKE_INSTANCE_DWA200296_HPP -# define MAKE_INSTANCE_DWA200296_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct make_instance_impl -{ - typedef objects::instance instance_t; - - template - static inline PyObject* execute(Arg& x) - { - BOOST_STATIC_ASSERT(is_class::value); - - PyTypeObject* type = Derived::get_class_object(x); - - PyObject* raw_result = type->tp_alloc( - type, objects::additional_instance_size::value); - - if (raw_result != 0) - { - python::detail::decref_guard protect(raw_result); - - instance_t* instance = (instance_t*)raw_result; - - // construct the new C++ object and install the pointer - // in the Python object. - Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result); - - // Note the position of the internally-stored Holder, - // for the sake of destruction - instance->ob_size = offsetof(instance_t, storage); - - // Release ownership of the python object - protect.cancel(); - } - return raw_result; - } -}; - - -template -struct make_instance - : make_instance_impl > -{ - template - static inline PyTypeObject* get_class_object(U&) - { - return converter::registered::converters.get_class_object(); - } - - static inline Holder* construct(void* storage, PyObject* instance, reference_wrapper x) - { - return new (storage) Holder(instance, x); - } -}; - - -}}} // namespace boost::python::object - -#endif // MAKE_INSTANCE_DWA200296_HPP diff --git a/include/boost/python/object/make_ptr_instance.hpp b/include/boost/python/object/make_ptr_instance.hpp deleted file mode 100644 index 25dbd77c..00000000 --- a/include/boost/python/object/make_ptr_instance.hpp +++ /dev/null @@ -1,66 +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 MAKE_PTR_INSTANCE_DWA200296_HPP -# define MAKE_PTR_INSTANCE_DWA200296_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct make_ptr_instance - : make_instance_impl > -{ - template - static inline Holder* construct(void* storage, PyObject*, Arg& x) - { - return new (storage) Holder(x); - } - - template - static inline PyTypeObject* get_class_object(Ptr const& x) - { - return get_class_object_impl(get_pointer(x)); - } - - private: - template - static inline PyTypeObject* get_class_object_impl(U const volatile* p) - { - PyTypeObject* derived = get_derived_class_object(is_polymorphic::type(), p); - if (derived) - return derived; - return converter::registered::converters.get_class_object(); - } - - template - static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x) - { - converter::registration const* r = converter::registry::query(type_info(typeid(*x))); - return r ? r->m_class_object : 0; - } - - template - static inline PyTypeObject* get_derived_class_object(mpl::false_, U* x) - { -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - if (typeid(*x) != typeid(U)) - return get_derived_class_object(mpl::true_(), x); -# else - (void)x; -# endif - return 0; - } -}; - - -}}} // namespace boost::python::object - -#endif // MAKE_PTR_INSTANCE_DWA200296_HPP diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp deleted file mode 100644 index e8033196..00000000 --- a/include/boost/python/object/pickle_support.hpp +++ /dev/null @@ -1,125 +0,0 @@ -// (C) Copyright R.W. Grosse-Kunstleve 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 BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP -# define BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP - -# include - -namespace boost { namespace python { - -namespace api -{ - class object; -} -using api::object; -class tuple; - -BOOST_PYTHON_DECL object const& make_instance_reduce_function(); - -struct pickle_suite; - -namespace error_messages { - - template - struct missing_pickle_suite_function_or_incorrect_signature {}; - - inline void must_be_derived_from_pickle_suite(pickle_suite const&) {} -} - -namespace detail { struct pickle_suite_registration; } - -struct pickle_suite -{ - private: - struct inaccessible {}; - friend struct detail::pickle_suite_registration; - public: - static inaccessible* getinitargs() { return 0; } - static inaccessible* getstate() { return 0; } - static inaccessible* setstate() { return 0; } - static bool getstate_manages_dict() { return false; } -}; - -namespace detail { - - struct pickle_suite_registration - { - typedef pickle_suite::inaccessible inaccessible; - - template - static - void - register_( - Class_& cl, - tuple (*getinitargs_fn)(Tgetinitargs), - inaccessible* (*getstate_fn)(), - inaccessible* (*setstate_fn)(), - bool) - { - cl.enable_pickling(false); - cl.def("__getinitargs__", getinitargs_fn); - } - - template - static - void - register_( - Class_& cl, - inaccessible* (*getinitargs_fn)(), - Rgetstate (*getstate_fn)(Tgetstate), - void (*setstate_fn)(Tsetstate, Ttuple), - bool getstate_manages_dict) - { - cl.enable_pickling(getstate_manages_dict); - cl.def("__getstate__", getstate_fn); - cl.def("__setstate__", setstate_fn); - } - - template - static - void - register_( - Class_& cl, - tuple (*getinitargs_fn)(Tgetinitargs), - Rgetstate (*getstate_fn)(Tgetstate), - void (*setstate_fn)(Tsetstate, Ttuple), - bool getstate_manages_dict) - { - cl.enable_pickling(getstate_manages_dict); - cl.def("__getinitargs__", getinitargs_fn); - cl.def("__getstate__", getstate_fn); - cl.def("__setstate__", setstate_fn); - } - - template - static - void - register_( - Class_&, - ...) - { - typedef typename - error_messages::missing_pickle_suite_function_or_incorrect_signature< - Class_>::error_type error_type; - } - }; - - template - struct pickle_suite_finalize - : PickleSuiteType, - pickle_suite_registration - {}; - -} // namespace detail - -}} // namespace boost::python - -#endif // BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp deleted file mode 100644 index 4400abe6..00000000 --- a/include/boost/python/object/pointer_holder.hpp +++ /dev/null @@ -1,176 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// 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 -# include -# include - -# include -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -bool is_null(T const& p, ...) -{ - return p.get() == 0; -} - -template -bool is_null(T* p, int) -{ - return p == 0; -} - -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) - -template -struct pointer_holder : instance_holder -{ - typedef Value value_type; - - pointer_holder(Pointer); - - // Forward construction to the held object - -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) -# include BOOST_PP_ITERATE() - - private: // types - - private: // required holder implementation - void* holds(type_info); - - private: // data members - Pointer m_p; -}; - -template -struct pointer_holder_back_reference : instance_holder -{ - private: - typedef typename python::pointee::type held_type; - public: - typedef Value value_type; - - // Not sure about this one -- can it work? The source object - // undoubtedly does not carry the correct back reference pointer. - pointer_holder_back_reference(Pointer); - - // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) -# include BOOST_PP_ITERATE() - - private: // required holder implementation - void* holds(type_info); - - private: // data members - Pointer m_p; -}; - -# undef BOOST_PYTHON_UNFORWARD_LOCAL - -template -inline pointer_holder::pointer_holder(Pointer p) - : m_p(p) -{ -} - -template -inline pointer_holder_back_reference::pointer_holder_back_reference(Pointer p) - : m_p(p) -{ -} - -template -void* pointer_holder::holds(type_info dst_t) -{ - if (dst_t == python::type_id()) - return &this->m_p; - - if (objects::is_null(this->m_p, 0)) - return 0; - - type_info src_t = python::type_id(); - Value* p = &*this->m_p; - return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); -} - -template -void* pointer_holder_back_reference::holds(type_info dst_t) -{ - if (dst_t == python::type_id()) - return &this->m_p; - - if (objects::is_null(this->m_p, 0)) - return 0; - - if (dst_t == python::type_id()) - return &*this->m_p; - - type_info src_t = python::type_id(); - Value* p = &*this->m_p; - return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); -} - -}}} // namespace boost::python::objects - -# endif // POINTER_HOLDER_DWA20011215_HPP - -/* --------------- pointer_holder --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 -# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template< BOOST_PP_ENUM_PARAMS_Z(1, N, class A) > -# endif - pointer_holder(PyObject* BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_p(new Value( - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - )) - {} - -# undef N - -/* --------------- pointer_holder_back_reference --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 -# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp(pointer_holder_back_reference)) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template < BOOST_PP_ENUM_PARAMS_Z(1, N, class A) > -# endif - pointer_holder_back_reference( - PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_p(new held_type( - p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - )) - {} - -# undef N - -#endif diff --git a/include/boost/python/object/py_function.hpp b/include/boost/python/object/py_function.hpp deleted file mode 100644 index 0682d692..00000000 --- a/include/boost/python/object/py_function.hpp +++ /dev/null @@ -1,22 +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 PY_FUNCTION_DWA200286_HPP -# define PY_FUNCTION_DWA200286_HPP -# include - -namespace boost { namespace python { namespace objects { - -// This type is used as a "generalized Python callback", wrapping the -// function signature: -// -// PyObject* (PyObject* args, PyObject* keywords) -// -// We use boost::function to avoid generating lots of virtual tables -typedef boost::function2 py_function; - -}}} // namespace boost::python::objects - -#endif // PY_FUNCTION_DWA200286_HPP diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp deleted file mode 100644 index 87bc06da..00000000 --- a/include/boost/python/object/select_holder.hpp +++ /dev/null @@ -1,236 +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 SELECT_HOLDER_DWA2002322_HPP -# define SELECT_HOLDER_DWA2002322_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include - -# include -# include -# include - -# include -# include -# include - -# include - -namespace boost { namespace python { namespace objects { - -namespace detail -{ - - // check_default_constructible -- - // - // Used to give a clean error message when the user doesn't specify - // any __init__ functions, but when the class being wrapped doesn't - // have an appropriate default constructor (or if - // has_back_reference is true, a constructor taking PyObject*). - - // A helpful compile-time assertion which gives a reasonable error - // message if T can't be default-constructed. - template - static int specify_init_arguments_or_no_init_for_class_(T const&); - - // U is expected to take an initial hidden PyObject* in its - // constructor. Normally this means U is a virtual function - // dispatcher subclass for T. - template - void check_default_constructible(T*, U*, mpl::bool_) - { - python::detail::force_instantiate( - sizeof(specify_init_arguments_or_no_init_for_class_(U((::PyObject*)0))) - ); - } - - // Handles the "normal" case where T is held directly and - // has_back_reference is not specialized. - template - void check_default_constructible(T*, T*, mpl::bool_) - { - python::detail::force_instantiate( - sizeof(specify_init_arguments_or_no_init_for_class_(T())) - ); - } - - // - // select_value_holder/select_pointer_holder -- - // - // An instantiation of one of these data-free class templates is - // returned by select_holder::execute(), below. Each provides the - // following public interface: - // - // static void assert_default_constructible() -- called when no - // init<...> arguments are specified in class_'s - // constructor; causes a compile-time error when T has no - // corresponding default constructor. - // - // typedef ... type -- the class derived from instance_holder - // which will manage a Held object in Python class instances - // - // static type* get() { return 0; } -- just a way to access the - // computed type at runtime. - // - // static void register_() -- forces registration of any - // to_python converters corresponding to Held. - - template - struct select_value_holder - { - BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same::value) | has_back_reference::value); - - static void assert_default_constructible() - { - detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_()); - } - - typedef typename mpl::if_c< - back_ref - , value_holder_back_reference - , value_holder - >::type type; - - static inline void register_() {} - - static type* get() { return 0; } - }; - - template - struct select_pointer_holder - { - typedef typename python::pointee::type pointee; - BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same::value) | has_back_reference::value); - - static void assert_default_constructible() - { - detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_()); - } - - typedef typename mpl::if_c< - back_ref - , pointer_holder_back_reference - , pointer_holder - >::type type; - - static inline void register_() - { - select_pointer_holder::register_(mpl::bool_()); - } - - static type* get() { return 0; } - - private: - static inline void register_(mpl::true_) - { - } - - struct construct_from_pointer - { - static type* execute(PyObject*, Ptr x) - { - return new type(x); - } - }; - - static inline void register_(mpl::false_) - { - python::detail::force_instantiate( - objects::class_value_wrapper >()); - } - }; -} - -// select_holder::execute((Held*)0) -// -// implements a compile-time returns an instantiation of -// detail::select_value_holder or detail::select_pointer_holder, as -// appropriate for class_ -template -struct select_holder -{ - // Return the additional size to allocate in Python class - // instances to hold the C++ instance data. - static inline std::size_t additional_size() - { - return additional_size_helper( -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - execute((Held*)0) -# else - type() -# endif - ); - } - - # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - // These overloads are an elaborate workaround for deficient - // compilers: - // - // They are meant to be called with a null pointer to the class_'s - // Held template argument. The selected overload will create an - // appropriate instantiation of select_value_holder or - // select_pointer_holder, which is itself an empty class that is - // ultimately used to create the class_'s instance_holder subclass - // object. - - // No Held was specified; T is held directly by-value - static inline detail::select_value_holder - execute(python::detail::not_specified*) - { - return detail::select_value_holder(); - } - - // A type derived from T was specified; it is assumed to be a - // virtual function dispatcher class, and T is held as Held. - static inline detail::select_value_holder - execute(T*) - { - return detail::select_value_holder(); - } - - // Some other type was specified; Held is assumed to be a (smart) - // pointer to T or a class derived from T. - static inline detail::select_pointer_holder - execute(void*) - { - return detail::select_pointer_holder(); - } -# else - typedef typename mpl::if_< - is_same - , detail::select_value_holder - , typename mpl::if_< - mpl::or_< - is_same - , is_base_and_derived - > - , detail::select_value_holder - , detail::select_pointer_holder - >::type - >::type type; -# endif - - private: - template - static inline std::size_t additional_size_helper(Selector const&) - { - typedef typename Selector::type holder; - return additional_instance_size::value; - } -}; - -}}} // namespace boost::python::objects - -#endif // SELECT_HOLDER_DWA2002322_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp deleted file mode 100644 index 6ae3ae75..00000000 --- a/include/boost/python/object/value_holder.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// 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 - -# include -# include - -# include -# include -# include -# include -# include - -# include -# include - -namespace boost { namespace python { namespace objects { - -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) - -template -struct value_holder : instance_holder -{ - typedef Held value_type; - - // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) -# include BOOST_PP_ITERATE() - - private: // required holder implementation - void* holds(type_info); - - private: // data members - Held m_held; -}; - -template -struct value_holder_back_reference : instance_holder -{ - typedef Held value_type; - - // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) -# include BOOST_PP_ITERATE() - -private: // required holder implementation - void* holds(type_info); - - private: // data members - BackReferenceType m_held; -}; - -# undef BOOST_PYTHON_UNFORWARD_LOCAL - -template -void* value_holder::holds(type_info dst_t) -{ - type_info src_t = python::type_id(); - return src_t == dst_t ? &m_held - : find_static_type(&m_held, src_t, dst_t); -} - -template -void* value_holder_back_reference::holds( - type_info dst_t) -{ - type_info src_t = python::type_id(); - Held* x = &m_held; - - if (dst_t == src_t) - return x; - else if (dst_t == python::type_id()) - return &m_held; - else - return find_static_type(x, src_t, dst_t); -} - -}}} // namespace boost::python::objects - -# endif // VALUE_HOLDER_DWA20011215_HPP - -// --------------- value_holder --------------- - -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 -# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder)) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template -# endif - value_holder( - PyObject* BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_held( - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - ) - {} - -# undef N - -// --------------- value_holder_back_reference --------------- - -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 -# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder_back_reference)) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template -# endif - value_holder_back_reference( - PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_held( - p BOOST_PP_COMMA_IF(N) - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - ) - { - } - -# undef N - -#endif diff --git a/include/boost/python/object/value_holder_fwd.hpp b/include/boost/python/object/value_holder_fwd.hpp deleted file mode 100644 index 6cb2a0f5..00000000 --- a/include/boost/python/object/value_holder_fwd.hpp +++ /dev/null @@ -1,17 +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_HOLDER_FWD_DWA2002311_HPP -# define VALUE_HOLDER_FWD_DWA2002311_HPP - -namespace boost { namespace python { namespace objects { - -struct no_back_reference; - -template struct value_holder_generator; - -}}} // namespace boost::python::object - -#endif // VALUE_HOLDER_FWD_DWA2002311_HPP diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp deleted file mode 100755 index 4d3c2a7d..00000000 --- a/include/boost/python/object_attributes.hpp +++ /dev/null @@ -1,67 +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 OBJECT_ATTRIBUTES_DWA2002615_HPP -# define OBJECT_ATTRIBUTES_DWA2002615_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace api { - -struct const_attribute_policies -{ - typedef char const* key_type; - static object get(object const& target, char const* key); -}; - -struct attribute_policies : const_attribute_policies -{ - static object const& set(object const& target, char const* key, object const& value); - static void del(object const&target, char const* key); -}; - -// -// implementation -// -template -inline object_attribute object_operators::attr(char const* name) -{ - object_cref2 x = *static_cast(this); - return object_attribute(x, name); -} - -template -inline const_object_attribute object_operators::attr(char const* name) const -{ - object_cref2 x = *static_cast(this); - return const_object_attribute(x, name); -} - -inline object const_attribute_policies::get(object const& target, char const* key) -{ - return python::getattr(target, key); -} - -inline object const& attribute_policies::set( - object const& target - , char const* key - , object const& value) -{ - python::setattr(target, key, value); - return value; -} - -inline void attribute_policies::del( - object const& target - , char const* key) -{ - python::delattr(target, key); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_ATTRIBUTES_DWA2002615_HPP diff --git a/include/boost/python/object_call.hpp b/include/boost/python/object_call.hpp deleted file mode 100644 index dd0c0dc0..00000000 --- a/include/boost/python/object_call.hpp +++ /dev/null @@ -1,24 +0,0 @@ -# if !defined(BOOST_PYTHON_SYNOPSIS) -# // 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. - -# if !defined(BOOST_PP_IS_ITERATING) -# error Boost.Python - do not include this file! -# endif - -# define N BOOST_PP_ITERATION() - - template - typename detail::dependent::type - operator()(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)) const - { - typedef typename detail::dependent::type obj; - U const& self = *static_cast(this); - return call(get_managed_object(self, tag), BOOST_PP_ENUM_PARAMS_Z(1, N, a)); - } - -# undef N -# endif // BOOST_PYTHON_SYNOPSIS diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp deleted file mode 100755 index 4727edba..00000000 --- a/include/boost/python/object_core.hpp +++ /dev/null @@ -1,386 +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 OBJECT_CORE_DWA2002615_HPP -# define OBJECT_CORE_DWA2002615_HPP - -# include - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include -# include - -namespace boost { namespace python { - -namespace converter -{ - template struct arg_to_python; -} - -// Put this in an inner namespace so that the generalized operators won't take over -namespace api -{ - -// This file contains the definition of the object class and enough to -// construct/copy it, but not enough to do operations like -// attribute/item access or addition. - - template class proxy; - - struct const_attribute_policies; - struct attribute_policies; - struct const_item_policies; - struct item_policies; - struct const_slice_policies; - struct slice_policies; - - typedef proxy const_object_attribute; - typedef proxy object_attribute; - typedef proxy const_object_item; - typedef proxy object_item; - typedef proxy const_object_slice; - typedef proxy object_slice; - - // - // is_proxy -- proxy type detection - // -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct is_proxy - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; - template - struct is_proxy > - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; -# else - typedef char yes_proxy; - typedef char (&no_proxy)[2]; - template - yes_proxy is_proxy_helper(boost::type >*); - no_proxy is_proxy_helper(...); - template - struct is_proxy - { - BOOST_STATIC_CONSTANT( - bool, value = (sizeof(is_proxy_helper((boost::type*)0)) - == sizeof(yes_proxy))); - }; -# endif - - template struct object_initializer; - - class object; - typedef PyObject* (object::*bool_type)() const; - - template - class object_operators - { - protected: -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef object const& object_cref; -# else - typedef object object_cref; -# endif - public: - // function call - // - object operator()() const; - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - - // truth value testing - // - operator bool_type() const; - bool operator!() const; // needed for vc6 - - // Attribute access - // - const_object_attribute attr(char const*) const; - object_attribute attr(char const*); - - // item access - // - const_object_item operator[](object_cref) const; - object_item operator[](object_cref); - - template - const_object_item - operator[](T const& key) const -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return (*this)[object(key)]; - } -# endif - - template - object_item - operator[](T const& key) -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return (*this)[object(key)]; - } -# endif - - // slicing - // - const_object_slice slice(object_cref, object_cref) const; - object_slice slice(object_cref, object_cref); - - const_object_slice slice(slice_nil, object_cref) const; - object_slice slice(slice_nil, object_cref); - - const_object_slice slice(object_cref, slice_nil) const; - object_slice slice(object_cref, slice_nil); - - template - const_object_slice - slice(T const& start, V const& end) const -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return this->slice( - slice_bound::type(start) - , slice_bound::type(end)); - } -# endif - - template - object_slice - slice(T const& start, V const& end) -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return this->slice( - slice_bound::type(start) - , slice_bound::type(end)); - } -# endif - private: - // there is a confirmed CWPro8 codegen bug here. We prevent the - // early destruction of a temporary by binding a named object - // instead. -# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3003 - typedef object const& object_cref2; -# else - typedef object const object_cref2; -# endif - }; - - // VC6 and VC7 require this base class in order to generate the - // correct copy constructor for object. We can't define it there - // explicitly or it will complain of ambiguity. - struct object_base : object_operators - { - // copy constructor without NULL checking, for efficiency. - inline object_base(object_base const&); - inline object_base(PyObject* ptr); - - object_base& operator=(object_base const& rhs); - ~object_base(); - - // Underlying object access -- returns a borrowed reference - PyObject* ptr() const; - - private: - PyObject* m_ptr; - }; - - class object : public object_base - { - public: - // default constructor creates a None object - object(); - // explicit conversion from any C++ object to Python - template - explicit object(T const& x) - : object_base( - object_initializer< - is_proxy::value - , converter::is_object_manager::value - >::get(&x, detail::convertible::check(&x))) - { - } - - // Throw error_already_set() if the handle is null. - BOOST_PYTHON_DECL explicit object(handle<> const&); - - public: // implementation detail -- for internal use only - explicit object(detail::borrowed_reference); - explicit object(detail::new_reference); - explicit object(detail::new_non_null_reference); - }; - - // Macros for forwarding constructors in classes derived from - // object. Derived classes will usually want these as an - // implementation detail -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \ - inline explicit derived(python::detail::borrowed_reference p) \ - : base(p) {} \ - inline explicit derived(python::detail::new_reference p) \ - : base(p) {} \ - inline explicit derived(python::detail::new_non_null_reference p) \ - : base(p) {} - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_ -# else - // MSVC6 has a bug which causes an explicit template constructor to - // be preferred over an appropriate implicit conversion operator - // declared on the argument type. Normally, that would cause a - // runtime failure when using extract to extract a type with a - // templated constructor. This additional constructor will turn that - // runtime failure into an ambiguity error at compile-time due to - // the lack of partial ordering, or at least a link-time error if no - // generalized template constructor is declared. -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \ - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \ - template \ - explicit derived(extract const&); -# endif - - // - // object_initializer -- get the handle to construct the object with, - // based on whether T is a proxy or derived from object - // - template - struct object_initializer - { - static PyObject* - get(object const* x, detail::yes_convertible) - { - return python::incref(x->ptr()); - } - - template - static PyObject* - get(T const* x, detail::no_convertible) - { - return python::incref(converter::arg_to_python(*x).get()); - } - }; - - template <> - struct object_initializer - { - template - static PyObject* - get(proxy const* x, detail::no_convertible) - { - return python::incref(x->operator object().ptr()); - } - }; - - template <> - struct object_initializer - { - template - static PyObject* - get(T const* x, ...) - { - return python::incref(get_managed_object(*x, tag)); - } - }; - - template <> - struct object_initializer - {}; // empty implementation should cause an error -} -using api::object; -template struct extract; - -// -// implementation -// - -inline object::object() - : object_base(python::incref(Py_None)) -{} - -// copy constructor without NULL checking, for efficiency -inline api::object_base::object_base(object_base const& rhs) - : m_ptr(python::incref(rhs.m_ptr)) -{} - -inline api::object_base::object_base(PyObject* p) - : m_ptr(p) -{} - -inline api::object_base& api::object_base::operator=(api::object_base const& rhs) -{ - Py_INCREF(rhs.m_ptr); - Py_DECREF(this->m_ptr); - this->m_ptr = rhs.m_ptr; - return *this; -} - -inline api::object_base::~object_base() -{ - Py_DECREF(m_ptr); -} - -inline object::object(detail::borrowed_reference p) - : object_base(python::incref((PyObject*)p)) -{} - -inline object::object(detail::new_reference p) - : object_base(expect_non_null((PyObject*)p)) -{} - -inline object::object(detail::new_non_null_reference p) - : object_base((PyObject*)p) -{} - -inline PyObject* api::object_base::ptr() const -{ - return m_ptr; -} - -// -// Converter specialization implementations -// -namespace converter -{ - template struct object_manager_traits; - - template <> - struct object_manager_traits - { - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - static bool check(PyObject*) { return true; } - - static python::detail::new_non_null_reference adopt(PyObject* x) - { - return python::detail::new_non_null_reference(x); - } - }; -} - -inline PyObject* get_managed_object(object const& x, tag_t) -{ - return x.ptr(); -} - -}} // namespace boost::python - -#endif // OBJECT_CORE_DWA2002615_HPP diff --git a/include/boost/python/object_fwd.hpp b/include/boost/python/object_fwd.hpp deleted file mode 100644 index 8b0c093e..00000000 --- a/include/boost/python/object_fwd.hpp +++ /dev/null @@ -1,17 +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 OBJECT_FWD_DWA2002724_HPP -# define OBJECT_FWD_DWA2002724_HPP - -namespace boost { namespace python { -namespace api -{ - class object; -} -using api::object; -}} // namespace boost::python - -#endif // OBJECT_FWD_DWA2002724_HPP diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp deleted file mode 100755 index 436a671f..00000000 --- a/include/boost/python/object_items.hpp +++ /dev/null @@ -1,88 +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 OBJECT_ITEMS_DWA2002615_HPP -# define OBJECT_ITEMS_DWA2002615_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace api { - -struct const_item_policies -{ - typedef object key_type; - static object get(object const& target, object const& key); -}; - -struct item_policies : const_item_policies -{ - static object const& set(object const& target, object const& key, object const& value); - static void del(object const& target, object const& key); -}; - -// -// implementation -// -template -inline object_item -object_operators::operator[](object_cref key) -{ - object_cref2 x = *static_cast(this); - return object_item(x, key); -} - -template -inline const_object_item -object_operators::operator[](object_cref key) const -{ - object_cref2 x = *static_cast(this); - return const_object_item(x, key); -} - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 -template -template -inline const_object_item -object_operators::operator[](T const& key) const -{ - return (*this)[object(key)]; -} - -template -template -inline object_item -object_operators::operator[](T const& key) -{ - return (*this)[object(key)]; -} -# endif - - -inline object const_item_policies::get(object const& target, object const& key) -{ - return getitem(target, key); -} - -inline object const& item_policies::set( - object const& target - , object const& key - , object const& value) -{ - setitem(target, key, value); - return value; -} - -inline void item_policies::del( - object const& target - , object const& key) -{ - delitem(target, key); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_ITEMS_DWA2002615_HPP diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp deleted file mode 100644 index fb14d484..00000000 --- a/include/boost/python/object_operators.hpp +++ /dev/null @@ -1,94 +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 OBJECT_OPERATORS_DWA2002617_HPP -# define OBJECT_OPERATORS_DWA2002617_HPP - -# include -# include - -namespace boost { namespace python { namespace api { - -template -object object_operators::operator()() const -{ - object_cref2 f = *static_cast(this); - return call(f.ptr()); -} - - -template -inline -object_operators::operator bool_type() const -{ - object_cref2 x = *static_cast(this); - return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0; -} - -template -inline bool -object_operators::operator!() const -{ - object_cref2 x = *static_cast(this); - return !PyObject_IsTrue(x.ptr()); -} - -# define BOOST_PYTHON_COMPARE_OP(op, opid) \ -template \ -bool operator op(L const& l, R const& r) \ -{ \ - return PyObject_RichCompareBool( \ - object(l).ptr(), object(r).ptr(), opid); \ -} -BOOST_PYTHON_COMPARE_OP(>, Py_GT) -BOOST_PYTHON_COMPARE_OP(>=, Py_GE) -BOOST_PYTHON_COMPARE_OP(<, Py_LT) -BOOST_PYTHON_COMPARE_OP(<=, Py_LE) -BOOST_PYTHON_COMPARE_OP(==, Py_EQ) -BOOST_PYTHON_COMPARE_OP(!=, Py_NE) -# undef BOOST_PYTHON_COMPARE_OP - -# define BOOST_PYTHON_BINARY_OPERATOR(op) \ -BOOST_PYTHON_DECL object operator op(object const& l, object const& r); \ -template \ -object operator op(L const& l, R const& r) \ -{ \ - return object(l) op object(r); \ -} -BOOST_PYTHON_BINARY_OPERATOR(+) -BOOST_PYTHON_BINARY_OPERATOR(-) -BOOST_PYTHON_BINARY_OPERATOR(*) -BOOST_PYTHON_BINARY_OPERATOR(/) -BOOST_PYTHON_BINARY_OPERATOR(%) -BOOST_PYTHON_BINARY_OPERATOR(<<) -BOOST_PYTHON_BINARY_OPERATOR(>>) -BOOST_PYTHON_BINARY_OPERATOR(&) -BOOST_PYTHON_BINARY_OPERATOR(^) -BOOST_PYTHON_BINARY_OPERATOR(|) -# undef BOOST_PYTHON_BINARY_OPERATOR - - -# define BOOST_PYTHON_INPLACE_OPERATOR(op) \ -BOOST_PYTHON_DECL object& operator op(object& l, object const& r); \ -template \ -object& operator op(object& l, R const& r) \ -{ \ - return l op object(r); \ -} -BOOST_PYTHON_INPLACE_OPERATOR(+=) -BOOST_PYTHON_INPLACE_OPERATOR(-=) -BOOST_PYTHON_INPLACE_OPERATOR(*=) -BOOST_PYTHON_INPLACE_OPERATOR(/=) -BOOST_PYTHON_INPLACE_OPERATOR(%=) -BOOST_PYTHON_INPLACE_OPERATOR(<<=) -BOOST_PYTHON_INPLACE_OPERATOR(>>=) -BOOST_PYTHON_INPLACE_OPERATOR(&=) -BOOST_PYTHON_INPLACE_OPERATOR(^=) -BOOST_PYTHON_INPLACE_OPERATOR(|=) -# undef BOOST_PYTHON_INPLACE_OPERATOR - -}}} // namespace boost::python - -#endif // OBJECT_OPERATORS_DWA2002617_HPP diff --git a/include/boost/python/object_protocol.hpp b/include/boost/python/object_protocol.hpp deleted file mode 100755 index 8698dd9f..00000000 --- a/include/boost/python/object_protocol.hpp +++ /dev/null @@ -1,80 +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 OBJECT_PROTOCOL_DWA2002615_HPP -# define OBJECT_PROTOCOL_DWA2002615_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace api { - -template -object getattr(Target const& target, Key const& key) -{ - return getattr(object(target), object(key)); -} - -template -object getattr(Target const& target, Key const& key, Default const& default_) -{ - return getattr(object(target), object(key), object(default_)); -} - - -template -void setattr(object const& target, Key const& key, Value const& value) -{ - setattr(target, object(key), object(value)); -} - -template -void delattr(object const& target, Key const& key) -{ - delattr(target, object(key)); -} - -template -object getitem(Target const& target, Key const& key) -{ - return getitem(object(target), object(key)); -} - - -template -void setitem(object const& target, Key const& key, Value const& value) -{ - return setitem(target, object(key), object(value)); -} - -template -void delitem(object const& target, Key const& key) -{ - delitem(target, object(key)); -} - -template -object getslice(Target const& target, Begin const& begin, End const& end) -{ - return getslice(object(target), object(begin), object(end)); -} - -template -void setslice(object const& target, Begin const& begin, End const& end, Value const& value) -{ - setslice(target, object(begin), object(end), object(value)); -} - -template -void delslice(object const& target, Begin const& begin, End const& end) -{ - delslice(target, object(begin), object(end)); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_PROTOCOL_DWA2002615_HPP diff --git a/include/boost/python/object_protocol_core.hpp b/include/boost/python/object_protocol_core.hpp deleted file mode 100755 index 50d2f454..00000000 --- a/include/boost/python/object_protocol_core.hpp +++ /dev/null @@ -1,53 +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 OBJECT_PROTOCOL_CORE_DWA2002615_HPP -# define OBJECT_PROTOCOL_CORE_DWA2002615_HPP - -# include -# include - -namespace boost { namespace python { - -namespace api -{ - class object; - - BOOST_PYTHON_DECL object getattr(object const& target, object const& key); - BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_); - BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value); - BOOST_PYTHON_DECL void delattr(object const& target, object const& key); - - // These are defined for efficiency, since attributes are commonly - // accessed through literal strings. - BOOST_PYTHON_DECL object getattr(object const& target, char const* key); - BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_); - BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value); - BOOST_PYTHON_DECL void delattr(object const& target, char const* key); - - BOOST_PYTHON_DECL object getitem(object const& target, object const& key); - BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value); - BOOST_PYTHON_DECL void delitem(object const& target, object const& key); - - BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end); - BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value); - BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end); -} - -using api::getattr; -using api::setattr; -using api::delattr; - -using api::getitem; -using api::setitem; -using api::delitem; - -using api::getslice; -using api::setslice; -using api::delslice; - -}} // namespace boost::python - -#endif // OBJECT_PROTOCOL_CORE_DWA2002615_HPP diff --git a/include/boost/python/object_slices.hpp b/include/boost/python/object_slices.hpp deleted file mode 100644 index eb8dcb0b..00000000 --- a/include/boost/python/object_slices.hpp +++ /dev/null @@ -1,125 +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 OBJECT_SLICES_DWA2002615_HPP -# define OBJECT_SLICES_DWA2002615_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace api { - -struct const_slice_policies -{ - typedef std::pair, handle<> > key_type; - static object get(object const& target, key_type const& key); -}; - -struct slice_policies : const_slice_policies -{ - static object const& set(object const& target, key_type const& key, object const& value); - static void del(object const& target, key_type const& key); -}; - -// -// implementation -// -template -object_slice -object_operators::slice(object_cref start, object_cref finish) -{ - object_cref2 x = *static_cast(this); - return object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr()))); -} - -template -const_object_slice -object_operators::slice(object_cref start, object_cref finish) const -{ - object_cref2 x = *static_cast(this); - return const_object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr()))); -} - -template -object_slice -object_operators::slice(slice_nil, object_cref finish) -{ - object_cref2 x = *static_cast(this); - return object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr()))); -} - -template -const_object_slice -object_operators::slice(slice_nil, object_cref finish) const -{ - object_cref2 x = *static_cast(this); - return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr()))); -} - -template -object_slice -object_operators::slice(object_cref start, slice_nil) -{ - object_cref2 x = *static_cast(this); - return object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0))); -} - -template -const_object_slice -object_operators::slice(object_cref start, slice_nil) const -{ - object_cref2 x = *static_cast(this); - return const_object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0))); -} -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 -template -template -inline const_object_slice -object_operators::slice(T const& start, V const& end) const -{ - return this->slice( - typename slice_bound::type(start) - , typename slice_bound::type(end)); -} - -template -template -inline object_slice -object_operators::slice(T const& start, V const& end) -{ - return this->slice( - typename slice_bound::type(start) - , typename slice_bound::type(end)); -} -# endif - - -inline object const_slice_policies::get(object const& target, key_type const& key) -{ - return getslice(target, key.first, key.second); -} - -inline object const& slice_policies::set( - object const& target - , key_type const& key - , object const& value) -{ - setslice(target, key.first, key.second, value); - return value; -} - -inline void slice_policies::del( - object const& target - , key_type const& key) -{ - delslice(target, key.first, key.second); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_SLICES_DWA2002615_HPP diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp deleted file mode 100644 index 3292efa7..00000000 --- a/include/boost/python/operators.hpp +++ /dev/null @@ -1,332 +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 OPERATORS_DWA2002530_HPP -# define OPERATORS_DWA2002530_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // This is essentially the old v1 to_python(). It will be eliminated - // once the public interface for to_python is settled on. - template - PyObject* convert_result(T const& x) - { - return converter::arg_to_python(x).release(); - } - - // Operator implementation template declarations. The nested apply - // declaration here keeps MSVC6 happy. - template struct operator_l - { - template struct apply; - }; - - template struct operator_r - { - template struct apply; - }; - - template struct operator_1 - { - template struct apply; - }; - - // MSVC6 doesn't want us to do this sort of inheritance on a nested - // class template, so we use this layer of indirection to avoid - // ::template<...> on the nested apply functions below - template - struct operator_l_inner - : operator_l::template apply - {}; - - template - struct operator_r_inner - : operator_r::template apply - {}; - - template - struct operator_1_inner - : operator_1::template apply - {}; - - // Define three different binary_op templates which take care of - // these cases: - // self op self - // self op R - // L op self - // - // The inner apply metafunction is used to adjust the operator to - // the class type being defined. Inheritance of the outer class is - // simply used to provide convenient access to the operation's - // name(). - - // self op self - template - struct binary_op : operator_l - { - template - struct apply : operator_l_inner - { - }; - }; - - // self op R - template - struct binary_op_l : operator_l - { - template - struct apply : operator_l_inner - { - }; - }; - - // L op self - template - struct binary_op_r : operator_r - { - template - struct apply : operator_r_inner - { - }; - }; - - template - struct unary_op : operator_1 - { - template - struct apply : operator_1_inner - { - }; - }; - - // This type is what actually gets returned from operators used on - // self_t - template - struct operator_ - : mpl::if_< - is_same - , typename mpl::if_< - is_same - , binary_op - , binary_op_l::type> - >::type - , typename mpl::if_< - is_same - , unary_op - , binary_op_r::type> - >::type - >::type - { - }; -} - -# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \ -namespace detail \ -{ \ - template <> \ - struct operator_l \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* execute(L const& l, R const& r) \ - { \ - return detail::convert_result(expr); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ - \ - template <> \ - struct operator_r \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* execute(R const& r, L const& l) \ - { \ - return detail::convert_result(expr); \ - } \ - }; \ - static char const* name() { return "__" #rid "__"; } \ - }; \ -} - -# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ -BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ -namespace self_ns \ -{ \ - template \ - inline detail::operator_ \ - operator op(L const&, R const&) \ - { \ - return detail::operator_(); \ - } \ -} - -BOOST_PYTHON_BINARY_OPERATOR(add, radd, +) -BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -) -BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *) -BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /) -BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %) -BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<) -BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>) -BOOST_PYTHON_BINARY_OPERATOR(and, rand, &) -BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^) -BOOST_PYTHON_BINARY_OPERATOR(or, ror, |) -BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >) -BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=) -BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <) -BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) -BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) -BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) -# undef BOOST_PYTHON_BINARY_OPERATOR - -// pow isn't an operator in C++; handle it specially. -BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r)) -# undef BOOST_PYTHON_BINARY_OPERATION - -namespace self_ns -{ -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP - template - inline detail::operator_ - pow(L const&, R const&) - { - return detail::operator_(); - } -# else - // When there's no argument-dependent lookup, we need these - // overloads to handle the case when everything is imported into the - // global namespace. Note that the plain overload below does /not/ - // take const& arguments. This is needed by MSVC6 at least, or it - // complains of ambiguities, since there's no partial ordering. - inline detail::operator_ - pow(self_t, self_t) - { - return detail::operator_(); - } - template - inline detail::operator_ - pow(self_t const&, R const&) - { - return detail::operator_(); - } - template - inline detail::operator_ - pow(L const&, self_t const&) - { - return detail::operator_(); - } -# endif -} - - -# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \ -namespace detail \ -{ \ - template <> \ - struct operator_l \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* \ - execute(back_reference l, R const& r) \ - { \ - l.get() op r; \ - return python::incref(l.source().ptr()); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ -} \ -namespace self_ns \ -{ \ - template \ - inline detail::operator_ \ - operator op(self_t const&, R const&) \ - { \ - return detail::operator_(); \ - } \ -} - -BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=) -BOOST_PYTHON_INPLACE_OPERATOR(isub,-=) -BOOST_PYTHON_INPLACE_OPERATOR(imul,*=) -BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=) -BOOST_PYTHON_INPLACE_OPERATOR(imod,%=) -BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=) -BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=) -BOOST_PYTHON_INPLACE_OPERATOR(iand,&=) -BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=) -BOOST_PYTHON_INPLACE_OPERATOR(ior,|=) - -# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \ -namespace detail \ -{ \ - template <> \ - struct operator_1 \ - { \ - template \ - struct apply \ - { \ - static PyObject* execute(T const& x) \ - { \ - return detail::convert_result(op(x)); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ -} \ -namespace self_ns \ -{ \ - inline detail::operator_ \ - func_name(self_t const&) \ - { \ - return detail::operator_(); \ - } \ -} -# undef BOOST_PYTHON_INPLACE_OPERATOR - -BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-) -BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+) -BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs) -BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~) -BOOST_PYTHON_UNARY_OPERATOR(int, long, int_) -BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) -BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) -BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_) -BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str) -# undef BOOST_PYTHON_UNARY_OPERATOR - -}} // namespace boost::python - -# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -using boost::python::self_ns::abs; -using boost::python::self_ns::int_; -using boost::python::self_ns::long_; -using boost::python::self_ns::float_; -using boost::python::self_ns::complex_; -using boost::python::self_ns::str; -using boost::python::self_ns::pow; -# endif - -#endif // OPERATORS_DWA2002530_HPP diff --git a/include/boost/python/other.hpp b/include/boost/python/other.hpp deleted file mode 100755 index 0142da34..00000000 --- a/include/boost/python/other.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef OTHER_DWA20020601_HPP -# define OTHER_DWA20020601_HPP -// 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. - -# if _MSC_VER+0 >= 1020 -# pragma once -# endif - -# include - -namespace boost { namespace python { - -template struct other -{ - typedef T type; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace detail -{ - template - class is_other - { - public: - BOOST_STATIC_CONSTANT(bool, value = false); - }; - - template - class is_other > - { - public: - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template - class unwrap_other - { - public: - typedef T type; - }; - - template - class unwrap_other > - { - public: - typedef T type; - }; -} -# else // no partial specialization - -}} // namespace boost::python - -#include - -namespace boost { namespace python { - -namespace detail -{ - typedef char (&yes_other_t)[1]; - typedef char (&no_other_t)[2]; - - no_other_t is_other_test(...); - - template - yes_other_t is_other_test(type< other >); - - template - struct other_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct other_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; - - template - class is_other - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_other_test(type())) - == sizeof(detail::yes_other_t))); - }; - - template - class unwrap_other - : public detail::other_unwrapper< - is_other::value - >::template apply - {}; -} - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}} // namespace boost::python - -#endif // #ifndef OTHER_DWA20020601_HPP diff --git a/include/boost/python/overloads.hpp b/include/boost/python/overloads.hpp deleted file mode 100644 index 50fc2497..00000000 --- a/include/boost/python/overloads.hpp +++ /dev/null @@ -1,12 +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 OVERLOADS_DWA2002101_HPP -# define OVERLOADS_DWA2002101_HPP - -# include -# include - -#endif // OVERLOADS_DWA2002101_HPP diff --git a/include/boost/python/pointee.hpp b/include/boost/python/pointee.hpp deleted file mode 100644 index d62bab54..00000000 --- a/include/boost/python/pointee.hpp +++ /dev/null @@ -1,40 +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 POINTEE_DWA2002323_HPP -# define POINTEE_DWA2002323_HPP - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct pointee_impl - { - template struct apply : remove_pointer {}; - }; - - template <> - struct pointee_impl - { - template struct apply - { - typedef typename T::element_type type; - }; - }; -} - -template -struct pointee - : detail::pointee_impl::value>::template apply -{ -}; - -}} // namespace boost::python::detail - -#endif // POINTEE_DWA2002323_HPP diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp deleted file mode 100755 index 1818fa27..00000000 --- a/include/boost/python/proxy.hpp +++ /dev/null @@ -1,101 +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 PROXY_DWA2002615_HPP -# define PROXY_DWA2002615_HPP -# include -# include - -namespace boost { namespace python { namespace api { - -template -class proxy : public object_operators > -{ - typedef typename Policies::key_type key_type; - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef proxy const& assignment_self; -# else - typedef proxy assignment_self; -# endif - public: - proxy(object const& target, key_type const& key); - operator object() const; - - // to support a[b] = c[d] - proxy const& operator=(assignment_self) const; - - template - inline proxy const& operator=(T const& rhs) const - { - Policies::set(m_target, m_key, object(rhs)); - return *this; - } - - public: // implementation detail - void del() const; - - private: - object m_target; - key_type m_key; -}; - - -template -inline void del(proxy const& x) -{ - x.del(); -} - -// -// implementation -// - -template -inline proxy::proxy(object const& target, key_type const& key) - : m_target(target), m_key(key) -{} - -template -inline proxy::operator object() const -{ - return Policies::get(m_target, m_key); -} - -// to support a[b] = c[d] -template -inline proxy const& proxy::operator=(typename proxy::assignment_self rhs) const -{ - return *this = python::object(rhs); -} - -# define BOOST_PYTHON_PROXY_INPLACE(op) \ -template \ -proxy const& operator op(proxy const& lhs, R const& rhs) \ -{ \ - object old(lhs); \ - return lhs = (old op rhs); \ -} -BOOST_PYTHON_PROXY_INPLACE(+=) -BOOST_PYTHON_PROXY_INPLACE(-=) -BOOST_PYTHON_PROXY_INPLACE(*=) -BOOST_PYTHON_PROXY_INPLACE(/=) -BOOST_PYTHON_PROXY_INPLACE(%=) -BOOST_PYTHON_PROXY_INPLACE(<<=) -BOOST_PYTHON_PROXY_INPLACE(>>=) -BOOST_PYTHON_PROXY_INPLACE(&=) -BOOST_PYTHON_PROXY_INPLACE(^=) -BOOST_PYTHON_PROXY_INPLACE(|=) -# undef BOOST_PYTHON_PROXY_INPLACE - -template -inline void proxy::del() const -{ - Policies::del(m_target, m_key); -} - -}}} // namespace boost::python::api - -#endif // PROXY_DWA2002615_HPP diff --git a/include/boost/python/ptr.hpp b/include/boost/python/ptr.hpp deleted file mode 100644 index dd37f58b..00000000 --- a/include/boost/python/ptr.hpp +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef PTR_DWA20020601_HPP -# define PTR_DWA20020601_HPP -// 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. -// -// Based on boost/ref.hpp, thus: -// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) -// Copyright (C) 2001 Peter Dimov - -# if _MSC_VER+0 >= 1020 -# pragma once -# endif - -# include -# include - -namespace boost { namespace python { - -template class pointer_wrapper -{ - public: - typedef Ptr type; - - explicit pointer_wrapper(Ptr x): p_(x) {} - operator Ptr() const { return p_; } - Ptr get() const { return p_; } - private: - Ptr p_; -}; - -template -inline pointer_wrapper ptr(T t) -{ - return pointer_wrapper(t); -} - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class is_pointer_wrapper - : public mpl::false_ -{ -}; - -template -class is_pointer_wrapper > - : public mpl::true_ -{ -}; - -template -class unwrap_pointer -{ - public: - typedef T type; -}; - -template -class unwrap_pointer > -{ - public: - typedef T type; -}; -# else // no partial specialization - -}} // namespace boost::python - -#include - -namespace boost { namespace python { - -namespace detail -{ - typedef char (&yes_pointer_wrapper_t)[1]; - typedef char (&no_pointer_wrapper_t)[2]; - - no_pointer_wrapper_t is_pointer_wrapper_test(...); - - template - yes_pointer_wrapper_t is_pointer_wrapper_test(boost::type< pointer_wrapper >); - - template - struct pointer_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct pointer_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; -} - -template -class is_pointer_wrapper -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_pointer_wrapper_test(boost::type())) - == sizeof(detail::yes_pointer_wrapper_t))); - typedef mpl::bool_ type; -}; - -template -class unwrap_pointer - : public detail::pointer_unwrapper< - is_pointer_wrapper::value - >::template apply -{}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}} // namespace boost::python - -#endif // #ifndef PTR_DWA20020601_HPP diff --git a/include/boost/python/raw_function.hpp b/include/boost/python/raw_function.hpp deleted file mode 100755 index 3a28d127..00000000 --- a/include/boost/python/raw_function.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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 RAW_FUNCTION_DWA200336_HPP -# define RAW_FUNCTION_DWA200336_HPP - -# include -# include -# include - -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct raw_dispatcher - { - raw_dispatcher(F f) : f(f) {} - - PyObject* operator()(PyObject* args, PyObject* keywords) - { - return incref( - object( - f(tuple(borrowed_reference(args)), dict(borrowed_reference(keywords))) - ).ptr() - ); - } - private: - F f; - }; - - object BOOST_PYTHON_DECL make_raw_function(objects::py_function, std::size_t min_args); -} - -template -object raw_function(F f, std::size_t min_args = 0) -{ - return detail::make_raw_function(detail::raw_dispatcher(f), min_args); -} - -}} // namespace boost::python - -#endif // RAW_FUNCTION_DWA200336_HPP diff --git a/include/boost/python/refcount.hpp b/include/boost/python/refcount.hpp deleted file mode 100755 index dce6b266..00000000 --- a/include/boost/python/refcount.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 REFCOUNT_DWA2002615_HPP -# define REFCOUNT_DWA2002615_HPP - -# include -# include - -namespace boost { namespace python { - -template -inline T* incref(T* p) -{ - Py_INCREF(python::upcast(p)); - return p; -} - -template -inline T* xincref(T* p) -{ - Py_XINCREF(python::upcast(p)); - return p; -} - -template -inline void decref(T* p) -{ - Py_DECREF(python::upcast(p)); -} - -template -inline void xdecref(T* p) -{ - Py_XDECREF(python::upcast(p)); -} - -}} // namespace boost::python - -#endif // REFCOUNT_DWA2002615_HPP diff --git a/include/boost/python/reference_existing_object.hpp b/include/boost/python/reference_existing_object.hpp deleted file mode 100644 index e16dcf18..00000000 --- a/include/boost/python/reference_existing_object.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 REFERENCE_EXISTING_OBJECT_DWA200222_HPP -# define REFERENCE_EXISTING_OBJECT_DWA200222_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct reference_existing_object_requires_a_pointer_or_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template struct to_python_value; - -struct reference_existing_object -{ - template - struct apply - { - BOOST_STATIC_CONSTANT( - bool, ok = is_pointer::value || is_reference::value); - - typedef typename mpl::if_c< - ok - , to_python_indirect - , detail::reference_existing_object_requires_a_pointer_or_reference_return_type - >::type type; - }; -}; - -}} // namespace boost::python - -#endif // REFERENCE_EXISTING_OBJECT_DWA200222_HPP diff --git a/include/boost/python/return_by_value.hpp b/include/boost/python/return_by_value.hpp deleted file mode 100644 index 97f9f245..00000000 --- a/include/boost/python/return_by_value.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BY_VALUE_DWA20021015_HPP -# define BY_VALUE_DWA20021015_HPP - -# include -# include -# include - -namespace boost { namespace python { - -struct return_by_value -{ - template - struct apply - { - typedef to_python_value< - typename add_reference< - typename add_const::type - >::type - > type; - }; -}; - -}} // namespace boost::python - -#endif // BY_VALUE_DWA20021015_HPP diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp deleted file mode 100644 index 7e350d77..00000000 --- a/include/boost/python/return_internal_reference.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 RETURN_INTERNAL_REFERENCE_DWA2002131_HPP -# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct return_internal_reference_owner_arg_must_be_greater_than_zero -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template -struct return_internal_reference - : with_custodian_and_ward_postcall<0, owner_arg, BasePolicy_> -{ - private: - BOOST_STATIC_CONSTANT(bool, legal = owner_arg > 0); - public: - typedef typename mpl::if_c< - legal - , reference_existing_object - , detail::return_internal_reference_owner_arg_must_be_greater_than_zero - >::type 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 0f3c00fe..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 : BasePolicy_ -{ - typedef ResultConverterGenerator result_converter; -}; - -}} // namespace boost::python - -#endif // RETURN_VALUE_POLICY_DWA2002131_HPP diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp deleted file mode 100644 index 2e208bfc..00000000 --- a/include/boost/python/scope.hpp +++ /dev/null @@ -1,76 +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 SCOPE_DWA2002724_HPP -# define SCOPE_DWA2002724_HPP - -# include -# include -# include - -namespace boost { namespace python { - -class BOOST_PYTHON_DECL scope - : public object -{ - public: - inline scope(scope const&); - inline scope(object const&); - inline scope(); - inline ~scope(); - - private: // data members - PyObject* m_previous_scope; - - private: // unimplemented functions - void operator=(scope const&); - - private: // static members - - // Use a PyObject* to avoid problems with static destruction after Py_Finalize - static PyObject* current_scope; -}; - -inline scope::scope(object const& new_scope) - : object(new_scope) - , m_previous_scope(current_scope) -{ - current_scope = python::incref(new_scope.ptr()); -} - -inline scope::scope() - : object(detail::borrowed_reference( - current_scope ? current_scope : Py_None - )) - , m_previous_scope(python::xincref(current_scope)) -{ -} - -inline scope::~scope() -{ - python::xdecref(current_scope); - current_scope = m_previous_scope; -} - -namespace converter -{ - template <> - struct object_manager_traits - : object_manager_traits - { - }; -} - -// Placing this after the specialization above suppresses a CWPro8.3 bug -inline scope::scope(scope const& new_scope) - : object(new_scope) - , m_previous_scope(current_scope) -{ - current_scope = python::incref(new_scope.ptr()); -} - -}} // namespace boost::python - -#endif // SCOPE_DWA2002724_HPP diff --git a/include/boost/python/self.hpp b/include/boost/python/self.hpp deleted file mode 100755 index c7d3f670..00000000 --- a/include/boost/python/self.hpp +++ /dev/null @@ -1,36 +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 SELF_DWA2002531_HPP -# define SELF_DWA2002531_HPP - -# include - -namespace boost { namespace python { - -//# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 -# define BOOST_PYTHON_SELF_IS_CLASS -//# endif - -// Sink self_t into its own namespace so that we have a safe place to -// put the completely general operator templates which operate on -// it. It is possible to avoid this, but it turns out to be much more -// complicated and finally GCC 2.95.2 chokes on it. -namespace self_ns -{ -# ifndef BOOST_PYTHON_SELF_IS_CLASS - enum self_t { self }; -# else - struct self_t {}; - extern BOOST_PYTHON_DECL self_t self; -# endif -} - -using self_ns::self_t; -using self_ns::self; - -}} // namespace boost::python - -#endif // SELF_DWA2002531_HPP diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp deleted file mode 100644 index 5b0f6026..00000000 --- a/include/boost/python/signature.hpp +++ /dev/null @@ -1,119 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 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. -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(BOOST_PP_IS_ITERATING) - -# ifndef SIGNATURE_JDG20020813_HPP -# define SIGNATURE_JDG20020813_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -# include -# include -# include -# include - -# define BOOST_PYTHON_LIST_INC(n) \ - BOOST_PP_CAT(mpl::list, BOOST_PP_INC(n)) - -/////////////////////////////////////////////////////////////////////////////// -namespace boost { namespace python { namespace detail { - -/////////////////////////////////////////////////////////////////////////////// -// -// The following macros generate expansions for: -// -// template -// inline mpl::list -// get_signature(RT(*)(T0...TN)) -// { -// return mpl::list(); -// } -// -// And, for an appropriate assortment of cv-qualifications -// -// template -// inline mpl::list -// get_signature(RT(ClassT::*)(T0...TN) cv)) -// { -// return mpl::list(); -// } -// -// These functions extract the return type, class (for member -// functions) and arguments of the input signature and stuffs them in -// an mpl::list. Note that cv-qualification is dropped from the -// target class; that is a necessary sacrifice to ensure that an -// lvalue from_python converter is used. -// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) - -# include BOOST_PP_ITERATE() - -} - -}} // namespace boost::python - - -# undef BOOST_PYTHON_LIST_INC - -/////////////////////////////////////////////////////////////////////////////// -# endif // SIGNATURE_JDG20020813_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING) - -# define N BOOST_PP_ITERATION() - -template < - class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> -inline BOOST_PYTHON_LIST_INC(N)< - RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T))) -{ - return BOOST_PYTHON_LIST_INC(N)< - RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) - >(); -} - -# undef N - -# define BOOST_PP_ITERATION_PARAMS_2 \ - (3, (0, 3, )) -# include BOOST_PP_ITERATE() - -#else - -# define N BOOST_PP_RELATIVE_ITERATION(1) -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_ITERATION()) - -template < - class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> -inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< - RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) -{ - return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< - RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) - >(); -} - -# undef Q -# undef N - -#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/slice_nil.hpp b/include/boost/python/slice_nil.hpp deleted file mode 100644 index cb169116..00000000 --- a/include/boost/python/slice_nil.hpp +++ /dev/null @@ -1,41 +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 SLICE_NIL_DWA2002620_HPP -# define SLICE_NIL_DWA2002620_HPP - -namespace boost { namespace python { namespace api { - -class object; - -enum slice_nil -{ -# ifndef _ // Watch out for GNU gettext users, who #define _(x) - _ -# endif -}; - -template -struct slice_bound -{ - typedef object type; -}; - -template <> -struct slice_bound -{ - typedef slice_nil type; -}; - -} - -using api::slice_nil; -# ifndef _ // Watch out for GNU gettext users, who #define _(x) -using api::_; -# endif - -}} // namespace boost::python - -#endif // SLICE_NIL_DWA2002620_HPP diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp deleted file mode 100644 index 2ebae5e7..00000000 --- a/include/boost/python/str.hpp +++ /dev/null @@ -1,400 +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 STR_20020703_HPP -#define STR_20020703_HPP - -#include -#include -#include - -// disable defines in provided by some system libraries -#undef isspace -#undef islower -#undef isalpha -#undef isdigit -#undef isalnum -#undef isupper - -namespace boost { namespace python { - -class str; - -namespace detail -{ - struct BOOST_PYTHON_DECL str_base : object - { - str capitalize() const; - - str center(object_cref width) const; - - long count(object_cref sub) const; - - long count(object_cref sub, object_cref start) const; - - long count(object_cref sub, object_cref start, object_cref end) const; - - object decode() const; - object decode(object_cref encoding) const; - - object decode(object_cref encoding, object_cref errors) const; - - object encode() const; - object encode(object_cref encoding) const; - object encode(object_cref encoding, object_cref errors) const; - - bool endswith(object_cref suffix) const; - - bool endswith(object_cref suffix, object_cref start) const; - bool endswith(object_cref suffix, object_cref start, object_cref end) const; - - str expandtabs() const; - str expandtabs(object_cref tabsize) const; - - long find(object_cref sub) const; - long find(object_cref sub, object_cref start) const; - - long find(object_cref sub, object_cref start, object_cref end) const; - - long index(object_cref sub) const; - - long index(object_cref sub, object_cref start) const; - long index(object_cref sub, object_cref start, object_cref end) const; - - bool isalnum() const; - bool isalpha() const; - bool isdigit() const; - bool islower() const; - bool isspace() const; - bool istitle() const; - bool isupper() const; - - str join(object_cref sequence) const; - - str ljust(object_cref width) const; - str lower() const; - str lstrip() const; - - str replace(object_cref old, object_cref new_) const; - str replace(object_cref old, object_cref new_, object_cref maxsplit) const; - long rfind(object_cref sub) const; - - long rfind(object_cref sub, object_cref start) const; - - long rfind(object_cref sub, object_cref start, object_cref end) const; - long rindex(object_cref sub) const; - long rindex(object_cref sub, object_cref start) const; - - - long rindex(object_cref sub, object_cref start, object_cref end) const; - - str rjust(object_cref width) const; - - str rstrip() const; - - list split() const; - list split(object_cref sep) const; - - list split(object_cref sep, object_cref maxsplit) const; - - - list splitlines() const; - list splitlines(object_cref keepends) const; - - bool startswith(object_cref prefix) const; - - - bool startswith(object_cref prefix, object_cref start) const; - bool startswith(object_cref prefix, object_cref start, object_cref end) const; - - str strip() const; - str swapcase() const; - str title() const; - - str translate(object_cref table) const; - - str translate(object_cref table, object_cref deletechars) const; - - - str upper() const; - - protected: - str_base(); // new str - - str_base(const char* s); // new str - explicit str_base(object_cref other); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str_base, object) - private: - static new_reference call(object const&); - }; -} - - -class str : public detail::str_base -{ - typedef detail::str_base base; - public: - str() {} // new str - - str(const char* s) : base(s) {} // new str - - template - explicit str(T const& other) - : base(object(other)) - { - } - - template - str center(T const& width) const - { - return base::center(object(width)); - } - - template - long count(T const& sub) const - { - return base::count(object(sub)); - } - - template - long count(T1 const& sub,T2 const& start) const - { - return base::count(object(sub), object(start)); - } - - template - long count(T1 const& sub,T2 const& start, T3 const& end) const - { - return base::count(object(sub), object(start)); - } - - object decode() const { return base::decode(); } - - template - object decode(T const& encoding) const - { - return base::decode(object(encoding)); - } - - template - object decode(T1 const& encoding, T2 const& errors) const - { - return base::decode(object(encoding),object(errors)); - } - - object encode() const { return base::encode(); } - - template - object encode(T const& encoding) const - { - return base::encode(object(encoding)); - } - - template - object encode(T1 const& encoding, T2 const& errors) const - { - return base::encode(object(encoding),object(errors)); - } - - template - bool endswith(T const& suffix) const - { - return base::endswith(object(suffix)); - } - - template - bool endswith(T1 const& suffix, T2 const& start) const - { - return base::endswith(object(suffix), object(start)); - } - - template - bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const - { - return base::endswith(object(suffix), object(start), object(end)); - } - - str expandtabs() const { return base::expandtabs(); } - - template - str expandtabs(T const& tabsize) const - { - return base::expandtabs(object(tabsize)); - } - - template - long find(T const& sub) const - { - return base::find(object(sub)); - } - - template - long find(T1 const& sub, T2 const& start) const - { - return base::find(object(sub), object(start)); - } - - template - long find(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::find(object(sub), object(start), object(end)); - } - - template - long index(T const& sub) const - { - return base::index(object(sub)); - } - - template - long index(T1 const& sub, T2 const& start) const - { - return base::index(object(sub), object(start)); - } - - template - long index(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::index(object(sub), object(start), object(end)); - } - - template - str join(T const& sequence) const - { - return base::join(object(sequence)); - } - - template - str ljust(T const& width) const - { - return base::ljust(object(width)); - } - - template - str replace(T1 const& old, T2 const& new_) const - { - return base::replace(object(old),object(new_)); - } - - template - str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const - { - return base::replace(object(old),object(new_), object(maxsplit)); - } - - template - long rfind(T const& sub) const - { - return base::rfind(object(sub)); - } - - template - long rfind(T1 const& sub, T2 const& start) const - { - return base::rfind(object(sub), object(start)); - } - - template - long rfind(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::rfind(object(sub), object(start), object(end)); - } - - template - long rindex(T const& sub) const - { - return base::rindex(object(sub)); - } - - template - long rindex(T1 const& sub, T2 const& start) const - { - return base::rindex(object(sub), object(start)); - } - - template - long rindex(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::rindex(object(sub), object(start), object(end)); - } - - template - str rjust(T const& width) const - { - return base::rjust(object(width)); - } - - list split() const { return base::split(); } - - template - list split(T const& sep) const - { - return base::split(object(sep)); - } - - template - list split(T1 const& sep, T2 const& maxsplit) const - { - return base::split(object(sep), object(maxsplit)); - } - - list splitlines() const { return base::splitlines(); } - - template - list splitlines(T const& keepends) const - { - return base::splitlines(object(keepends)); - } - - template - bool startswith(T const& prefix) const - { - return base::startswith(object(prefix)); - } - - template - bool startswith(T1 const& prefix, T2 const& start) const - { - return base::startswith(object(prefix), object(start)); - } - - template - bool startswith(T1 const& prefix, T2 const& start, T3 const& end) const - { - return base::startswith(object(prefix), object(start), object(end)); - } - - template - str translate(T const& table) const - { - return base::translate(object(table)); - } - - template - str translate(T1 const& table, T2 const& deletechars) const - { - return base::translate(object(table), object(deletechars)); - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyString_Type,str> - { - }; -} - -}} // namespace boost::python - -#endif // STR_20020703_HPP diff --git a/include/boost/python/tag.hpp b/include/boost/python/tag.hpp deleted file mode 100644 index c8ce6878..00000000 --- a/include/boost/python/tag.hpp +++ /dev/null @@ -1,17 +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 TAG_DWA2002720_HPP -# define TAG_DWA2002720_HPP - -namespace boost { namespace python { - -// used only to prevent argument-dependent lookup from finding the -// wrong function in some cases. Cheaper than qualification. -enum tag_t { tag }; - -}} // namespace boost::python - -#endif // TAG_DWA2002720_HPP diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp deleted file mode 100644 index 86bf95a3..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_function< - T, Conversion - > normalized; - - converter::registry::insert( - &normalized::convert - , type_id()); -} - -}} // namespace boost::python - -#endif // TO_PYTHON_CONVERTER_DWA200221_HPP diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp deleted file mode 100644 index 215cb198..00000000 --- a/include/boost/python/to_python_indirect.hpp +++ /dev/null @@ -1,114 +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_INDIRECT_DWA200221_HPP -# define TO_PYTHON_INDIRECT_DWA200221_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template -struct to_python_indirect -{ - PyObject* operator()(T ptr) const; - private: - static PyTypeObject* type(); -}; - -// -// implementations -// -namespace detail -{ - struct make_owning_holder - { - typedef PyObject* result_type; - template - static result_type execute(T* p) - { - // can't use auto_ptr with Intel 5 and VC6 Dinkum library - // for some reason. We get link errors against the auto_ptr - // copy constructor. -# if defined(__ICL) && __ICL < 600 - typedef boost::shared_ptr smart_pointer; -# else - typedef std::auto_ptr smart_pointer; -# endif - typedef objects::pointer_holder holder_t; - - smart_pointer ptr(p); - return objects::make_ptr_instance::execute(ptr); - } - }; - - struct make_reference_holder - { - typedef PyObject* result_type; - template - static result_type execute(T* p) - { - typedef objects::pointer_holder holder_t; - return objects::make_ptr_instance::execute(p); - } - }; - - struct get_pointer_class - { - typedef PyTypeObject* result_type; - template - static result_type execute(T* p) - { - BOOST_STATIC_ASSERT(is_class::value); - return converter::registered::converters.class_object; - } - }; - - // null_pointer_to_none -- return none() for null pointers and 0 for all other types/values - // - // Uses simulated partial ordering - template - inline PyObject* null_pointer_to_none(T&, int) - { - return 0; - } - - // overload for pointers - template - inline PyObject* null_pointer_to_none(T* x, long) - { - return x == 0 ? python::detail::none() : 0; - } -} - -template -inline PyObject* to_python_indirect::operator()(T x) const -{ - BOOST_STATIC_ASSERT(is_pointer::value || is_reference::value); - - PyObject* const null_result = detail::null_pointer_to_none(x, 1L); - if (null_result != 0) - return null_result; - - return detail::unwind_type(x); -} - -template -inline PyTypeObject* to_python_indirect::type() -{ - return detail::unwind_type(); -} - -}} // namespace boost::python - -#endif // TO_PYTHON_INDIRECT_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 4af5c6f8..00000000 --- a/include/boost/python/to_python_value.hpp +++ /dev/null @@ -1,123 +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 -# include -# include -# include - -# include - -# include - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct object_manager_to_python_value - { - typedef typename add_reference< - typename add_const::type - >::type argument_type; - - PyObject* operator()(argument_type) const; - - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = false); - }; - - - template - struct registry_to_python_value - { - typedef typename add_reference< - typename add_const::type - >::type argument_type; - - PyObject* operator()(argument_type) const; - - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = true); - }; - - template - struct shared_ptr_to_python_value - { - typedef typename add_reference< - typename add_const::type - >::type argument_type; - - PyObject* operator()(argument_type) const; - - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = false); - }; -} - -template -struct to_python_value - : mpl::if_< - detail::value_is_shared_ptr - , detail::shared_ptr_to_python_value - , typename mpl::if_< - mpl::or_< - converter::is_object_manager - , converter::is_reference_to_object_manager - > - , detail::object_manager_to_python_value - , detail::registry_to_python_value - >::type - >::type -{ -}; - -// -// implementation -// -namespace detail -{ - template - inline PyObject* registry_to_python_value::operator()(argument_type x) const - { - return converter::registered::converters.to_python(&x); - } - - template - inline PyObject* object_manager_to_python_value::operator()(argument_type x) const - { - return python::upcast( - python::xincref( - get_managed_object(x, tag)) - ); - } - - template - inline PyObject* shared_ptr_to_python_value::operator()(argument_type x) const - { - return converter::shared_ptr_to_python(x); - } -} - -}} // namespace boost::python - -#endif // TO_PYTHON_VALUE_DWA200221_HPP diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp deleted file mode 100644 index 8e3cb210..00000000 --- a/include/boost/python/tuple.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TUPLE_20020706_HPP -#define TUPLE_20020706_HPP - -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace detail -{ - struct BOOST_PYTHON_DECL tuple_base : object - { - protected: - tuple_base(); - tuple_base(object_cref sequence); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple_base, object) - - private: - static detail::new_reference call(object const&); - }; -} - -class tuple : public detail::tuple_base -{ - typedef detail::tuple_base base; - public: - tuple() {} - - template - explicit tuple(T const& sequence) - : base(object(sequence)) - { - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple, base) -}; - -// -// Converter Specializations // $$$ JDG $$$ moved here to prevent -// // G++ bug complaining specialization - // provided after instantiation -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyTuple_Type,tuple> - { - }; -} - -// for completeness -inline tuple make_tuple() { return tuple(); } - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace boost::python - -#endif - diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp deleted file mode 100755 index d44ce26a..00000000 --- a/include/boost/python/type_id.hpp +++ /dev/null @@ -1,134 +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_ID_DWA2002517_HPP -# define TYPE_ID_DWA2002517_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// 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) \ - || defined(_AIX) \ - || ( defined(__sgi) && defined(__host_mips)) -# 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 type_info : private totally_ordered -{ - inline type_info(std::type_info const& = typeid(void)); - - inline bool operator<(type_info const& rhs) const; - inline bool operator==(type_info const& rhs) const; - - char const* name() const; - friend BOOST_PYTHON_DECL std::ostream& operator<<( - std::ostream&, type_info 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; -}; - -template -inline type_info type_id(boost::type* = 0) -{ - return type_info( -# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 700) - typeid(T) -# else // strip the decoration which msvc and Intel mistakenly leave in - python::detail::msvc_typeid() -# endif - ); -} - -# if defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -// Older EDG-based compilers seems to mistakenly distinguish "int" from -// "signed int", etc., but only in typeid() expressions. However -// though int == signed int, the "signed" decoration is propagated -// down into template instantiations. Explicit specialization stops -// that from taking hold. - -# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \ -template <> \ -inline type_info type_id(boost::type*) \ -{ \ - return type_info(typeid(T)); \ -} - -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short) -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int) -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long) -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long) -# endif -# undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID -# endif - - -inline type_info::type_info(std::type_info const& id) - : m_base_type( -# ifdef BOOST_PYTHON_TYPE_ID_NAME - id.name() -# else - &id -# endif - ) -{ -} - -inline bool type_info::operator<(type_info 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_info::operator==(type_info 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 char const* type_info::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&, type_info const&); - -}} // namespace boost::python - -#endif // TYPE_ID_DWA2002517_HPP diff --git a/include/boost/python/with_custodian_and_ward.hpp b/include/boost/python/with_custodian_and_ward.hpp deleted file mode 100644 index 4d022448..00000000 --- a/include/boost/python/with_custodian_and_ward.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP -# define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP - -# include -# include - -namespace boost { namespace python { - -template -struct with_custodian_and_ward : BasePolicy_ -{ - static bool precall(PyObject* args); -}; - -template -struct with_custodian_and_ward_postcall : BasePolicy_ -{ - static PyObject* postcall(PyObject* args, PyObject* result); -}; - -// -// implementations -// -template -bool with_custodian_and_ward::precall(PyObject* args_) -{ - BOOST_STATIC_ASSERT(custodian != ward); - BOOST_STATIC_ASSERT(custodian > 0); - BOOST_STATIC_ASSERT(ward > 0); - - PyObject* patient = PyTuple_GetItem(args_, ward - 1); - if (patient == 0) return false; - PyObject* nurse = PyTuple_GetItem(args_, custodian - 1); - if (nurse == 0) return false; - - PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient); - if (life_support == 0) - return false; - - bool result = BasePolicy_::precall(args_); - - if (!result) - Py_XDECREF(life_support); - - return result; -} - -template -PyObject* with_custodian_and_ward_postcall::postcall(PyObject* args_, PyObject* result) -{ - BOOST_STATIC_ASSERT(custodian != ward); - - PyObject* patient = ward > 0 ? PyTuple_GetItem(args_, ward - 1) : result; - if (patient == 0) return 0; - - PyObject* nurse = custodian > 0 ? PyTuple_GetItem(args_, custodian - 1) : result; - if (nurse == 0) return 0; - - result = BasePolicy_::postcall(args_, result); - if (result == 0) - return 0; - - if (python::objects::make_nurse_and_patient(nurse, patient) == 0) - { - Py_XDECREF(result); - return 0; - } - return result; -} - -}} // namespace boost::python - -#endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP diff --git a/index.html b/index.html deleted file mode 100644 index dff3b20f..00000000 --- a/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - -Automatic redirection failed, please go to -doc/index.html. - - \ No newline at end of file diff --git a/pyste/README b/pyste/README deleted file mode 100644 index b0cc7d36..00000000 --- a/pyste/README +++ /dev/null @@ -1,31 +0,0 @@ -Pyste - Python Semi-Automatic Exporter -====================================== - -Pyste is a Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple interface file, which following the -Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code. - -The documentation can be found in the file index.html accompaning this README. - -Enjoy! -Bruno da Silva de Oliveira (nicodemus@globalite.com.br) - -Thanks -====== - -- David Abrahams, creator of Boost.Python, for tips on the syntax of the interface - file and support. -- Marcelo Camelo, for design tips, support and inspiration for this project. - Also, the name was his idea. 8) -- Brad King, creator of the excellent GCCXML (http://www.gccxml.org) -- Fredrik Lundh, creator of the elementtree library (http://effbot.org) - -Bugs -==== - -Pyste is a young tool, so please help it to get better! Send bug reports to -nicodemus@globalite.com.br, accompaining the stack trace in case of exceptions. -If possible, run pyste with --debug, and send the resulting xmls too (pyste -will output a xml file with the same of each header it parsed). diff --git a/pyste/doc/exporting_all_declarations_from_a_header.html b/pyste/doc/exporting_all_declarations_from_a_header.html deleted file mode 100644 index 4f2418f5..00000000 --- a/pyste/doc/exporting_all_declarations_from_a_header.html +++ /dev/null @@ -1,76 +0,0 @@ - - - -Exporting All Declarations from a Header - - - - - - - - - -
- - Exporting All Declarations from a Header -
-
- - - - - - -
-

-Pyste also supports a mechanism to export all declarations found in a header -file. Suppose again our file, hello.h:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} 
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-    enum choice { red, blue };
-    
-    void show(choice c) { std::cout << "value: " << (int)c << std::endl; } 
-
-

-You can just use the AllFromHeader construct:

-
-    hello = AllFromHeader("hello.h")
-
-

-this will export all the declarations found in hello.h, which is equivalent -to write:

-
-    Class("World", "hello.h")
-    Enum("choice", "hello.h")
-    Function("show", "hello.h")
-
-

-Note that you can still use the functions rename, set_policy, exclude, etc. Just access -the members of the header object like this:

-
-    rename(hello.World.greet, "Greet")
-    exclude(hello.World.set, "Set")
-
- - - - - - -
-
-
- - diff --git a/pyste/doc/introduction.html b/pyste/doc/introduction.html deleted file mode 100644 index ffb50e7e..00000000 --- a/pyste/doc/introduction.html +++ /dev/null @@ -1,74 +0,0 @@ - - - -Introduction - - - - - - - - - -
- - Introduction -
-
- - - - - - -
-

What is Pyste?

-Pyste is a -Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple interface file, which following the - -Boost.Python's philosophy, is simple Python code. Pyste then uses -GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code.

-

Example

-Let's borrow the class World from the -tutorial:

-
-    struct World
-    {
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-

-Here's the interface file for it, named world.pyste:

-
-    Class("World", "world.h")
-
-

-and that's it!

-

-The next step is invoke pyste in the command-line:

-
python pyste.py --module=hello world.pyste

-this will create a file "hello.cpp" in the directory where the command was -run.

-

-Pyste supports the following features:

-
  • Functions
  • Classes
  • Class Templates
  • Virtual Methods
  • Overloading
  • Attributes
  • Enums (both "free" enums and class enums)
  • Nested Classes
- - - - - -
-
-
- - diff --git a/pyste/doc/policies.html b/pyste/doc/policies.html deleted file mode 100644 index 2869889f..00000000 --- a/pyste/doc/policies.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Policies - - - - - - - - - - -
- - Policies -
-
- - - - - - -
-

-Even thought Pyste can identify various elements in the C++ code, like virtual -methods, attributes, and so on, one thing that it can't do is to guess the -semantics of functions that return pointers or references. In this case, the -user must manually specify the policy. Policies are explained in the - -tutorial.

-

-The policies in Pyste are named exactly as in -Boost.Python, only the syntax is -slightly different. For instance, this policy:

-
-    return_internal_reference<1, with_custodian_and_ward<1, 2> >()
-
-

-becomes in Pyste:

-
-    return_internal_reference(1, with_custodian_and_ward(1, 2))
-
-

-The user can specify policies for functions and methods with the set_policy -function:

-
-    set_policy(f, return_internal_reference())
-    set_policy(C.foo, return_value_policy(manage_new_object))
-
- - - - -
- - What if a function or method needs a policy and the user -doesn't set one?

-If a function/method needs a policy and one was not set, Pyste will issue a error. -The user should then go in the interface file and set the policy for it, -otherwise the generated cpp won't compile. -
- - - - - - -
-
-
- - diff --git a/pyste/doc/pyste.txt b/pyste/doc/pyste.txt deleted file mode 100644 index b6fbb281..00000000 --- a/pyste/doc/pyste.txt +++ /dev/null @@ -1,370 +0,0 @@ -[doc Pyste Documentation] - -[def GCCXML [@http://www.gccxml.org GCCXML]] -[def Boost.Python [@../../index.html Boost.Python]] - -[page Introduction] - -[h2 What is Pyste?] - -Pyste is a Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple ['interface file], which following the -Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code. - -[h2 Example] - -Let's borrow the class [^World] from the [@../../doc/tutorial/doc/exposing_classes.html tutorial]: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -Here's the interface file for it, named [^world.pyste]: - - Class("World", "world.h") - -and that's it! - -The next step is invoke pyste in the command-line: - -[pre python pyste.py --module=hello world.pyste] - -this will create a file "[^hello.cpp]" in the directory where the command was -run. - -Pyste supports the following features: - -* Functions -* Classes -* Class Templates -* Virtual Methods -* Overloading -* Attributes -* Enums (both "free" enums and class enums) -* Nested Classes - -[page Running Pyste] - -To run pyste, you will need: - -* Python 2.2, avaiable at [@http://www.python.org python's website]. -* The great [@http://effbot.org elementtree] library, from Fredrik Lundh. -* The excellent GCCXML, from Brad King. - -Installation for the tools is avaiable in their respective webpages. - -[blurb -[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so -that pyste can call it. How to do this varies from platform to platform. -] - -[h2 Ok, now what?] - -Well, now let's fire it up: - -[pre -''' ->python pyste.py - -Usage: - pyste [options] --module= interface-files - -where options are: - -I add an include path - -D define symbol - --no-using do not declare "using namespace boost"; - use explicit declarations instead - --pyste-ns= set the namespace where new types will be declared; - default is "pyste" -''' -] - -Options explained: - -The [^-I] and [^-D] are preprocessor flags, which are needed by gccxml to parse the header files correctly and by pyste to find the header files declared in the -interface files. - -[^--no-using] tells pyste to don't declare "[^using namespace boost;]" in the -generated cpp, using the namespace boost::python explicitly in all declarations. -Use only if you're having a name conflict in one of the files. - -Use [^--pyste-ns] to change the namespace where new types are declared (for -instance, the virtual wrappers). Use only if one of your header files declare a -namespace named "pyste" and this is causing conflicts. - -So, the usage is simple enough: - -[pre >python pyste.py --module=mymodule file.pyste file2.pyste ...] - -will generate a file [^mymodule.cpp] in the same dir where the command was -executed. Now you can compile the file using the same instructions of the -[@../../doc/tutorial/doc/building_hello_world.html tutorial]. - -[h2 Wait... how do I set those I and D flags?] - -Don't worry: normally GCCXML is already configured correctly for your plataform, -so the search path to the standard libraries and the standard defines should -already be set. You only have to set the paths to other libraries that your code -needs, like Boost, for example. - -Plus, Pyste automatically uses the contents of the environment variable -[^INCLUDE] if it exists. Visual C++ users should run the [^Vcvars32.bat] file, -which for Visual C++ 6 is normally located at: - - C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat - -with that, you should have little trouble setting up the flags. - -[page The Interface Files] - -The interface files are the heart of Pyste. The user creates one or more -interface files declaring the classes and functions he wants to export, and then -invokes pyste passing the interface files to it. Pyste then generates a single -cpp file with Boost.Python code, with all the classes and functions exported. - -Besides declaring the classes and functions, the user has a number of other -options, like renaming classes and methods, excluding methods and attributes, -and so on. - -[h2 Basics] - -Suppose we have a class and some functions that we want to expose to Python -declared in the header [^hello.h]: - - struct World - { - World(std::string msg): msg(msg) {} - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - - enum choice { red, blue }; - - namespace test { - - void show(choice c) { std::cout << "value: " << (int)c << std::endl; } - - } - -We create a file named [^hello.pyste] and create instances of the classes -[^Function], [^Class] and [^Enum]: - - Function("test::show", "hello.h") - Class("World", "hello.h") - Enum("choice", "hello.h") - -That will expose the class, the free function and the enum found in [^hello.h]. - -[page:1 Renaming and Excluding] - -You can easily rename functions, classes, methods, attributes, etc. Just use the -function [^rename], like this: - - World = Class("World", "hello.h") - rename(World, "IWorld") - show = Function("choice", "hello.h") - rename(show, "Show") - -You can rename methods and attributes using this syntax: - - rename(World.greet, "Greet") - rename(World.set, "Set") - choice = Enum("choice", "hello.h") - rename(choice.red, "Red") - rename(choice.blue, "Blue") - -You can exclude functions, classes, methods, attributes, etc, in the same way, -with the function [^exclude]: - - exclude(World.greet) - exclude(World.msg) - -Easy, huh? [$theme/smiley.gif] - -[page:1 Policies] - -Even thought Pyste can identify various elements in the C++ code, like virtual -methods, attributes, and so on, one thing that it can't do is to guess the -semantics of functions that return pointers or references. In this case, the -user must manually specify the policy. Policies are explained in the -[@../../doc/tutorial/doc/call_policies.html tutorial]. - -The policies in Pyste are named exactly as in Boost.Python, only the syntax is -slightly different. For instance, this policy: - - return_internal_reference<1, with_custodian_and_ward<1, 2> >() - -becomes in Pyste: - - return_internal_reference(1, with_custodian_and_ward(1, 2)) - -The user can specify policies for functions and methods with the [^set_policy] -function: - - set_policy(f, return_internal_reference()) - set_policy(C.foo, return_value_policy(manage_new_object)) - -[blurb -[$theme/note.gif] [*What if a function or method needs a policy and the user -doesn't set one?][br][br] -If a function/method needs a policy and one was not set, Pyste will issue a error. -The user should then go in the interface file and set the policy for it, -otherwise the generated cpp won't compile. -] - -[page:1 Templates] - -Template Classes can easily exported too, but you can't export the "Template" -itself... you have to export instantiations of it! So, if you want to export a -[^std::vector], you will have to export vectors of int, doubles, etc. - -Suppose we have this code: - - template - struct Point - { - T x; - T y; - }; - -And we want to export [^Point]s of int and double: - - Point = Template("Point", "point.h") - Point("int") - Point("double") - -Pyste will assign default names for each instantiation. In this example, those -would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to -rename the instantiations: - - Point("int", "IPoint") // renames the instantiation - double_inst = Point("double") // another way to do the same - rename(double_inst, "DPoint") - -Note that you can rename, exclude, set policies, etc, in the [^Template] class -like you would do with a [^Function] or a [^Class]. This changes affect all -[*future] instantiations: - - Point = Template("Point", "point.h") - Point("float", "FPoint") // will have x and y as data members - rename(Point.x, "X") - rename(Point.y, "Y") - Point("int", "IPoint") // will have X and Y as data members - Point("double", "DPoint") // also will have X and Y as data member - -If you want to change a option of a particular instantiation, you can do so: - - Point = Template("Point", "point.h") - Point("int", "IPoint") - d_inst = Point("double", "DPoint") - rename(d_inst.x, "X") // only DPoint is affect by this renames, - rename(d_inst.y, "Y") // IPoint stays intact - -[blurb [$theme/note.gif] [*What if my template accepts more than one type?] -[br][br] -When you want to instantiate a Template with more than one type, you can pass -either a string with the types separated by whitespace, or a list of strings -'''("int double" or ["int", "double"]''' would both work). -] - -[page:1 Wrappers] - -Suppose you have this function: - - std::vector names(); - -But you don't want to export a vector, you want this function to return -a python list of strings. Boost.Python has an excellent support for that: - - list names_wrapper() - { - list result; - vector v = names(); - // put each string in the vector in the list - return result; - } - - BOOST_PYTHON_MODULE(test) - { - def("names", &names_wrapper); - } - -Nice heh? -Pyste supports this mechanism too. You declare the [^names_wrapper] function in a -header, like "[^test_wrappers.h]", and in the interface file: - - Include("test_wrappers.h") - names = Function("names", "test.h") - set_wrapper(names, "names_wrapper") - -You can optionally declare the function in the interface file itself: - - names_wrapper = Wrapper("names_wrapper", - """ - list names_wrapper() - { - // call name() and convert the vector to a list... - } - """) - names = Function("names", "test.h") - set_wrapper(names, names_wrapper) - -The same mechanism can be done with methods too. Just remember that the first -parameter of wrappers for methods is a pointer to the class, like in -Boost.Python: - - struct C - { - std::vector names(); - } - - list names_wrapper(C* c) - { - // same as before, calling c->names() and converting result to a list - } - -And then in the interface file: - - C = Class("C", "test.h") - set_wrapper(C.names, "names_wrapper") - -[page:1 Exporting All Declarations from a Header] - -Pyste also supports a mechanism to export all declarations found in a header -file. Suppose again our file, [^hello.h]: - - struct World - { - World(std::string msg): msg(msg) {} - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - - enum choice { red, blue }; - - void show(choice c) { std::cout << "value: " << (int)c << std::endl; } - -You can just use the [^AllFromHeader] construct: - - hello = AllFromHeader("hello.h") - -this will export all the declarations found in [^hello.h], which is equivalent -to write: - - Class("World", "hello.h") - Enum("choice", "hello.h") - Function("show", "hello.h") - -Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access -the members of the header object like this: - - rename(hello.World.greet, "Greet") - exclude(hello.World.set, "Set") - diff --git a/pyste/doc/renaming_and_excluding.html b/pyste/doc/renaming_and_excluding.html deleted file mode 100644 index 29a8001b..00000000 --- a/pyste/doc/renaming_and_excluding.html +++ /dev/null @@ -1,68 +0,0 @@ - - - -Renaming and Excluding - - - - - - - - - - -
- - Renaming and Excluding -
-
- - - - - - -
-

-You can easily rename functions, classes, methods, attributes, etc. Just use the -function rename, like this:

-
-    World = Class("World", "hello.h")
-    rename(World, "IWorld")
-    show = Function("choice", "hello.h")
-    rename(show, "Show")
-
-

-You can rename methods and attributes using this syntax:

-
-    rename(World.greet, "Greet")
-    rename(World.set, "Set")
-    choice = Enum("choice", "hello.h")
-    rename(choice.red, "Red")
-    rename(choice.blue, "Blue")
-
-

-You can exclude functions, classes, methods, attributes, etc, in the same way, -with the function exclude:

-
-    exclude(World.greet)
-    exclude(World.msg)
-
-

-Easy, huh?

- - - - - - -
-
-
- - diff --git a/pyste/doc/running_pyste.html b/pyste/doc/running_pyste.html deleted file mode 100644 index 42834000..00000000 --- a/pyste/doc/running_pyste.html +++ /dev/null @@ -1,110 +0,0 @@ - - - -Running Pyste - - - - - - - - - - -
- - Running Pyste -
-
- - - - - - -
-

-To run pyste, you will need:

-

-Installation for the tools is avaiable in their respective webpages.

- - - - -
- - -GCCXML must be accessible in the PATH environment variable, so -that pyste can call it. How to do this varies from platform to platform. -
-

Ok, now what?

-Well, now let's fire it up:

-
-
->python pyste.py
-
-Usage:
-    pyste [options] --module=<name> interface-files
-
-where options are:
-    -I <path>           add an include path
-    -D <symbol>         define symbol
-    --no-using          do not declare "using namespace boost";
-                        use explicit declarations instead
-    --pyste-ns=<name>   set the namespace where new types will be declared;
-                        default is "pyste"
-                        
-

-Options explained:

-

-The -I and -D are preprocessor flags, which are needed by gccxml to parse the header files correctly and by pyste to find the header files declared in the -interface files.

-

---no-using tells pyste to don't declare "using namespace boost;" in the -generated cpp, using the namespace boost::python explicitly in all declarations. -Use only if you're having a name conflict in one of the files.

-

-Use --pyste-ns to change the namespace where new types are declared (for -instance, the virtual wrappers). Use only if one of your header files declare a -namespace named "pyste" and this is causing conflicts.

-

-So, the usage is simple enough:

-
>python pyste.py --module=mymodule file.pyste file2.pyste ...

-will generate a file mymodule.cpp in the same dir where the command was -executed. Now you can compile the file using the same instructions of the - -tutorial.

-

Wait... how do I set those I and D flags?

-Don't worry: normally -GCCXML is already configured correctly for your plataform, -so the search path to the standard libraries and the standard defines should -already be set. You only have to set the paths to other libraries that your code -needs, like Boost, for example.

-

-Plus, Pyste automatically uses the contents of the environment variable -INCLUDE if it exists. Visual C++ users should run the Vcvars32.bat file, -which for Visual C++ 6 is normally located at:

-
-    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
-
-

-with that, you should have little trouble setting up the flags.

- - - - - - -
-
-
- - diff --git a/pyste/doc/templates.html b/pyste/doc/templates.html deleted file mode 100644 index 58548c72..00000000 --- a/pyste/doc/templates.html +++ /dev/null @@ -1,103 +0,0 @@ - - - -Templates - - - - - - - - - - -
- - Templates -
-
- - - - - - -
-

-Template Classes can easily exported too, but you can't export the "Template" -itself... you have to export instantiations of it! So, if you want to export a -std::vector, you will have to export vectors of int, doubles, etc.

-

-Suppose we have this code:

-
-    template <class T>
-    struct Point
-    {
-        T x;
-        T y;
-    };
-
-

-And we want to export Points of int and double:

-
-    Point = Template("Point", "point.h")
-    Point("int")
-    Point("double")
-
-

-Pyste will assign default names for each instantiation. In this example, those -would be "Point_int" and "Point_double", but most of the time users will want to -rename the instantiations:

-
-    Point("int", "IPoint")         // renames the instantiation
-    double_inst = Point("double")  // another way to do the same
-    rename(double_inst, "DPoint")
-
-

-Note that you can rename, exclude, set policies, etc, in the Template class -like you would do with a Function or a Class. This changes affect all -future instantiations:

-
-    Point = Template("Point", "point.h")
-    Point("float", "FPoint")        // will have x and y as data members
-    rename(Point.x, "X")
-    rename(Point.y, "Y")
-    Point("int", "IPoint")          // will have X and Y as data members
-    Point("double", "DPoint")       // also will have X and Y as data member
-
-

-If you want to change a option of a particular instantiation, you can do so:

-
-    Point = Template("Point", "point.h")
-    Point("int", "IPoint")          
-    d_inst = Point("double", "DPoint")       
-    rename(d_inst.x, "X")           // only DPoint is affect by this renames,
-    rename(d_inst.y, "Y")           // IPoint stays intact
-
- - - - -
- What if my template accepts more than one type? -

-When you want to instantiate a Template with more than one type, you can pass -either a string with the types separated by whitespace, or a list of strings -("int double" or ["int", "double"] would both work). -
- - - - - - -
-
-
- - diff --git a/pyste/doc/the_interface_files.html b/pyste/doc/the_interface_files.html deleted file mode 100644 index 77246af7..00000000 --- a/pyste/doc/the_interface_files.html +++ /dev/null @@ -1,81 +0,0 @@ - - - -The Interface Files - - - - - - - - - - -
- - The Interface Files -
-
- - - - - - -
-

-The interface files are the heart of Pyste. The user creates one or more -interface files declaring the classes and functions he wants to export, and then -invokes pyste passing the interface files to it. Pyste then generates a single -cpp file with -Boost.Python code, with all the classes and functions exported.

-

-Besides declaring the classes and functions, the user has a number of other -options, like renaming classes and methods, excluding methods and attributes, -and so on.

-

Basics

-Suppose we have a class and some functions that we want to expose to Python -declared in the header hello.h:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} 
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-    enum choice { red, blue };
-    
-    namespace test {
-    
-    void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
-    
-    }
-
-

-We create a file named hello.pyste and create instances of the classes -Function, Class and Enum:

-
-    Function("test::show", "hello.h")
-    Class("World", "hello.h")
-    Enum("choice", "hello.h")
-
-

-That will expose the class, the free function and the enum found in hello.h.

- - - - - - -
-
-
- - diff --git a/pyste/doc/theme/alert.gif b/pyste/doc/theme/alert.gif deleted file mode 100644 index 270764cc..00000000 Binary files a/pyste/doc/theme/alert.gif and /dev/null differ diff --git a/pyste/doc/theme/arrow.gif b/pyste/doc/theme/arrow.gif deleted file mode 100644 index e33db0fb..00000000 Binary files a/pyste/doc/theme/arrow.gif and /dev/null differ diff --git a/pyste/doc/theme/bkd.gif b/pyste/doc/theme/bkd.gif deleted file mode 100644 index dcabcb80..00000000 Binary files a/pyste/doc/theme/bkd.gif and /dev/null differ diff --git a/pyste/doc/theme/bkd2.gif b/pyste/doc/theme/bkd2.gif deleted file mode 100644 index b03d9ba9..00000000 Binary files a/pyste/doc/theme/bkd2.gif and /dev/null differ diff --git a/pyste/doc/theme/bulb.gif b/pyste/doc/theme/bulb.gif deleted file mode 100644 index 74f3baac..00000000 Binary files a/pyste/doc/theme/bulb.gif and /dev/null differ diff --git a/pyste/doc/theme/bullet.gif b/pyste/doc/theme/bullet.gif deleted file mode 100644 index da787e2e..00000000 Binary files a/pyste/doc/theme/bullet.gif and /dev/null differ diff --git a/pyste/doc/theme/c++boost.gif b/pyste/doc/theme/c++boost.gif deleted file mode 100644 index 58be431a..00000000 Binary files a/pyste/doc/theme/c++boost.gif and /dev/null differ diff --git a/pyste/doc/theme/l_arr.gif b/pyste/doc/theme/l_arr.gif deleted file mode 100644 index 5b3cb1cb..00000000 Binary files a/pyste/doc/theme/l_arr.gif and /dev/null differ diff --git a/pyste/doc/theme/l_arr_disabled.gif b/pyste/doc/theme/l_arr_disabled.gif deleted file mode 100644 index ed58a605..00000000 Binary files a/pyste/doc/theme/l_arr_disabled.gif and /dev/null differ diff --git a/pyste/doc/theme/note.gif b/pyste/doc/theme/note.gif deleted file mode 100644 index bd92f075..00000000 Binary files a/pyste/doc/theme/note.gif and /dev/null differ diff --git a/pyste/doc/theme/r_arr.gif b/pyste/doc/theme/r_arr.gif deleted file mode 100644 index 2dcdad11..00000000 Binary files a/pyste/doc/theme/r_arr.gif and /dev/null differ diff --git a/pyste/doc/theme/r_arr_disabled.gif b/pyste/doc/theme/r_arr_disabled.gif deleted file mode 100644 index 2100f78b..00000000 Binary files a/pyste/doc/theme/r_arr_disabled.gif and /dev/null differ diff --git a/pyste/doc/theme/smiley.gif b/pyste/doc/theme/smiley.gif deleted file mode 100644 index 4c848f8f..00000000 Binary files a/pyste/doc/theme/smiley.gif and /dev/null differ diff --git a/pyste/doc/theme/style.css b/pyste/doc/theme/style.css deleted file mode 100644 index 53a6205e..00000000 --- a/pyste/doc/theme/style.css +++ /dev/null @@ -1,170 +0,0 @@ -body -{ - background-image: url(bkd.gif); - background-color: #FFFFFF; - margin: 1em 2em 1em 2em; -} - -h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; } -h2 { font: 140% sans-serif; font-weight: bold; text-align: left; } -h3 { font: 120% sans-serif; font-weight: bold; text-align: left; } -h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; } -h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; } -h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; } - -pre -{ - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-top: 2pt; - padding-right: 2pt; - padding-left: 2pt; - padding-bottom: 2pt; - - display: block; - font-family: "courier new", courier, mono; - background-color: #eeeeee; font-size: small -} - -code -{ - font-family: "Courier New", Courier, mono; - font-size: small -} - -tt -{ - display: inline; - font-family: "Courier New", Courier, mono; - color: #000099; - font-size: small -} - -p -{ - text-align: justify; - font-family: Georgia, "Times New Roman", Times, serif -} - -ul -{ - list-style-image: url(bullet.gif); - font-family: Georgia, "Times New Roman", Times, serif -} - -ol -{ - font-family: Georgia, "Times New Roman", Times, serif -} - -a -{ - font-weight: bold; - color: #003366; - text-decoration: none; -} - -a:hover { color: #8080FF; } - -.literal { color: #666666; font-style: italic} -.keyword { color: #000099} -.identifier {} -.comment { font-style: italic; color: #990000} -.special { color: #800040} -.preprocessor { color: #FF0000} -.string { font-style: italic; color: #666666} -.copyright { color: #666666; font-size: small} -.white_bkd { background-color: #FFFFFF} -.dk_grey_bkd { background-color: #999999} -.quotes { color: #666666; font-style: italic; font-weight: bold} - -.note_box -{ - display: block; - - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-right: 12pt; - padding-left: 12pt; - padding-bottom: 12pt; - padding-top: 12pt; - - font-family: Arial, Helvetica, sans-serif; - background-color: #E2E9EF; - font-size: small; text-align: justify -} - -.table_title -{ - background-color: #648CCA; - - font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; - font-weight: bold -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.table_cells -{ - background-color: #E2E9EF; - - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.toc -{ - DISPLAY: block; - background-color: #E2E9EF - font-family: Arial, Helvetica, sans-serif; - - border-top: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - border-right: gray 1pt solid; - - padding-top: 24pt; - padding-right: 24pt; - padding-left: 24pt; - padding-bottom: 24pt; -} - -.toc_title -{ - background-color: #648CCA; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - color: #FFFFFF; - font-weight: bold -} - -.toc_cells -{ - background-color: #E2E9EF; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -} - -div.logo -{ - float: right; -} - -.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } diff --git a/pyste/doc/theme/u_arr.gif b/pyste/doc/theme/u_arr.gif deleted file mode 100644 index ada3d6e0..00000000 Binary files a/pyste/doc/theme/u_arr.gif and /dev/null differ diff --git a/pyste/doc/wrappers.html b/pyste/doc/wrappers.html deleted file mode 100644 index 61bda6f8..00000000 --- a/pyste/doc/wrappers.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -Wrappers - - - - - - - - - - -
- - Wrappers -
-
- - - - - - -
-

-Suppose you have this function:

-
-    std::vector<std::string> names();
-
-

-But you don't want to export a vector<string>, you want this function to return -a python list of strings. -Boost.Python has an excellent support for that:

-
-    list names_wrapper()
-    {
-        list result;
-        vector<string> v = names();
-        // put each string in the vector in the list
-        return result;
-    }
-    
-    BOOST_PYTHON_MODULE(test)
-    {
-        def("names", &names_wrapper);
-    }
-
-

-Nice heh? -Pyste supports this mechanism too. You declare the names_wrapper function in a -header, like "test_wrappers.h", and in the interface file:

-
-    Include("test_wrappers.h")
-    names = Function("names", "test.h")
-    set_wrapper(names, "names_wrapper")
-
-

-You can optionally declare the function in the interface file itself:

-
-    names_wrapper = Wrapper("names_wrapper",
-    """
-    list names_wrapper()
-    {
-        // call name() and convert the vector to a list...
-    }
-    """)
-    names = Function("names", "test.h")
-    set_wrapper(names, names_wrapper)
-
-

-The same mechanism can be done with methods too. Just remember that the first -parameter of wrappers for methods is a pointer to the class, like in - -Boost.Python:

-
-    struct C
-    {
-        std::vector<std::string> names();
-    }
-
-    list names_wrapper(C* c)
-    {
-        // same as before, calling c->names() and converting result to a list
-    }
-
-

-And then in the interface file:

-
-    C = Class("C", "test.h")
-    set_wrapper(C.names, "names_wrapper")
-
- - - - - - -
-
-
- - diff --git a/pyste/example/README b/pyste/example/README deleted file mode 100644 index 868345b0..00000000 --- a/pyste/example/README +++ /dev/null @@ -1,5 +0,0 @@ -To use this examples, just execute the command-line: - -pyste --module= .pyste - -For more information, please refer to the documentation. diff --git a/pyste/example/basic.h b/pyste/example/basic.h deleted file mode 100644 index 5a619e72..00000000 --- a/pyste/example/basic.h +++ /dev/null @@ -1,21 +0,0 @@ -struct C -{ - virtual int f(int x = 10) - { - return x*2; - } - - int foo(int x=1){ - return x+1; - } -}; - -int call_f(C& c) -{ - return c.f(); -} - -int call_f(C& c, int x) -{ - return c.f(x); -} diff --git a/pyste/example/basic.pyste b/pyste/example/basic.pyste deleted file mode 100644 index a6b4e17b..00000000 --- a/pyste/example/basic.pyste +++ /dev/null @@ -1,2 +0,0 @@ -Class('C', 'basic.h') -Function('call_f', 'basic.h') diff --git a/pyste/example/enums.h b/pyste/example/enums.h deleted file mode 100644 index 440cefd2..00000000 --- a/pyste/example/enums.h +++ /dev/null @@ -1,18 +0,0 @@ -namespace test { -enum color { red, blue }; - -struct X -{ - enum choices - { - good = 1, - bad = 2 - }; - - int set(choices c) - { - return (int)c; - } -}; - -} diff --git a/pyste/example/enums.pyste b/pyste/example/enums.pyste deleted file mode 100644 index dd9d7fbc..00000000 --- a/pyste/example/enums.pyste +++ /dev/null @@ -1,8 +0,0 @@ -color = Enum('test::color', 'enums.h') -rename(color.red, 'Red') -rename(color.blue, 'Blue') -X = Class('test::X', 'enums.h') -rename(X.choices.bad, 'Bad') -rename(X.choices.good, 'Good') -rename(X.choices, 'Choices') - diff --git a/pyste/example/header_test.h b/pyste/example/header_test.h deleted file mode 100644 index d3d60fcc..00000000 --- a/pyste/example/header_test.h +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include - -enum choice { red, blue }; - -void print_choice(choice c) -{ - std::map choice_map; - choice_map[red] = "red"; - choice_map[blue] = "blue"; - std::cout << "You chose: " << choice_map[c] << std::endl; -} - -struct C -{ - choice c; - - void print_() - { - print_choice(c); - } -}; diff --git a/pyste/example/header_test.pyste b/pyste/example/header_test.pyste deleted file mode 100644 index b0e752ff..00000000 --- a/pyste/example/header_test.pyste +++ /dev/null @@ -1 +0,0 @@ -AllFromHeader('header_test.h') diff --git a/pyste/example/nested.h b/pyste/example/nested.h deleted file mode 100644 index 35804fbb..00000000 --- a/pyste/example/nested.h +++ /dev/null @@ -1,21 +0,0 @@ - -struct X -{ - struct Y - { - int valueY; - static int staticYValue; - struct Z - { - int valueZ; - }; - }; - - static int staticXValue; - int valueX; -}; - -int X::staticXValue = 10; -int X::Y::staticYValue = 20; - -typedef X Root; diff --git a/pyste/example/nested.pyste b/pyste/example/nested.pyste deleted file mode 100644 index b6291385..00000000 --- a/pyste/example/nested.pyste +++ /dev/null @@ -1 +0,0 @@ -Class('Root', 'nested.h') diff --git a/pyste/example/operator.h b/pyste/example/operator.h deleted file mode 100644 index 5c07549b..00000000 --- a/pyste/example/operator.h +++ /dev/null @@ -1,47 +0,0 @@ -#include - - -struct C -{ - static double x; - double value; - - const C operator+(const C other) const - { - C c; - c.value = value + other.value; - return c; - } - operator int() const - { - return value; - } - double operator()() - { - return x; - } - - double operator()(double other) - { - return x + other; - } - - -}; - -double C::x = 10; - -const C operator*(const C& lhs, const C& rhs) -{ - C c; - c.value = lhs.value * rhs.value; - return c; -} - -std::ostream& operator <<( std::ostream& s, const C& c) -{ - std::cout << "here"; - s << "C instance: "; - return s; -} - diff --git a/pyste/example/operator.pyste b/pyste/example/operator.pyste deleted file mode 100644 index ffa5725c..00000000 --- a/pyste/example/operator.pyste +++ /dev/null @@ -1,12 +0,0 @@ -Include('iostream') -test = Wrapper('sum', -''' -const C sum(const C&, const C&) -{ - std::cout << "sum!" << std::endl; - return C(); -} -''' -) -C = Class('C', 'operator.h') -set_wrapper(C.operator['+'], test) diff --git a/pyste/example/templates.h b/pyste/example/templates.h deleted file mode 100644 index de2afe44..00000000 --- a/pyste/example/templates.h +++ /dev/null @@ -1,8 +0,0 @@ - -template -struct Point -{ - X x; - Y y; -}; - diff --git a/pyste/example/templates.pyste b/pyste/example/templates.pyste deleted file mode 100644 index 30bef79e..00000000 --- a/pyste/example/templates.pyste +++ /dev/null @@ -1,8 +0,0 @@ -Point = Template('Point', 'templates.h') -rename(Point.x, 'i') -rename(Point.y, 'j') -IPoint = Point('int double') -FPoint = Point('double int') -rename(IPoint, 'IPoint') -rename(IPoint.x, '_x_') - diff --git a/pyste/example/wrappertest.h b/pyste/example/wrappertest.h deleted file mode 100644 index a75cddcc..00000000 --- a/pyste/example/wrappertest.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef WRAPPER_TEST -#define WRAPPER_TEST - - -#include - -std::vector Range(int count) -{ - std::vector v; - v.reserve(count); - for (int i = 0; i < count; ++i){ - v.push_back(i); - } - return v; -} - - -struct C -{ - C() {} - - std::vector Mul(int value) - { - std::vector res; - res.reserve(value); - std::vector::const_iterator it; - std::vector v(Range(value)); - for (it = v.begin(); it != v.end(); ++it){ - res.push_back(*it * value); - } - return res; - } -}; - -#endif diff --git a/pyste/example/wrappertest.pyste b/pyste/example/wrappertest.pyste deleted file mode 100644 index 80c76cda..00000000 --- a/pyste/example/wrappertest.pyste +++ /dev/null @@ -1,15 +0,0 @@ -Include('wrappertest_wrappers.h') - -f = Function('Range', 'wrappertest.h') -set_wrapper(f, 'RangeWrapper') - -mul = Wrapper('MulWrapper', -''' -list MulWrapper(C& c, int value){ - return VectorToList(c.Mul(value)); -} -''' -) - -C = Class('C', 'wrappertest.h') -set_wrapper(C.Mul, mul) diff --git a/pyste/example/wrappertest_wrappers.h b/pyste/example/wrappertest_wrappers.h deleted file mode 100644 index a45c3671..00000000 --- a/pyste/example/wrappertest_wrappers.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef WRAPPER_TEST_WRAPPERS -#define WRAPPER_TEST_WRAPPERS - -#include -#include -#include "wrappertest.h" - -using namespace boost::python; - -template -list VectorToList(const std::vector & v) -{ - list res; - std::vector::const_iterator it; - for(it = v.begin(); it != v.end(); ++it){ - res.append(*it); - } - Py_XINCREF(res.ptr()); - return res; -} - -list RangeWrapper(int count){ - return VectorToList(Range(count)); -} - -#endif diff --git a/pyste/index.html b/pyste/index.html deleted file mode 100644 index ff153b50..00000000 --- a/pyste/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - -Pyste Documentation - - - - - - - - - -
- - Pyste Documentation -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table of contents
- Introduction -
- Running Pyste -
- The Interface Files -
- Renaming and Excluding -
- Policies -
- Templates -
- Wrappers -
- Exporting All Declarations from a Header -
-
-
- - diff --git a/pyste/src/.cvsignore b/pyste/src/.cvsignore deleted file mode 100644 index 0d20b648..00000000 --- a/pyste/src/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/pyste/src/ClassExporter.py b/pyste/src/ClassExporter.py deleted file mode 100644 index 64bf3834..00000000 --- a/pyste/src/ClassExporter.py +++ /dev/null @@ -1,726 +0,0 @@ -import exporters -from Exporter import Exporter -from declarations import * -from enumerate import enumerate -from settings import * -from CodeUnit import CodeUnit -from EnumExporter import EnumExporter - - -#============================================================================== -# ClassExporter -#============================================================================== -class ClassExporter(Exporter): - 'Generates boost.python code to export a class declaration' - - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - # sections of code - self.sections = {} - # template: each item in the list is an item into the class_<...> - # section. - self.sections['template'] = [] - # constructor: each item in the list is a parameter to the class_ - # constructor, like class_(...) - self.sections['constructor'] = [] - # inside: everything within the class_<> statement - self.sections['inside'] = [] - # scope: items outside the class statement but within its scope. - # scope* s = new scope(class<>()); - # ... - # delete s; - self.sections['scope'] = [] - # declarations: outside the BOOST_PYTHON_MODULE macro - self.sections['declaration'] = [] - self.sections['include'] = [] - # a list of Constructor instances - self.constructors = [] - self.wrapper_generator = None - # a list of code units, generated by nested declarations - self.nested_codeunits = [] - - - def ScopeName(self): - return _ID(self.class_.FullName()) + '_scope' - - - def Name(self): - return self.class_.FullName() - - - def SetDeclarations(self, declarations): - Exporter.SetDeclarations(self, declarations) - decl = self.GetDeclaration(self.info.name) - if isinstance(decl, Typedef): - self.class_ = decl.type - if not self.info.rename: - self.info.rename = decl.name - else: - self.class_ = decl - self.public_members = \ - [x for x in self.class_.members if x.visibility == Scope.public] - - - def Order(self): - '''Return the TOTAL number of bases that this class has, including the - bases' bases. Do this because base classes must be instantialized - before the derived classes in the module definition. - ''' - - def BasesCount(classname): - decl = self.GetDeclaration(classname) - bases = [x.name for x in decl.bases] - total = 0 - for base in bases: - total += BasesCount(base) - return len(bases) + total - - return BasesCount(self.class_.FullName()) - - - def Export(self, codeunit, exported_names): - self.ExportBasics() - self.ExportBases(exported_names) - self.ExportConstructors() - self.ExportVariables() - self.ExportMethods() - self.ExportVirtualMethods() - self.ExportOperators() - self.ExportNestedClasses(exported_names) - self.ExportNestedEnums() - self.Write(codeunit) - - - def Write(self, codeunit): - indent = self.INDENT - boost_ns = namespaces.python - pyste_ns = namespaces.pyste - code = '' - # begin a scope for this class if needed - nested_codeunits = self.nested_codeunits - needs_scope = self.sections['scope'] or nested_codeunits - if needs_scope: - scope_name = self.ScopeName() - code += indent + boost_ns + 'scope* %s = new %sscope(\n' %\ - (scope_name, boost_ns) - # export the template section - template_params = ', '.join(self.sections['template']) - code += indent + boost_ns + 'class_< %s >' % template_params - # export the constructor section - constructor_params = ', '.join(self.sections['constructor']) - code += '(%s)\n' % constructor_params - # export the inside section - in_indent = indent*2 - for line in self.sections['inside']: - code += in_indent + line + '\n' - # write the scope section and end it - if not needs_scope: - code += indent + ';\n' - else: - code += indent + ');\n' - for line in self.sections['scope']: - code += indent + line + '\n' - # write the contents of the nested classes - for nested_unit in nested_codeunits: - code += '\n' + nested_unit.Section('module') - # close the scope - code += indent + 'delete %s;\n' % scope_name - - # write the code to the module section in the codeunit - codeunit.Write('module', code + '\n') - - # write the declarations to the codeunit - declarations = '\n'.join(self.sections['declaration']) - for nested_unit in nested_codeunits: - declarations += nested_unit.Section('declaration') - if declarations: - codeunit.Write('declaration', declarations + '\n') - - # write the includes to the codeunit - includes = '\n'.join(self.sections['include']) - for nested_unit in nested_codeunits: - includes += nested_unit.Section('include') - if includes: - codeunit.Write('include', includes) - - - def Add(self, section, item): - 'Add the item into the corresponding section' - self.sections[section].append(item) - - - def ExportBasics(self): - 'Export the name of the class and its class_ statement' - self.Add('template', self.class_.FullName()) - name = self.info.rename or self.class_.name - self.Add('constructor', '"%s"' % name) - - - def ExportBases(self, exported_names): - 'Expose the bases of the class into the template section' - bases = self.class_.bases - bases_list = [] - for base in bases: - if base.visibility == Scope.public and base.name in exported_names: - bases_list.append(base.name) - if bases_list: - code = namespaces.python + 'bases< %s > ' % \ - (', '.join(bases_list)) - self.Add('template', code) - - - def ExportConstructors(self): - '''Exports all the public contructors of the class, plus indicates if the - class is noncopyable. - ''' - py_ns = namespaces.python - indent = self.INDENT - - def init_code(cons): - 'return the init<>() code for the given contructor' - param_list = [p.FullName() for p in cons.parameters] - min_params_list = param_list[:cons.minArgs] - max_params_list = param_list[cons.minArgs:] - min_params = ', '.join(min_params_list) - max_params = ', '.join(max_params_list) - init = py_ns + 'init< ' - init += min_params - if max_params: - if min_params: - init += ', ' - init += py_ns + ('optional< %s >' % max_params) - init += ' >()' - return init - - constructors = [x for x in self.public_members if isinstance(x, Constructor)] - self.constructors = constructors[:] - if not constructors: - # declare no_init - self.Add('constructor', py_ns + 'no_init') - else: - # write the constructor with less parameters to the constructor section - smaller = None - for cons in constructors: - if smaller is None or len(cons.parameters) < len(smaller.parameters): - smaller = cons - assert smaller is not None - self.Add('constructor', init_code(smaller)) - constructors.remove(smaller) - # write the rest to the inside section, using def() - for cons in constructors: - code = '.def(%s)' % init_code(cons) - self.Add('inside', code) - # check if the class is copyable - if not self.class_.HasCopyConstructor() or self.class_.abstract: - self.Add('template', namespaces.boost + 'noncopyable') - - - def ExportVariables(self): - 'Export the variables of the class, both static and simple variables' - vars = [x for x in self.public_members if isinstance(x, Variable)] - for var in vars: - if self.info[var.name].exclude: - continue - name = self.info[var.name].rename or var.name - fullname = var.FullName() - if var.static: - code = '%s->attr("%s") = %s;' % (self.ScopeName(), name, fullname) - self.Add('scope', code) - else: - if var.type.const: - def_ = '.def_readonly' - else: - def_ = '.def_readwrite' - code = '%s("%s", &%s)' % (def_, name, fullname) - self.Add('inside', code) - - - printed_policy_warnings = {} - - def CheckPolicy(self, m): - 'Warns the user if this method needs a policy' - def IsString(type): - return type.const and type.name == 'char' and isinstance(type, PointerType) - needs_policy = isinstance(m.result, (ReferenceType, PointerType)) - if IsString(m.result): - needs_policy = False - has_policy = self.info[m.name].policy is not None - if needs_policy and not has_policy: - warning = '---> Error: Method "%s" needs a policy.' % m.FullName() - if warning not in self.printed_policy_warnings: - print warning - print - self.printed_policy_warnings[warning] = 1 - - - def ExportMethods(self): - 'Export all the non-virtual methods of this class' - - def OverloadName(m): - 'Returns the name of the overloads struct for the given method' - return _ID(m.FullName()) + ('_overloads_%i_%i' % (m.minArgs, m.maxArgs)) - - declared = {} - def DeclareOverloads(m): - 'Declares the macro for the generation of the overloads' - if not m.virtual: - func = m.name - code = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(%s, %s, %i, %i)\n' - code = code % (OverloadName(m), func, m.minArgs, m.maxArgs) - if code not in declared: - declared[code] = True - self.Add('declaration', code) - - - def Pointer(m): - 'returns the correct pointer declaration for the method m' - # check if this method has a wrapper set for him - wrapper = self.info[method.name].wrapper - if wrapper: - return '&' + wrapper.FullName() - # return normal pointers to the methods of the class - is_unique = self.class_.IsUnique(m.name) - if is_unique: - return '&' + method.FullName() - else: - return method.PointerDeclaration() - - def IsExportable(m): - 'Returns true if the given method is exportable by this routine' - ignore = (Constructor, ClassOperator, Destructor) - return isinstance(m, Method) and not isinstance(m, ignore) and not m.virtual - - methods = [x for x in self.public_members if IsExportable(x)] - - for method in methods: - if self.info[method.name].exclude: - continue # skip this method - - name = self.info[method.name].rename or method.name - - # warn the user if this method needs a policy and doesn't have one - self.CheckPolicy(method) - - # check for policies - policy = self.info[method.name].policy or '' - if policy: - policy = ', %s%s()' % (namespaces.python, policy.Code()) - # check for overloads - overload = '' - if method.minArgs != method.maxArgs: - # add the overloads for this method - overload_name = OverloadName(method) - DeclareOverloads(method) - overload = ', %s%s()' % (namespaces.pyste, overload_name) - - # build the .def string to export the method - pointer = Pointer(method) - code = '.def("%s", %s' % (name, pointer) - code += policy - code += overload - code += ')' - self.Add('inside', code) - # static method - if method.static: - code = '.staticmethod("%s")' % name - self.Add('inside', code) - # add wrapper code if this method has one - wrapper = self.info[method.name].wrapper - if wrapper and wrapper.code: - self.Add('declaration', wrapper.code) - - - def ExportVirtualMethods(self): - # check if this class has any virtual methods - has_virtual_methods = False - for member in self.class_.members: - if type(member) == Method and member.virtual: - has_virtual_methods = True - break - - if has_virtual_methods: - generator = _VirtualWrapperGenerator(self.class_, self.info) - self.Add('template', generator.FullName()) - for definition in generator.GenerateDefinitions(): - self.Add('inside', definition) - self.Add('declaration', generator.GenerateVirtualWrapper(self.INDENT)) - - - # operators natively supported by boost - BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -='\ - '*= /= %= ^= &= |= <<= >>='.split() - # create a map for faster lookup - BOOST_SUPPORTED_OPERATORS = dict(zip(BOOST_SUPPORTED_OPERATORS, range(len(BOOST_SUPPORTED_OPERATORS)))) - - # a dict of operators that are not directly supported by boost, but can be exposed - # simply as a function with a special signature - BOOST_RENAME_OPERATORS = { - '()' : '__call__', - } - - # converters which has a special name in python - SPECIAL_CONVETERS = { - 'double' : '__float__', - 'float' : '__float__', - 'int' : '__int__', - } - - - def ExportOperators(self): - 'Export all member operators and free operators related to this class' - - def GetFreeOperators(): - 'Get all the free (global) operators related to this class' - operators = [] - for decl in self.declarations: - if isinstance(decl, Operator): - # check if one of the params is this class - for param in decl.parameters: - if param.name == self.class_.FullName(): - operators.append(decl) - break - return operators - - def GetOperand(param): - 'Returns the operand of this parameter (either "self", or "other")' - if param.name == self.class_.FullName(): - return namespaces.python + 'self' - else: - return namespaces.python + ('other< %s >()' % param.name) - - - def HandleSpecialOperator(operator): - # gatter information about the operator and its parameters - result_name = operator.result.name - param1_name = '' - if operator.parameters: - param1_name = operator.parameters[0].name - - # check for str - ostream = 'basic_ostream' - is_str = result_name.find(ostream) != -1 and param1_name.find(ostream) != -1 - if is_str: - namespace = namespaces.python + 'self_ns::' - self_ = namespaces.python + 'self' - return '.def(%sstr(%s))' % (namespace, self_) - - # is not a special operator - return None - - - - frees = GetFreeOperators() - members = [x for x in self.public_members if type(x) == ClassOperator] - all_operators = frees + members - operators = [x for x in all_operators if not self.info['operator'][x.name].exclude] - - for operator in operators: - # gatter information about the operator, for use later - wrapper = self.info['operator'][operator.name].wrapper - if wrapper: - pointer = '&' + wrapper.FullName() - if wrapper.code: - self.Add('declaration', wrapper.code) - elif isinstance(operator, ClassOperator) and self.class_.IsUnique(operator.name): - pointer = '&' + operator.FullName() - else: - pointer = operator.PointerDeclaration() - rename = self.info['operator'][operator.name].rename - - # check if this operator will be exported as a method - export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS - - # check if this operator has a special representation in boost - special_code = HandleSpecialOperator(operator) - has_special_representation = special_code is not None - - if export_as_method: - # export this operator as a normal method, renaming or using the given wrapper - if not rename: - if wrapper: - rename = wrapper.name - else: - rename = self.BOOST_RENAME_OPERATORS[operator.name] - policy = '' - policy_obj = self.info['operator'][operator.name].policy - if policy_obj: - policy = ', %s()' % policy_obj.Code() - self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy)) - - elif has_special_representation: - self.Add('inside', special_code) - - elif operator.name in self.BOOST_SUPPORTED_OPERATORS: - # export this operator using boost's facilities - op = operator - is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\ - isinstance(op, ClassOperator) and len(op.parameters) == 0 - if is_unary: - self.Add('inside', '.def( %s%sself )' % \ - (operator.name, namespaces.python)) - else: - # binary operator - if len(operator.parameters) == 2: - left_operand = GetOperand(operator.parameters[0]) - right_operand = GetOperand(operator.parameters[1]) - else: - left_operand = namespaces.python + 'self' - right_operand = GetOperand(operator.parameters[0]) - self.Add('inside', '.def( %s %s %s )' % \ - (left_operand, operator.name, right_operand)) - - # export the converters. - # export them as simple functions with a pre-determined name - - converters = [x for x in self.public_members if type(x) == ConverterOperator] - - def ConverterMethodName(converter): - result_fullname = converter.result.name - # extract the last name from the full name - result_name = _ID(result_fullname.split('::')[-1]) - return 'to_' + result_name - - for converter in converters: - info = self.info['operator'][converter.result.name] - # check if this operator should be excluded - if info.exclude: - continue - - special_code = HandleSpecialOperator(converter) - if info.rename or not special_code: - # export as method - name = info.rename or ConverterMethodName(converter) - if self.class_.IsUnique(converter.name): - pointer = '&' + converter.FullName() - else: - pointer = converter.PointerDeclaration() - policy_code = '' - if info.policy: - policy_code = ', %s()' % info.policy.Code() - self.Add('inside', '.def("%s", %s%s)' % (name, pointer, policy_code)) - - elif special_code: - self.Add('inside', special_code) - - - - def ExportNestedClasses(self, exported_names): - nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)] - for nested_class in nested_classes: - nested_info = self.info[nested_class.name] - nested_info.include = self.info.include - nested_info.name = nested_class.FullName() - exporter = ClassExporter(nested_info) - exporter.SetDeclarations(self.declarations + [nested_class]) - codeunit = CodeUnit(None) - exporter.Export(codeunit, exported_names) - self.nested_codeunits.append(codeunit) - - - def ExportNestedEnums(self): - nested_enums = [x for x in self.public_members if isinstance(x, ClassEnumeration)] - for enum in nested_enums: - enum_info = self.info[enum.name] - enum_info.include = self.info.include - enum_info.name = enum.FullName() - exporter = EnumExporter(enum_info) - exporter.SetDeclarations(self.declarations + [enum]) - codeunit = CodeUnit(None) - exporter.Export(codeunit, None) - self.nested_codeunits.append(codeunit) - - - - -def _ID(name): - 'Returns the name as a valid identifier' - for invalidchar in ('::', '<', '>', ' ', ','): - name = name.replace(invalidchar, '_') - # avoid duplications of '_' chars - names = [x for x in name.split('_') if x] - return '_'.join(names) - - -#============================================================================== -# Virtual Wrapper utils -#============================================================================== - -def _ParamsInfo(m, count=None): - if count is None: - count = len(m.parameters) - param_names = ['p%i' % i for i in range(count)] - param_types = [x.FullName() for x in m.parameters[:count]] - params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)] - #for i, p in enumerate(m.parameters[:count]): - # if p.default is not None: - # #params[i] += '=%s' % p.default - # params[i] += '=%s' % (p.name + '()') - params = ', '.join(params) - return params, param_names, param_types - - -class _VirtualWrapperGenerator(object): - 'Generates code to export the virtual methods of the given class' - - def __init__(self, class_, info): - self.class_ = class_ - self.info = info - self.wrapper_name = _ID(class_.FullName()) + '_Wrapper' - - - def DefaultImplementationNames(self, method): - '''Returns a list of default implementations for this method, one for each - number of default arguments. Always returns at least one name, and return from - the one with most arguments to the one with the least. - ''' - base_name = 'default_' + method.name - minArgs = method.minArgs - maxArgs = method.maxArgs - if minArgs == maxArgs: - return [base_name] - else: - return [base_name + ('_%i' % i) for i in range(minArgs, maxArgs+1)] - - - def Declaration(self, method, indent): - '''Returns a string with the declarations of the virtual wrapper and - its default implementations. This string must be put inside the Wrapper - body. - ''' - pyste = namespaces.pyste - python = namespaces.python - rename = self.info[method.name].rename or method.name - result = method.result.FullName() - return_str = 'return ' - if result == 'void': - return_str = '' - params, param_names, param_types = _ParamsInfo(method) - constantness = '' - if method.const: - constantness = ' const' - - # call_method callback - decl = indent + '%s %s(%s)%s {\n' % (result, method.name, params, constantness) - param_names_str = ', '.join(param_names) - if param_names_str: - param_names_str = ', ' + param_names_str - decl += indent*2 + '%s%scall_method<%s>(self, "%s"%s);\n' %\ - (return_str, python, result, rename, param_names_str) - decl += indent + '}\n' - - # default implementations (with overloading) - if not method.abstract: - minArgs = method.minArgs - maxArgs = method.maxArgs - impl_names = self.DefaultImplementationNames(method) - for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)): - params, param_names, param_types = _ParamsInfo(method, argNum) - decl += '\n' - decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness) - decl += indent*2 + '%s%s::%s(%s);\n' % \ - (return_str, self.class_.FullName(), method.name, ', '.join(param_names)) - decl += indent + '}\n' - return decl - - - def MethodDefinition(self, method): - '''Returns a list of lines, which should be put inside the class_ - statement to export this method.''' - # dont define abstract methods - if method.abstract: - return [] - pyste = namespaces.pyste - rename = self.info[method.name].rename or method.name - default_names = self.DefaultImplementationNames(method) - class_name = self.class_.FullName() - wrapper_name = pyste + self.wrapper_name - result = method.result.FullName() - is_method_unique = self.class_.IsUnique(method.name) - constantness = '' - if method.const: - constantness = ' const' - - # create a list of default-impl pointers - minArgs = method.minArgs - maxArgs = method.maxArgs - if is_method_unique: - default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names] - else: - default_pointers = [] - for impl_name, argNum in zip(default_names, range(minArgs, maxArgs+1)): - param_list = [x.FullName() for x in method.parameters[:argNum]] - params = ', '.join(param_list) - signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness) - default_pointer = '(%s)%s::%s' % (signature, wrapper_name, impl_name) - default_pointers.append(default_pointer) - - # get the pointer of the method - if is_method_unique: - pointer = '&' + method.FullName() - else: - pointer = method.PointerDeclaration() - - # generate the defs - definitions = [] - # basic def - definitions.append('.def("%s", %s, %s)' % (rename, pointer, default_pointers[-1])) - for default_pointer in default_pointers[:-1]: - definitions.append('.def("%s", %s)' % (rename, default_pointer)) - return definitions - - - def FullName(self): - return namespaces.pyste + self.wrapper_name - - - def VirtualMethods(self): - return [m for m in self.class_.members if type(m) == Method and m.virtual] - - - def Constructors(self): - return [m for m in self.class_.members if isinstance(m, Constructor)] - - - def GenerateDefinitions(self): - defs = [] - for method in self.VirtualMethods(): - if not self.info[method.name].exclude: - defs.extend(self.MethodDefinition(method)) - return defs - - - def GenerateVirtualWrapper(self, indent): - 'Return the wrapper for this class' - - # generate the class code - class_name = self.class_.FullName() - code = 'struct %s: %s\n' % (self.wrapper_name, class_name) - code += '{\n' - # generate constructors (with the overloads for each one) - for cons in self.Constructors(): - minArgs = cons.minArgs - maxArgs = cons.maxArgs - # from the min number of arguments to the max number, generate - # all version of the given constructor - cons_code = '' - for argNum in range(minArgs, maxArgs+1): - params, param_names, param_types = _ParamsInfo(cons, argNum) - if params: - params = ', ' + params - cons_code += indent + '%s(PyObject* self_%s):\n' % \ - (self.wrapper_name, params) - cons_code += indent*2 + '%s(%s), self(self_) {}\n\n' % \ - (class_name, ', '.join(param_names)) - code += cons_code - # generate the body - body = [] - for method in self.VirtualMethods(): - if not self.info[method.name].exclude: - body.append(self.Declaration(method, indent)) - body = '\n'.join(body) - code += body + '\n' - # add the self member - code += indent + 'PyObject* self;\n' - code += '};\n' - return code diff --git a/pyste/src/CodeUnit.py b/pyste/src/CodeUnit.py deleted file mode 100644 index ac123f99..00000000 --- a/pyste/src/CodeUnit.py +++ /dev/null @@ -1,78 +0,0 @@ -from settings import * - -#============================================================================== -# RemoveDuplicatedLines -#============================================================================== -def RemoveDuplicatedLines(text): - includes = text.splitlines() - d = dict([(include, 0) for include in includes]) - return '\n'.join(d.keys()) - - -#============================================================================== -# CodeUnit -#============================================================================== -class CodeUnit: - ''' - Represents a cpp file, where other objects can write in one of the - predefined sections. - The avaiable sections are: - include - The include area of the cpp file - declaration - The part before the module definition - module - Inside the BOOST_PYTHON_MODULE macro - ''' - - USING_BOOST_NS = True - - def __init__(self, modulename): - self.modulename = modulename - # define the avaiable sections - self.code = {} - self.code['include'] = '' - self.code['declaration'] = '' - self.code['module'] = '' - - - def Write(self, section, code): - 'write the given code in the section of the code unit' - if section not in self.code: - raise RuntimeError, 'Invalid CodeUnit section: %s' % section - self.code[section] += code - - - def Section(self, section): - return self.code[section] - - - def Save(self, filename): - 'Writes this code unit to the filename' - space = '\n\n' - fout = file(filename, 'w') - # includes - includes = RemoveDuplicatedLines(self.code['include']) - fout.write('\n' + self._leftEquals('Includes')) - fout.write('#include \n') - fout.write(includes) - fout.write(space) - # using - if self.USING_BOOST_NS: - fout.write(self._leftEquals('Using')) - fout.write('using namespace boost::python;\n\n') - # declarations - if self.code['declaration']: - pyste_namespace = namespaces.pyste[:-2] - fout.write(self._leftEquals('Declarations')) - fout.write('namespace %s {\n\n\n' % pyste_namespace) - fout.write(self.code['declaration']) - fout.write('\n\n}// namespace %s\n' % pyste_namespace) - fout.write(space) - # module - fout.write(self._leftEquals('Module')) - fout.write('BOOST_PYTHON_MODULE(%s)\n{\n' % self.modulename) - fout.write(self.code['module']) - fout.write('}\n') - - - def _leftEquals(self, s): - s = '// %s ' % s - return s + ('='*(80-len(s))) + '\n' diff --git a/pyste/src/CppParser.py b/pyste/src/CppParser.py deleted file mode 100644 index 2dd9c9ff..00000000 --- a/pyste/src/CppParser.py +++ /dev/null @@ -1,94 +0,0 @@ -from GCCXMLParser import ParseDeclarations -import tempfile -import shutil -import os -import os.path -import settings - -class CppParserError(Exception): pass - - -class CppParser: - 'Parses a header file and returns a list of declarations' - - def __init__(self, includes=None, defines=None): - 'includes and defines ar the directives given to gcc' - if includes is None: - includes = [] - if defines is None: - defines = [] - self.includes = includes - self.defines = defines - - - def _includeparams(self, filename): - includes = self.includes[:] - filedir = os.path.dirname(filename) - if not filedir: - filedir = '.' - includes.insert(0, filedir) - includes = ['-I "%s"' % x for x in includes] - return ' '.join(includes) - - - def _defineparams(self): - defines = ['-D "%s"' % x for x in self.defines] - return ' '.join(defines) - - - def FindFileName(self, include): - if os.path.isfile(include): - return include - for path in self.includes: - filename = os.path.join(path, include) - if os.path.isfile(filename): - return filename - name = os.path.basename(include) - raise RuntimeError, 'Header file "%s" not found!' % name - - - def parse(self, include, symbols=None, tail=None): - '''Parses the given filename, and returns (declaration, header). The - header returned is normally the same as the given to this method, - except if tail is not None: in this case, the header is copied to a temp - filename and the tail code is appended to it before being passed on to gcc. - This temp filename is then returned. - ''' - filename = self.FindFileName(include) - # copy file to temp folder, if needed - if tail: - tempfilename = tempfile.mktemp('.h') - infilename = tempfilename - shutil.copy(filename, infilename) - f = file(infilename, 'a') - f.write('\n\n'+tail) - f.close() - else: - infilename = filename - xmlfile = tempfile.mktemp('.xml') - try: - # get the params - includes = self._includeparams(filename) - defines = self._defineparams() - # call gccxml - cmd = 'gccxml %s %s %s -fxml=%s' \ - % (includes, defines, infilename, xmlfile) - if symbols: - cmd += ' -fxml-start=' + ','.join(symbols) - status = os.system(cmd) - if status != 0 or not os.path.isfile(xmlfile): - raise CppParserError, 'Error executing gccxml' - # parse the resulting xml - declarations = ParseDeclarations(xmlfile) - # return the declarations - return declarations, infilename - finally: - if settings.DEBUG and os.path.isfile(xmlfile): - filename = os.path.basename(include) - shutil.copy(xmlfile, os.path.splitext(filename)[0] + '.xml') - # delete the temporary files - try: - os.remove(xmlfile) - if tail: - os.remove(tempfilename) - except OSError: pass diff --git a/pyste/src/EnumExporter.py b/pyste/src/EnumExporter.py deleted file mode 100644 index fda4d721..00000000 --- a/pyste/src/EnumExporter.py +++ /dev/null @@ -1,30 +0,0 @@ -from Exporter import Exporter -from settings import * - -#============================================================================== -# EnumExporter -#============================================================================== -class EnumExporter(Exporter): - 'Exports enumerators' - - def __init__(self, info): - Exporter.__init__(self, info) - - - def SetDeclarations(self, declarations): - Exporter.SetDeclarations(self, declarations) - self.enum = self.GetDeclaration(self.info.name) - - - def Export(self, codeunit, expoted_names): - indent = self.INDENT - in_indent = self.INDENT*2 - rename = self.info.rename or self.enum.name - full_name = self.enum.FullName() - code = indent + namespaces.python + 'enum_< %s >("%s")\n' % (full_name, rename) - for name in self.enum.values: - rename = self.info[name].rename or name - value_fullname = self.enum.ValueFullName(name) - code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname) - code += indent + ';\n\n' - codeunit.Write('module', code) diff --git a/pyste/src/Exporter.py b/pyste/src/Exporter.py deleted file mode 100644 index 02259582..00000000 --- a/pyste/src/Exporter.py +++ /dev/null @@ -1,69 +0,0 @@ -import os.path - -#============================================================================== -# Exporter -#============================================================================== -class Exporter: - 'Base class for objects capable to generate boost.python code.' - - INDENT = ' ' * 4 - - def __init__(self, info, parser_tail=None): - self.info = info - self.parser_tail = parser_tail - - - def Parse(self, parser): - self.parser = parser - header = self.info.include - tail = self.parser_tail - declarations, parser_header = parser.parse(header, tail=tail) - self.parser_header = parser_header - self.SetDeclarations(declarations) - - - def SetDeclarations(self, declarations): - self.declarations = declarations - - - def GenerateCode(self, codeunit, exported_names): - self.WriteInclude(codeunit) - self.Export(codeunit, exported_names) - - - def WriteInclude(self, codeunit): - codeunit.Write('include', '#include <%s>\n' % self.info.include) - - - def Export(self, codeunit, exported_names): - 'subclasses must override this to do the real work' - pass - - - def Name(self): - '''Returns the name of this Exporter. The name will be added to the - list of names exported, which may have a use for other exporters. - ''' - return None - - - def GetDeclarations(self, fullname): - decls = [x for x in self.declarations if x.FullName() == fullname] - if not decls: - raise RuntimeError, 'no %s declaration found!' % fullname - return decls - - - def GetDeclaration(self, fullname): - decls = self.GetDeclarations(fullname) - assert len(decls) == 1 - return decls[0] - - - def Order(self): - '''Returns a number that indicates to which order this exporter - belongs. The exporters will be called from the lowest order to the - highest order. - This function will only be called after Parse has been called. - ''' - return None # don't care diff --git a/pyste/src/FunctionExporter.py b/pyste/src/FunctionExporter.py deleted file mode 100644 index 60735ca0..00000000 --- a/pyste/src/FunctionExporter.py +++ /dev/null @@ -1,85 +0,0 @@ -from Exporter import Exporter -from policies import * -from declarations import * -from settings import * - - -class FunctionExporter(Exporter): - 'Generates boost.python code to export the given function.' - - def __init__(self, info, tail=None): - Exporter.__init__(self, info, tail) - - - def Export(self, codeunit, exported_names): - decls = self.GetDeclarations(self.info.name) - for decl in decls: - self.CheckPolicy(decl) - self.ExportDeclaration(decl, len(decls) == 1, codeunit) - self.GenerateOverloads(decls, codeunit) - - - def Name(self): - return self.info.name - - - def CheckPolicy(self, func): - 'Warns the user if this function needs a policy' - def IsString(type): - return type.const and type.name == 'char' and isinstance(type, PointerType) - needs_policy = isinstance(func.result, (ReferenceType, PointerType)) - if IsString(func.result): - needs_policy = False - if needs_policy and self.info.policy is None: - print '---> Error: Function "%s" needs a policy.' % func.FullName() - print - - def ExportDeclaration(self, decl, unique, codeunit): - name = self.info.rename or decl.name - defs = namespaces.python + 'def("%s", ' % name - wrapper = self.info.wrapper - if wrapper: - pointer = '&' + wrapper.FullName() - elif not unique: - pointer = decl.PointerDeclaration() - else: - pointer = '&' + decl.FullName() - defs += pointer - defs += self.PolicyCode() - overload = self.OverloadName(decl) - if overload: - defs += ', %s()' % (namespaces.pyste + overload) - defs += ');' - codeunit.Write('module', self.INDENT + defs + '\n') - # add the code of the wrapper - if wrapper and wrapper.code: - codeunit.Write('declaration', code + '\n') - - - def OverloadName(self, decl): - if decl.minArgs != decl.maxArgs: - return '%s_overloads_%i_%i' % \ - (decl.name, decl.minArgs, decl.maxArgs) - else: - return '' - - - def GenerateOverloads(self, declarations, codeunit): - codes = {} - for decl in declarations: - overload = self.OverloadName(decl) - if overload and overload not in codes: - code = 'BOOST_PYTHON_FUNCTION_OVERLOADS(%s, %s, %i, %i)' %\ - (overload, decl.FullName(), decl.minArgs, decl.maxArgs) - codeunit.Write('declaration', code + '\n') - codes[overload] = None - - - def PolicyCode(self): - policy = self.info.policy - if policy is not None: - assert isinstance(policy, Policy) - return ', %s()' % policy.Code() - else: - return '' - diff --git a/pyste/src/GCCXMLParser.py b/pyste/src/GCCXMLParser.py deleted file mode 100644 index 937db92f..00000000 --- a/pyste/src/GCCXMLParser.py +++ /dev/null @@ -1,395 +0,0 @@ -from declarations import * -from elementtree.ElementTree import ElementTree -from xml.parsers.expat import ExpatError -from copy import deepcopy - - -class InvalidXMLError(Exception): pass - -class ParserError(Exception): pass - -class InvalidContextError(ParserError): pass - - -class GCCXMLParser(object): - 'Parse a GCC_XML file and extract the top-level declarations.' - - interested_tags = {'Class':0, 'Function':0, 'Variable':0, 'Enumeration':0} - - def Parse(self, filename): - self.elements = self.GetElementsFromXML(filename) - # high level declarations - self.declarations = [] - # parse the elements - for id in self.elements: - element, decl = self.elements[id] - if decl is None: - try: - self.ParseElement(id, element) - except InvalidContextError: - pass # ignore those nodes with invalid context - # (workaround gccxml bug) - - - def Declarations(self): - return self.declarations - - - def AddDecl(self, decl): - self.declarations.append(decl) - - - def ParseElement(self, id, element): - method = 'Parse' + element.tag - if hasattr(self, method): - func = getattr(self, method) - func(id, element) - - - def GetElementsFromXML(self,filename): - 'Extracts a dictionary of elements from the gcc_xml file.' - - tree = ElementTree() - try: - tree.parse(filename) - except ExpatError: - raise InvalidXMLError, 'Not a XML file: %s' % filename - - root = tree.getroot() - if root.tag != 'GCC_XML': - raise InvalidXMLError, 'Not a valid GCC_XML file' - - # build a dictionary of id -> element, None - elementlist = root.getchildren() - elements = {} - for element in elementlist: - id = element.get('id') - if id: - elements[id] = element, None - return elements - - - def GetDecl(self, id): - if id not in self.elements: - if id == '_0': - raise InvalidContextError, 'Invalid context found in the xml file.' - else: - msg = 'ID not found in elements: %s' % id - raise ParserError, msg - - elem, decl = self.elements[id] - if decl is None: - self.ParseElement(id, elem) - elem, decl = self.elements[id] - if decl is None: - raise ParserError, 'Could not parse element: %s' % elem.tag - return decl - - - def GetType(self, id): - const = False - volatile = False - if id[-1] == 'v': - volatile = True - id = id[:-1] - if id[-1] == 'c': - const = True - id = id[:-1] - decl = self.GetDecl(id) - if isinstance(decl, Type): - res = deepcopy(decl) - if const: - res.const = const - if volatile: - res.volatile = volatile - else: - res = Type(decl.FullName(), const) - res.volatile = volatile - return res - - - def GetLocation(self, location): - file, line = location.split(':') - file = self.GetDecl(file) - return file, int(line) - - - def Update(self, id, decl): - element, _ = self.elements[id] - self.elements[id] = element, decl - - - def ParseNamespace(self, id, element): - namespace = element.get('name') - context = element.get('context') - if context: - outerns = self.GetDecl(context) - if not outerns.endswith('::'): - outerns += '::' - namespace = outerns + namespace - if namespace.startswith('::'): - namespace = namespace[2:] - self.Update(id, namespace) - - - def ParseFile(self, id, element): - filename = element.get('name') - self.Update(id, filename) - - - def ParseVariable(self, id, element): - # in gcc_xml, a static Field is declared as a Variable, so we check - # this and call the Field parser if apply. - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - self.ParseField(id, element) - elem, decl = self.elements[id] - decl.static = True - else: - namespace = context - name = element.get('name') - type_ = self.GetType(element.get('type')) - location = self.GetLocation(element.get('location')) - variable = Variable(type_, name, namespace) - variable.location = location - self.AddDecl(variable) - self.Update(id, variable) - - - def GetArguments(self, element): - args = [] - for child in element: - if child.tag == 'Argument': - type_ = self.GetType(child.get('type')) - type_.default = child.get('default') - args.append(type_) - return args - - - def ParseFunction(self, id, element, functionType=Function): - '''functionType is used because a Operator is identical to a normal - function, only the type of the function changes.''' - name = element.get('name') - returns = self.GetType(element.get('returns')) - namespace = self.GetDecl(element.get('context')) - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - function = functionType(name, namespace, returns, params) - function.location = location - self.AddDecl(function) - self.Update(id, function) - - - def ParseOperatorFunction(self, id, element): - self.ParseFunction(id, element, Operator) - - - def GetBases(self, bases): - 'Parses the string "bases" from the xml into a list of Base instances.' - - if bases is None: - return [] - bases = bases.split() - baseobjs = [] - for base in bases: - # get the visibility - split = base.split(':') - if len(split) == 2: - visib = split[0] - base = split[1] - else: - visib = Scope.public - decl = self.GetDecl(base) - baseobj = Base(decl.FullName(), visib) - baseobjs.append(baseobj) - return baseobjs - - - def GetMembers(self, members): - # members must be a string with the ids of the members - if members is None: - return [] - memberobjs = [] - for member in members.split(): - memberobjs.append(self.GetDecl(member)) - return memberobjs - - - def ParseClass(self, id, element): - name = element.get('name') - abstract = bool(int(element.get('abstract', '0'))) - bases = self.GetBases(element.get('bases')) - location = self.GetLocation(element.get('location')) - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): # a nested class - visib = element.get('access', Scope.public) - class_ = NestedClass( - name, context.FullName(), visib, [], abstract, bases) - else: - assert isinstance(context, str) - class_ = Class(name, context, [], abstract, bases) - self.AddDecl(class_) - # we have to add the declaration of the class before trying - # to parse its members, to avoid recursion. - class_.location = location - self.Update(id, class_) - # now we can get the members - class_.members = self.GetMembers(element.get('members')) - - - def ParseStruct(self, id, element): - self.ParseClass(id, element) - - - def ParseFundamentalType(self, id, element): - name = element.get('name') - type_ = FundamentalType(name) - self.Update(id, type_) - - - def ParseArrayType(self, id, element): - type_ = self.GetType(element.get('type')) - min = element.get('min') - max = element.get('max') - if min: - min = int(min) - if max: - max = int(max) - array = ArrayType(type_.name, min, max, type_.const) - self.Update(id, array) - - - def ParseReferenceType(self, id, element): - type_ = self.GetType(element.get('type')) - expand = not isinstance(type_, FunctionType) - ref = ReferenceType(type_.name, type_.const, None, expand) - self.Update(id, ref) - - - def ParsePointerType(self, id, element): - type_ = self.GetType(element.get('type')) - expand = not isinstance(type_, FunctionType) - ref = PointerType(type_.name, type_.const, None, expand) - self.Update(id, ref) - - - def ParseFunctionType(self, id, element): - result = self.GetType(element.get('returns')) - args = self.GetArguments(element) - func = FunctionType(result, args) - self.Update(id, func) - - - def ParseMethodType(self, id, element): - class_ = self.GetDecl(element.get('basetype')).FullName() - result = self.GetType(element.get('returns')) - args = self.GetArguments(element) - method = MethodType(result, args, class_) - self.Update(id, method) - - - def ParseField(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - type_ = self.GetType(element.get('type')) - static = bool(int(element.get('extern', '0'))) - location = self.GetLocation(element.get('location')) - var = ClassVariable(type_, name, classname, visib, static) - var.location = location - self.Update(id, var) - - - def ParseMethod(self, id, element, methodType=Method): - name = element.get('name') - result = self.GetType(element.get('returns')) - classname = self.GetDecl(element.get('context')).FullName() - visib = element.get('access', Scope.public) - static = bool(int(element.get('static', '0'))) - virtual = bool(int(element.get('virtual', '0'))) - abstract = bool(int(element.get('pure_virtual', '0'))) - const = bool(int(element.get('const', '0'))) - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - method = methodType( - name, classname, result, params, visib, virtual, abstract, static, const) - method.location = location - self.Update(id, method) - - - def ParseOperatorMethod(self, id, element): - self.ParseMethod(id, element, ClassOperator) - - - def ParseConstructor(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - ctor = Constructor(name, classname, params, visib) - ctor.location = location - self.Update(id, ctor) - - - def ParseDestructor(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - virtual = bool(int(element.get('virtual', '0'))) - location = self.GetLocation(element.get('location')) - des = Destructor(name, classname, visib, virtual) - des.location = location - self.Update(id, des) - - - def ParseConverter(self, id, element): - self.ParseMethod(id, element, ConverterOperator) - - - def ParseTypedef(self, id, element): - name = element.get('name') - type = self.GetDecl(element.get('type')) - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - context = context.FullName() - typedef = Typedef(type, name, context) - self.Update(id, typedef) - self.AddDecl(typedef) - - - def ParseEnumeration(self, id, element): - name = element.get('name') - location = self.GetLocation(element.get('location')) - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - visib = element.get('access', Scope.public) - enum = ClassEnumeration(name, context.FullName(), visib) - else: - enum = Enumeration(name, context) - self.AddDecl(enum) # in this case, is a top level decl - enum.location = location - for child in element: - if child.tag == 'EnumValue': - name = child.get('name') - value = int(child.get('init')) - enum.values[name] = value - self.Update(id, enum) - - - def ParseUnimplemented(self, id, element): - 'No idea of what this is' - self.Update(id, Declaration('', '')) - - - def ParseUnion(self, id, element): - self.Update(id, Declaration(element.get('name'), '')) - - - -def ParseDeclarations(filename): - 'Returns a list of the top declarations found in the gcc_xml file.' - - parser = GCCXMLParser() - parser.Parse(filename) - return parser.Declarations() diff --git a/pyste/src/HeaderExporter.py b/pyste/src/HeaderExporter.py deleted file mode 100644 index 9234e8af..00000000 --- a/pyste/src/HeaderExporter.py +++ /dev/null @@ -1,67 +0,0 @@ -from Exporter import Exporter -from ClassExporter import ClassExporter -from FunctionExporter import FunctionExporter -from EnumExporter import EnumExporter -from infos import * -from declarations import * -import os.path -import exporters - -#============================================================================== -# HeaderExporter -#============================================================================== -class HeaderExporter(Exporter): - 'Exports all declarations found in the given header' - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - - - def WriteInclude(self, codeunit): - pass - - - def SetDeclarations(self, declarations): - def IsInternalName(name): - '''Returns true if the given name looks like a internal compiler - structure''' - return name.startswith('__') - - Exporter.SetDeclarations(self, declarations) - header = os.path.normpath(self.parser_header) - for decl in declarations: - # check if this declaration is in the header - location = os.path.normpath(decl.location[0]) - if location != header or IsInternalName(decl.name): - continue - # ok, check the type of the declaration and export it accordingly - self.HandleDeclaration(decl) - - - def HandleDeclaration(self, decl): - '''Dispatch the declaration to the appropriate method, that must create - a suitable info object for a Exporter, create a Exporter, set its - declarations and append it to the list of exporters. - ''' - dispatch_table = { - Class : ClassExporter, - Enumeration : EnumExporter, - Function : FunctionExporter, - } - - for decl_type, exporter_type in dispatch_table.items(): - if type(decl) == decl_type: - self.HandleExporter(decl, exporter_type) - break - - - def HandleExporter(self, decl, exporter_type): - info = self.info[decl.name] - info.name = decl.FullName() - info.include = self.info.include - exporter = exporter_type(info) - exporter.SetDeclarations(self.declarations) - exporters.exporters.append(exporter) - - - diff --git a/pyste/src/IncludeExporter.py b/pyste/src/IncludeExporter.py deleted file mode 100644 index 2a7b0602..00000000 --- a/pyste/src/IncludeExporter.py +++ /dev/null @@ -1,19 +0,0 @@ -import os.path -from Exporter import Exporter - -#============================================================================== -# IncludeExporter -#============================================================================== -class IncludeExporter(Exporter): - '''Writes an include declaration to the module. Useful to add extra code - for use in the Wrappers. - This class just reimplements the Parse method to do nothing: the - WriteInclude in Exporter already does the work for us. - ''' - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - - def Parse(self, parser): - pass - diff --git a/pyste/src/declarations.py b/pyste/src/declarations.py deleted file mode 100644 index adba6fd3..00000000 --- a/pyste/src/declarations.py +++ /dev/null @@ -1,452 +0,0 @@ -''' -Module declarations - - Defines classes that represent declarations found in C++ header files. - -''' - -class Declaration(object): - 'Represents a basic declaration.' - - def __init__(self, name, namespace): - # the declaration name - self.name = name - # all the namespaces, separated by '::' = 'boost::inner' - self.namespace = namespace - # tuple (filename, line) - self.location = '', -1 - - - def FullName(self): - 'Returns the full qualified name: "boost::inner::Test"' - namespace = self.namespace or '' - #if not namespace: - # namespace = '' - if namespace and not namespace.endswith('::'): - namespace += '::' - return namespace + self.name - - - def __repr__(self): - return '' % (self.FullName(), id(self)) - - - def __str__(self): - return 'Declaration of %s' % self.FullName() - - - -class Class(Declaration): - 'The declaration of a class or struct.' - - def __init__(self, name, namespace, members, abstract, bases): - Declaration.__init__(self, name, namespace) - # list of members - self.members = members - # whatever the class has any abstract methods - self.abstract = abstract - # instances of Base - self.bases = bases - self._members_count = {} - - - def __iter__(self): - return iter(self.members) - - - def IsAbstract(self): - 'Returns True if any method of this class is abstract' - for member in self.members: - if isinstance(member, Method): - if member.abstract: - return True - return False - - - def RawName(self): - 'Returns the raw name of a template class. name = Foo, raw = Foo' - lesspos = self.name.find('<') - if lesspos != -1: - return self.name[:lesspos] - else: - return self.name - - - def Constructors(self, publics_only=True): - constructors = [] - for member in self: - if isinstance(member, Constructor): - if publics_only and member.visibility != Scope.public: - continue - constructors.append(member) - return constructors - - - def HasCopyConstructor(self): - for cons in self.Constructors(): - if cons.IsCopy(): - return True - return False - - - def HasDefaultConstructor(self): - for cons in self.Constructors(): - if cons.IsDefault(): - return True - return False - - - def IsUnique(self, member_name): - if not self._members_count: - for m in self: - self._members_count[m.name] = self._members_count.get(m.name, 0) + 1 - try: - return self._members_count[member_name] == 1 - except KeyError: - print self._members_count - print 'Key', member_name - - - -class NestedClass(Class): - 'The declaration of a class/struct inside another class/struct.' - - def __init__(self, name, class_, visib, members, abstract, bases): - Class.__init__(self, name, None, members, abstract, bases) - self.class_ = class_ - self.visibility = visib - - - def FullName(self): - return '%s::%s' % (self.class_, self.name) - - - -class Base: - 'Represents a base class of another class.' - - def __init__(self, name, visibility=None): - # class_ is the full name of the base class - self.name = name - # visibility of the derivation - if visibility is None: - visibility = Scope.public - self.visibility = visibility - - - -class Scope: - public = 'public' - private = 'private' - protected = 'protected' - - - -class Function(Declaration): - 'The declaration of a function.' - - def __init__(self, name, namespace, result, params): - Declaration.__init__(self, name, namespace) - # the result type: instance of Type, or None (constructors) - self.result = result - # the parameters: instances of Type - self.parameters = params - - - def PointerDeclaration(self): - 'returns a declaration of a pointer to this function' - result = self.result.FullName() - params = ', '.join([x.FullName() for x in self.parameters]) - return '(%s (*)(%s))%s' % (result, params, self.FullName()) - - - def _MinArgs(self): - min = 0 - for arg in self.parameters: - if arg.default is None: - min += 1 - return min - - minArgs = property(_MinArgs) - - - def _MaxArgs(self): - return len(self.parameters) - - maxArgs = property(_MaxArgs) - - - -class Operator(Function): - 'The declaration of a custom operator.' - def FullName(self): - namespace = self.namespace or '' - if not namespace.endswith('::'): - namespace += '::' - return namespace + 'operator' + self.name - - - -class Method(Function): - 'The declaration of a method.' - - def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const): - Function.__init__(self, name, None, result, params) - self.visibility = visib - self.virtual = virtual - self.abstract = abstract - self.static = static - self.class_ = class_ - self.const = const - - - def FullName(self): - return self.class_ + '::' + self.name - - - def PointerDeclaration(self): - 'returns a declaration of a pointer to this function' - result = self.result.FullName() - params = ', '.join([x.FullName() for x in self.parameters]) - const = '' - if self.const: - const = 'const' - return '(%s (%s::*)(%s) %s)%s' %\ - (result, self.class_, params, const, self.FullName()) - - -class Constructor(Method): - 'A constructor of a class.' - - def __init__(self, name, class_, params, visib): - Method.__init__(self, name, class_, None, params, visib, False, False, False, False) - - - def IsDefault(self): - return len(self.parameters) == 0 - - - def IsCopy(self): - if len(self.parameters) != 1: - return False - param = self.parameters[0] - class_as_param = self.parameters[0].name == self.class_ - param_reference = isinstance(param, ReferenceType) - return param_reference and class_as_param and param.const - - -class Destructor(Method): - 'The destructor of a class.' - - def __init__(self, name, class_, visib, virtual): - Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False) - - def FullName(self): - return self.class_ + '::~' + self.name - - - -class ClassOperator(Method): - 'The declaration of a custom operator in a class.' - - def FullName(self): - return self.class_ + '::operator ' + self.name - - - -class ConverterOperator(ClassOperator): - 'An operator in the form "operator OtherClass()".' - - def FullName(self): - return self.class_ + '::operator ' + self.result.name - - - -class Type(Declaration): - 'Represents a type.' - - def __init__(self, name, const=False, default=None): - Declaration.__init__(self, name, None) - # whatever the type is constant or not - self.const = const - # used when the Type is a function argument - self.default = default - self.volatile = False - - def __repr__(self): - if self.const: - const = 'const ' - else: - const = '' - return '' - - - def FullName(self): - if self.const: - const = 'const ' - else: - const = '' - return const + self.name - - - -class ArrayType(Type): - 'Represents an array.' - - def __init__(self, name, min, max, const=False): - 'min and max can be None.' - Type.__init__(self, name, const) - self.min = min - self.max = max - - - -class ReferenceType(Type): - 'A reference type.' - - def __init__(self, name, const=False, default=None, expandRef=True): - Type.__init__(self, name, const, default) - self.expand = expandRef - - - def FullName(self): - 'expand is False for function pointers' - expand = ' &' - if not self.expand: - expand = '' - return Type.FullName(self) + expand - - - -class PointerType(Type): - 'A pointer type.' - - def __init__(self, name, const=False, default=None, expandPointer=False): - Type.__init__(self, name, const, default) - self.expand = expandPointer - - - def FullName(self): - 'expand is False for function pointer' - expand = ' *' - if not self.expand: - expand = '' - return Type.FullName(self) + expand - - - -class FundamentalType(Type): - 'One of the fundamental types (int, void...).' - - def __init__(self, name, const=False): - Type.__init__(self, name, const) - - - -class FunctionType(Type): - 'A pointer to a function.' - - def __init__(self, result, params): - Type.__init__(self, '', False) - self.result = result - self.parameters = params - self.name = self.FullName() - - - def FullName(self): - full = '%s (*)' % self.result.FullName() - params = [x.FullName() for x in self.parameters] - full += '(%s)' % ', '.join(params) - return full - - - -class MethodType(FunctionType): - 'A pointer to a member function of a class.' - - def __init__(self, result, params, class_): - Type.__init__(self, '', False) - self.result = result - self.parameters = params - self.class_ = class_ - self.name = self.FullName() - - def FullName(self): - full = '%s (%s::*)' % (self.result.FullName(), self.class_) - params = [x.FullName() for x in self.parameters] - full += '(%s)' % ', '.join(params) - return full - - - -class Variable(Declaration): - 'Represents a global variable.' - - def __init__(self, type, name, namespace): - Declaration.__init__(self, name, namespace) - # instance of Type - self.type = type - - - -class ClassVariable(Variable): - 'Represents a class variable.' - - def __init__(self, type, name, class_, visib, static): - Variable.__init__(self, type, name, None) - self.visibility = visib - self.static = static - self.class_ = class_ - - - def FullName(self): - return self.class_ + '::' + self.name - - - -class Enumeration(Declaration): - - def __init__(self, name, namespace): - Declaration.__init__(self, name, namespace) - self.values = {} # dict of str => int - - def ValueFullName(self, name): - assert name in self.values - namespace = self.namespace - if namespace: - namespace += '::' - return namespace + name - - - -class ClassEnumeration(Enumeration): - - def __init__(self, name, class_, visib): - Enumeration.__init__(self, name, None) - self.class_ = class_ - self.visibility = visib - - - def FullName(self): - return '%s::%s' % (self.class_, self.name) - - - def ValueFullName(self, name): - assert name in self.values - return '%s::%s' % (self.class_, name) - - - -class Typedef(Declaration): - - def __init__(self, type, name, namespace): - Declaration.__init__(self, name, namespace) - self.type = type - self.visibility = Scope.public - - - - - - - diff --git a/pyste/src/enumerate.py b/pyste/src/enumerate.py deleted file mode 100644 index 099e42ba..00000000 --- a/pyste/src/enumerate.py +++ /dev/null @@ -1,7 +0,0 @@ -from __future__ import generators - -def enumerate(seq): - i = 0 - for x in seq: - yield i, x - i += 1 diff --git a/pyste/src/exporters.py b/pyste/src/exporters.py deleted file mode 100644 index 65536780..00000000 --- a/pyste/src/exporters.py +++ /dev/null @@ -1,3 +0,0 @@ - -# a list of Exporter instances -exporters = [] diff --git a/pyste/src/exporterutils.py b/pyste/src/exporterutils.py deleted file mode 100644 index 5134a1e5..00000000 --- a/pyste/src/exporterutils.py +++ /dev/null @@ -1,26 +0,0 @@ -''' -Various helpers for interface files. -''' - -from settings import * - -#============================================================================== -# FunctionWrapper -#============================================================================== -class FunctionWrapper(object): - '''Holds information about a wrapper for a function or a method. It is in 2 - parts: the name of the Wrapper, and its code. The code is placed in the - declaration section of the module, while the name is used to def' the - function or method (with the pyste namespace prepend to it). If code is None, - the name is left unchanged. - ''' - - def __init__(self, name, code=None): - self.name = name - self.code = code - - def FullName(self): - if self.code: - return namespaces.pyste + self.name - else: - return self.name diff --git a/pyste/src/infos.py b/pyste/src/infos.py deleted file mode 100644 index ce8334c5..00000000 --- a/pyste/src/infos.py +++ /dev/null @@ -1,187 +0,0 @@ -import os.path -import copy -import exporters -from ClassExporter import ClassExporter -from FunctionExporter import FunctionExporter -from IncludeExporter import IncludeExporter -from EnumExporter import EnumExporter -from HeaderExporter import HeaderExporter -from exporterutils import FunctionWrapper - - -#============================================================================== -# DeclarationInfo -#============================================================================== -class DeclarationInfo: - - def __init__(self, otherInfo=None): - self.__infos = {} - self.__attributes = {} - if otherInfo is not None: - self.__infos = copy.deepcopy(otherInfo.__infos) - self.__attributes = copy.deepcopy(otherInfo.__attributes) - - - def __getitem__(self, name): - 'Used to access sub-infos' - if name.startswith('__'): - raise AttributeError - default = DeclarationInfo() - default._Attribute('name', name) - return self.__infos.setdefault(name, default) - - - def __getattr__(self, name): - return self[name] - - - def _Attribute(self, name, value=None): - if value is None: - # get value - return self.__attributes.get(name) - else: - # set value - self.__attributes[name] = value - - -#============================================================================== -# FunctionInfo -#============================================================================== -class FunctionInfo(DeclarationInfo): - - def __init__(self, name, include, tail=None, otherOption=None): - DeclarationInfo.__init__(self, otherOption) - self._Attribute('name', name) - self._Attribute('include', include) - # create a FunctionExporter - exporter = FunctionExporter(InfoWrapper(self), tail) - exporters.exporters.append(exporter) - - -#============================================================================== -# ClassInfo -#============================================================================== -class ClassInfo(DeclarationInfo): - - def __init__(self, name, include, tail=None, otherInfo=None): - DeclarationInfo.__init__(self, otherInfo) - self._Attribute('name', name) - self._Attribute('include', include) - # create a ClassExporter - exporter = ClassExporter(InfoWrapper(self), tail) - exporters.exporters.append(exporter) - - -#============================================================================== -# IncludeInfo -#============================================================================== -class IncludeInfo(DeclarationInfo): - - def __init__(self, include): - DeclarationInfo.__init__(self) - self._Attribute('include', include) - exporter = IncludeExporter(InfoWrapper(self)) - exporters.exporters.append(exporter) - - -#============================================================================== -# templates -#============================================================================== -def GenerateName(name, type_list): - name = name.replace('::', '_') - names = [name] + type_list - return '_'.join(names) - - -class ClassTemplateInfo(DeclarationInfo): - - def __init__(self, name, include): - DeclarationInfo.__init__(self) - self._Attribute('name', name) - self._Attribute('include', include) - - - def Instantiate(self, type_list, rename=None): - if not rename: - rename = GenerateName(self._Attribute('name'), type_list) - # generate code to instantiate the template - types = ', '.join(type_list) - tail = 'typedef %s< %s > %s;\n' % (self._Attribute('name'), types, rename) - tail += 'void __instantiate_%s()\n' % rename - tail += '{ sizeof(%s); }\n\n' % rename - # create a ClassInfo - class_ = ClassInfo(rename, self._Attribute('include'), tail, self) - return class_ - - - def __call__(self, types, rename=None): - if isinstance(types, str): - types = types.split() - return self.Instantiate(types, rename) - -#============================================================================== -# EnumInfo -#============================================================================== -class EnumInfo(DeclarationInfo): - - def __init__(self, name, include): - DeclarationInfo.__init__(self) - self._Attribute('name', name) - self._Attribute('include', include) - exporter = EnumExporter(InfoWrapper(self)) - exporters.exporters.append(exporter) - - -#============================================================================== -# HeaderInfo -#============================================================================== -class HeaderInfo(DeclarationInfo): - - def __init__(self, include): - DeclarationInfo.__init__(self) - self._Attribute('include', include) - exporter = HeaderExporter(InfoWrapper(self)) - exporters.exporters.append(exporter) - - -#============================================================================== -# InfoWrapper -#============================================================================== -class InfoWrapper: - 'Provides a nicer interface for a info' - - def __init__(self, info): - self.__dict__['_info'] = info # so __setattr__ is not called - - def __getitem__(self, name): - return InfoWrapper(self._info[name]) - - def __getattr__(self, name): - return self._info._Attribute(name) - - def __setattr__(self, name, value): - self._info._Attribute(name, value) - - -#============================================================================== -# Functions -#============================================================================== -def exclude(option): - option._Attribute('exclude', True) - -def set_policy(option, policy): - option._Attribute('policy', policy) - -def rename(option, name): - option._Attribute('rename', name) - -def set_wrapper(option, wrapper): - if isinstance(wrapper, str): - wrapper = FunctionWrapper(wrapper) - option._Attribute('wrapper', wrapper) - -def instantiate(template, types, rename=None): - if isinstance(types, str): - types = types.split() - return template.Instantiate(types, rename) - diff --git a/pyste/src/policies.py b/pyste/src/policies.py deleted file mode 100644 index 977e7f92..00000000 --- a/pyste/src/policies.py +++ /dev/null @@ -1,75 +0,0 @@ - - -class Policy: - 'Represents one of the call policies of boost.python.' - - def __init__(self): - raise RuntimeError, "Can't create an instance of the class Policy" - - - def Code(self): - 'Returns the string corresponding to a instancialization of the policy.' - pass - - - def _next(self): - if self.next is not None: - return ', %s >' % self.next.Code() - else: - return ' >' - - - -class return_internal_reference(Policy): - 'Ties the return value to one of the parameters.' - - def __init__(self, param=1, next=None): - ''' - param is the position of the parameter, or None for "self". - next indicates the next policy, or None. - ''' - self.param = param - self.next=next - - - def Code(self): - c = 'return_internal_reference< %i' % self.param - c += self._next() - return c - - - -class with_custodian_and_ward(Policy): - 'Ties lifetime of two arguments of a function.' - - def __init__(self, custodian, ward, next=None): - self.custodian = custodian - self.ward = ward - self.next = next - - def Code(self): - c = 'with_custodian_and_ward< %i, %i' % (self.custodian, self.ward) - c += self._next() - return c - - - -class return_value_policy(Policy): - 'Policy to convert return values.' - - def __init__(self, which, next=None): - self.which = which - self.next = next - - - def Code(self): - c = 'return_value_policy< %s' % self.which - c += self._next() - return c - - -# values for return_value_policy -reference_existing_object = 'reference_existing_object' -copy_const_reference = 'copy_const_reference' -copy_non_const_reference = 'copy_non_const_reference' -manage_new_object = 'manage_new_object' diff --git a/pyste/src/pyste-profile.py b/pyste/src/pyste-profile.py deleted file mode 100644 index d7afff45..00000000 --- a/pyste/src/pyste-profile.py +++ /dev/null @@ -1,17 +0,0 @@ -import profile -import pstats -import pyste - -import psyco -import elementtree.XMLTreeBuilder as XMLTreeBuilder -import GCCXMLParser - - -if __name__ == '__main__': - #psyco.bind(XMLTreeBuilder.fixtext) - #psyco.bind(XMLTreeBuilder.fixname) - #psyco.bind(XMLTreeBuilder.TreeBuilder) - #psyco.bind(GCCXMLParser.GCCXMLParser) - profile.run('pyste.Main()', 'profile') - p = pstats.Stats('profile') - p.strip_dirs().sort_stats(-1).print_stats() diff --git a/pyste/src/pyste.py b/pyste/src/pyste.py deleted file mode 100644 index 090c7fd9..00000000 --- a/pyste/src/pyste.py +++ /dev/null @@ -1,154 +0,0 @@ -''' -Usage: - pyste [options] --module= interface-files - -where options are: - -I add an include path - -D define symbol - --no-using do not declare "using namespace boost"; - use explicit declarations instead - --pyste-ns= set the namespace where new types will be declared; - default is "pyste" -''' - -import sys -import os -import getopt -import exporters -import CodeUnit -import infos -import exporterutils -import settings -from policies import * -from CppParser import CppParser, CppParserError -from Exporter import Exporter -from FunctionExporter import FunctionExporter -from ClassExporter import ClassExporter -from IncludeExporter import IncludeExporter -from HeaderExporter import HeaderExporter - - -def GetDefaultIncludes(): - if 'INCLUDE' in os.environ: - include = os.environ['INCLUDE'] - return include.split(os.pathsep) - else: - return [] - - -def ParseArguments(): - - def Usage(): - print __doc__ - sys.exit(1) - - options, files = getopt.getopt(sys.argv[1:], 'I:D:', ['module=', 'out=', 'no-using', 'pyste-ns=', 'debug']) - includes = GetDefaultIncludes() - defines = [] - module = None - out = None - for opt, value in options: - if opt == '-I': - includes.append(value) - elif opt == '-D': - defines.append(value) - elif opt == '--module': - module = value - elif opt == '--out': - out = value - elif opt == '--no-using': - settings.namespaces.python = 'boost::python::' - CodeUnit.CodeUnit.USING_BOOST_NS = False - elif opt == '--pyste-ns': - settings.namespaces.pyste = value + '::' - elif opt == '--debug': - settings.DEBUG = True - else: - print 'Unknown option:', opt - Usage() - - if not files or not module: - Usage() - if not out: - out = module + '.cpp' - return includes, defines, module, out, files - - -def CreateContext(): - 'create the context where a interface file can be executed' - context = {} - # infos - context['Function'] = infos.FunctionInfo - context['Class'] = infos.ClassInfo - context['Include'] = infos.IncludeInfo - context['Template'] = infos.ClassTemplateInfo - context['Enum'] = infos.EnumInfo - context['AllFromHeader'] = infos.HeaderInfo - # functions - context['rename'] = infos.rename - context['set_policy'] = infos.set_policy - context['exclude'] = infos.exclude - context['set_wrapper'] = infos.set_wrapper - # policies - context['return_internal_reference'] = return_internal_reference - context['with_custodian_and_ward'] = with_custodian_and_ward - context['return_value_policy'] = return_value_policy - context['reference_existing_object'] = reference_existing_object - context['copy_const_reference'] = copy_const_reference - context['copy_non_const_reference'] = copy_non_const_reference - context['manage_new_object'] = manage_new_object - # utils - context['Wrapper'] = exporterutils.FunctionWrapper - return context - - -def Main(): - includes, defines, module, out, interfaces = ParseArguments() - # execute the interface files - for interface in interfaces: - context = CreateContext() - execfile(interface, context) - # parse all the C++ code - parser = CppParser(includes, defines) - exports = exporters.exporters[:] - for export in exports: - try: - export.Parse(parser) - except CppParserError, e: - print '\n' - print '***', e, ': exitting' - return 2 - print - # sort the exporters by its order - exports = [(x.Order(), x) for x in exporters.exporters] - exports.sort() - exports = [x for _, x in exports] - # now generate the wrapper code - codeunit = CodeUnit.CodeUnit(module) - exported_names = [] - for export in exports: - export.GenerateCode(codeunit, exported_names) - exported_names.append(export.Name()) - codeunit.Save(out) - print 'Module %s generated' % module - return 0 - - -def UsePsyco(): - 'Tries to use psyco if it is installed' - try: - import psyco - import elementtree.XMLTreeBuilder as XMLTreeBuilder - import GCCXMLParser - - psyco.bind(XMLTreeBuilder.fixtext) - psyco.bind(XMLTreeBuilder.fixname) - psyco.bind(XMLTreeBuilder.TreeBuilder) - psyco.bind(GCCXMLParser.GCCXMLParser) - except ImportError: pass - - -if __name__ == '__main__': - UsePsyco() - status = Main() - sys.exit(status) diff --git a/pyste/src/settings.py b/pyste/src/settings.py deleted file mode 100644 index e5adfc25..00000000 --- a/pyste/src/settings.py +++ /dev/null @@ -1,12 +0,0 @@ - -#============================================================================== -# Global information -#============================================================================== - -DEBUG = False - -class namespaces: - boost = 'boost::' - pyste = '' - python = '' # default is to not use boost::python namespace explicitly, so - # use the "using namespace" statement instead diff --git a/pyste/tests/GCCXMLParserUT.py b/pyste/tests/GCCXMLParserUT.py deleted file mode 100644 index c0a17b33..00000000 --- a/pyste/tests/GCCXMLParserUT.py +++ /dev/null @@ -1,338 +0,0 @@ -import sys -sys.path.append('..') -import unittest -import tempfile -import os.path -import GCCXMLParser -from declarations import * - - -class Tester(unittest.TestCase): - - def TestConstructor(self, class_, method, visib): - self.assert_(isinstance(method, Constructor)) - self.assertEqual(method.FullName(), class_.FullName() + '::' + method.name) - self.assertEqual(method.result, None) - self.assertEqual(method.visibility, visib) - self.assert_(not method.virtual) - self.assert_(not method.abstract) - self.assert_(not method.static) - - def TestDefaultConstructor(self, class_, method, visib): - self.TestConstructor(class_, method, visib) - self.assert_(method.IsDefault()) - - def TestCopyConstructor(self, class_, method, visib): - self.TestConstructor(class_, method, visib) - self.assertEqual(len(method.parameters), 1) - param = method.parameters[0] - self.TestType( - param, - ReferenceType, - class_.FullName(), - 'const %s &' % class_.FullName(), - True) - self.assert_(method.IsCopy()) - - - def TestType(self, type_, classtype_, name, fullname, const): - self.assert_(isinstance(type_, classtype_)) - self.assertEqual(type_.name, name) - self.assertEqual(type_.namespace, None) - self.assertEqual(type_.FullName(), fullname) - self.assertEqual(type_.const, const) - - -class ClassBaseTest(Tester): - - def setUp(self): - self.base = GetDecl('Base') - - def testClass(self): - 'test the properties of the class Base' - self.assert_(isinstance(self.base, Class)) - self.assert_(self.base.abstract) - self.assertEqual(self.base.RawName(), 'Base') - - - def testFoo(self): - 'test function foo in class Base' - foo = GetMember(self.base, 'foo') - self.assert_(isinstance(foo, Method)) - self.assertEqual(foo.visibility, Scope.public) - self.assert_(foo.virtual) - self.assert_(foo.abstract) - self.failIf(foo.static) - self.assertEqual(foo.class_, 'test::Base') - self.failIf(foo.const) - self.assertEqual(foo.FullName(), 'test::Base::foo') - self.assertEqual(foo.result.name, 'void') - self.assertEqual(len(foo.parameters), 1) - param = foo.parameters[0] - self.TestType(param, FundamentalType, 'int', 'int', False) - self.assertEqual(foo.namespace, None) - self.assertEqual( - foo.PointerDeclaration(), '(void (test::Base::*)(int) )test::Base::foo') - - def testX(self): - 'test the member x in class Base' - x = GetMember(self.base, 'x') - self.assertEqual(x.class_, 'test::Base') - self.assertEqual(x.FullName(), 'test::Base::x') - self.assertEqual(x.namespace, None) - self.assertEqual(x.visibility, Scope.private) - self.TestType(x.type, FundamentalType, 'int', 'int', False) - self.assertEqual(x.static, False) - - def testConstructors(self): - 'test constructors in class Base' - constructors = GetMembers(self.base, 'Base') - for cons in constructors: - if len(cons.parameters) == 0: - self.TestDefaultConstructor(self.base, cons, Scope.public) - elif len(cons.parameters) == 1: # copy constructor - self.TestCopyConstructor(self.base, cons, Scope.public) - elif len(cons.parameters) == 2: # other constructor - intp, floatp = cons.parameters - self.TestType(intp, FundamentalType, 'int', 'int', False) - self.TestType(floatp, FundamentalType, 'float', 'float', False) - - def testSimple(self): - 'test function simple in class Base' - simple = GetMember(self.base, 'simple') - self.assert_(isinstance(simple, Method)) - self.assertEqual(simple.visibility, Scope.protected) - self.assertEqual(simple.FullName(), 'test::Base::simple') - self.assertEqual(len(simple.parameters), 1) - param = simple.parameters[0] - self.TestType(param, ReferenceType, 'std::string', 'const std::string &', True) - self.TestType(simple.result, FundamentalType, 'bool', 'bool', False) - self.assertEqual( - simple.PointerDeclaration(), - '(bool (test::Base::*)(const std::string &) )test::Base::simple') - - - def testZ(self): - z = GetMember(self.base, 'z') - self.assert_(isinstance(z, Variable)) - self.assertEqual(z.visibility, Scope.public) - self.assertEqual(z.FullName(), 'test::Base::z') - self.assertEqual(z.type.name, 'int') - self.assertEqual(z.type.const, False) - self.assert_(z.static) - - -class ClassTemplateTest(Tester): - - def setUp(self): - self.template = GetDecl('Template') - - def testClass(self): - 'test the properties of the Template class' - self.assert_(isinstance(self.template, Class)) - self.assert_(not self.template.abstract) - self.assertEqual(self.template.FullName(), 'Template') - self.assertEqual(self.template.namespace, '') - self.assertEqual(self.template.name, 'Template') - self.assertEqual(self.template.RawName(), 'Template') - - def testConstructors(self): - 'test the automatic constructors of the class Template' - constructors = GetMembers(self.template, 'Template') - for cons in constructors: - if len(cons.parameters) == 0: - self.TestDefaultConstructor(self.template, cons, Scope.public) - elif len(cons.parameters) == 1: - self.TestCopyConstructor(self.template, cons, Scope.public) - - - def testValue(self): - 'test the class variable value' - value = GetMember(self.template, 'value') - self.assert_(isinstance(value, ClassVariable)) - self.assert_(value.name, 'value') - self.TestType(value.type, FundamentalType, 'int', 'int', False) - self.assert_(not value.static) - self.assertEqual(value.visibility, Scope.public) - self.assertEqual(value.class_, 'Template') - self.assertEqual(value.FullName(), 'Template::value') - - def testBase(self): - 'test the superclasses of Template' - bases = self.template.bases - self.assertEqual(len(bases), 1) - base = bases[0] - self.assert_(isinstance(base, Base)) - self.assertEqual(base.name, 'test::Base') - self.assertEqual(base.visibility, Scope.protected) - - - -class FreeFuncTest(Tester): - - def setUp(self): - self.func = GetDecl('FreeFunc') - - def testFunc(self): - 'test attributes of FreeFunc' - self.assert_(isinstance(self.func, Function)) - self.assertEqual(self.func.name, 'FreeFunc') - self.assertEqual(self.func.FullName(), 'test::FreeFunc') - self.assertEqual(self.func.namespace, 'test') - self.assertEqual( - self.func.PointerDeclaration(), - '(const test::Base & (*)(const std::string &, int))test::FreeFunc') - - - def testResult(self): - 'test the return value of FreeFunc' - res = self.func.result - self.TestType(res, ReferenceType, 'test::Base', 'const test::Base &', True) - - def testParameters(self): - 'test the parameters of FreeFunc' - self.assertEqual(len(self.func.parameters), 2) - strp, intp = self.func.parameters - self.TestType(strp, ReferenceType, 'std::string', 'const std::string &', True) - self.assertEqual(strp.default, None) - self.TestType(intp, FundamentalType, 'int', 'int', False) - self.assertEqual(intp.default, '10') - - - -class testFunctionPointers(Tester): - - def testMethodPointer(self): - 'test declaration of a pointer-to-method' - meth = GetDecl('MethodTester') - param = meth.parameters[0] - fullname = 'void (test::Base::*)(int)' - self.TestType(param, PointerType, fullname, fullname, False) - - def testFunctionPointer(self): - 'test declaration of a pointer-to-function' - func = GetDecl('FunctionTester') - param = func.parameters[0] - fullname = 'void (*)(int)' - self.TestType(param, PointerType, fullname, fullname, False) - - - -# ============================================================================= -# Support routines -# ============================================================================= - -cppcode = ''' -namespace std { - class string; -} -namespace test { -class Base -{ -public: - Base(); - Base(const Base&); - Base(int, float); - - virtual void foo(int = 0.0) = 0; - static int z; -protected: - bool simple(const std::string&); -private: - int x; -}; - -void MethodTester( void (Base::*)(int) ); -void FunctionTester( void (*)(int) ); - - -const Base & FreeFunc(const std::string&, int=10); - -} - -template -struct Template: protected test::Base -{ - T value; - virtual void foo(int); -}; - -Template __aTemplateInt; -''' - -def GetXMLFile(): - '''Generates an gccxml file using the code from the global cppcode. - Returns the xml's filename.''' - # write the code to a header file - tmpfile = tempfile.mktemp() + '.h' - f = file(tmpfile, 'w') - f.write(cppcode) - f.close() - # run gccxml - outfile = tmpfile + '.xml' - if os.system('gccxml "%s" "-fxml=%s"' % (tmpfile, outfile)) != 0: - raise RuntimeError, 'Error executing GCCXML.' - # read the output file into the xmlcode - f = file(outfile) - xmlcode = f.read() - #print xmlcode - f.close() - # remove the header - os.remove(tmpfile) - return outfile - - - -def GetDeclarations(): - 'Uses the GCCXMLParser module to get the declarations.' - xmlfile = GetXMLFile() - declarations = GCCXMLParser.ParseDeclarations(xmlfile) - os.remove(xmlfile) - return declarations - -# the declarations to be analysed -declarations = GetDeclarations() - - -def GetDecl(name): - 'returns one of the top declarations given its name' - for decl in declarations: - if decl.name == name: - return decl - else: - raise RuntimeError, 'Declaration not found: %s' % name - - -def GetMember(class_, name): - 'gets the member of the given class by its name' - - res = None - multipleFound = False - for member in class_: - if member.name == name: - if res is not None: - multipleFound = True - break - res = member - if res is None or multipleFound: - raise RuntimeError, \ - 'No member or more than one member found in class %s: %s' \ - % (class_.name, name) - return res - - -def GetMembers(class_, name): - 'gets the members of the given class by its name' - res = [] - for member in class_: - if member.name == name: - res.append(member) - if len(res) in (0, 1): - raise RuntimeError, \ - 'GetMembers: 0 or 1 members found in class %s: %s' \ - % (class_.name, name) - return res - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/infosUT.py b/pyste/tests/infosUT.py deleted file mode 100644 index 71d5e368..00000000 --- a/pyste/tests/infosUT.py +++ /dev/null @@ -1,50 +0,0 @@ -import sys -sys.path.append('../src') -from infos import * -from policies import * -from exporterutils import * -import unittest - - -class InfosTest(unittest.TestCase): - - def testFunctionInfo(self): - info = FunctionInfo('test::foo', 'foo.h') - rename(info, 'hello') - set_policy(info, return_internal_reference()) - set_wrapper(info, FunctionWrapper('foo_wrapper')) - - info = InfoWrapper(info) - - self.assertEqual(info.rename, 'hello') - self.assertEqual(info.policy.Code(), 'return_internal_reference< 1 >') - self.assertEqual(info.wrapper.name, 'foo_wrapper') - - - def testClassInfo(self): - info = ClassInfo('test::IFoo', 'foo.h') - rename(info.name, 'Name') - rename(info.exclude, 'Exclude') - rename(info, 'Foo') - rename(info.Bar, 'bar') - set_policy(info.Baz, return_internal_reference()) - rename(info.operator['>>'], 'from_string') - exclude(info.Bar) - set_wrapper(info.Baz, FunctionWrapper('baz_wrapper')) - - info = InfoWrapper(info) - - self.assertEqual(info.rename, 'Foo') - self.assertEqual(info['Bar'].rename, 'bar') - self.assertEqual(info['name'].rename, 'Name') - self.assertEqual(info['exclude'].rename, 'Exclude') - self.assertEqual(info['Bar'].exclude, True) - self.assertEqual(info['Baz'].policy.Code(), 'return_internal_reference< 1 >') - self.assertEqual(info['Baz'].wrapper.name, 'baz_wrapper') - self.assertEqual(info['operator']['>>'].rename, 'from_string') - - - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/policiesUT.py b/pyste/tests/policiesUT.py deleted file mode 100644 index bde08543..00000000 --- a/pyste/tests/policiesUT.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys -sys.path.append('..') -import unittest -from policies import * - -class PoliciesTest(unittest.TestCase): - - def testReturnInternal(self): - 'tests the code from a simple internal_reference' - - x = return_internal_reference(1) - self.assertEqual(x.Code(), 'return_internal_reference< 1 >') - x = return_internal_reference(3) - self.assertEqual(x.Code(), 'return_internal_reference< 3 >') - - - def testCustodian(self): - 'tests the code from a simple custodian_and_ward' - - x = with_custodian_and_ward(1,2) - self.assertEqual(x.Code(), 'with_custodian_and_ward< 1, 2 >') - x = with_custodian_and_ward(3,4) - self.assertEqual(x.Code(), 'with_custodian_and_ward< 3, 4 >') - - - def testReturnPolicies(self): - 'tests all the return_value_policies' - - ret = 'return_value_policy< %s >' - x = return_value_policy(reference_existing_object) - self.assertEqual(x.Code(), ret % 'reference_existing_object') - x = return_value_policy(copy_const_reference) - self.assertEqual(x.Code(), ret % 'copy_const_reference') - x = return_value_policy(copy_non_const_reference) - self.assertEqual(x.Code(), ret % 'copy_non_const_reference') - x = return_value_policy(manage_new_object) - self.assertEqual(x.Code(), ret % 'manage_new_object') - - - def testReturnWithCustodiam(self): - 'test the mix of return_internal with custodian' - - x = return_internal_reference(1, with_custodian_and_ward(3,2)) - self.assertEqual( - x.Code(), - 'return_internal_reference< 1, with_custodian_and_ward< 3, 2 > >') - - - def testReturnPoliciesWithInternal(self): - 'test the mix of return_internal with return_policy' - - x = return_internal_reference(1, return_value_policy(manage_new_object)) - self.assertEqual( - x.Code(), - 'return_internal_reference< 1, return_value_policy< manage_new_object > >') - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/runtests.py b/pyste/tests/runtests.py deleted file mode 100644 index f670e3d4..00000000 --- a/pyste/tests/runtests.py +++ /dev/null @@ -1,14 +0,0 @@ -import sys -sys.path.append('../src') -import unittest -import os.path -from glob import glob - -if __name__ == '__main__': - loader = unittest.defaultTestLoader - tests = [] - for name in glob('*UT.py'): - module = __import__(os.path.splitext(name)[0]) - tests.append(loader.loadTestsFromModule(module)) - runner = unittest.TextTestRunner() - runner.run(unittest.TestSuite(tests)) 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/aix_init_module.cpp b/src/aix_init_module.cpp deleted file mode 100644 index 3eb9f097..00000000 --- a/src/aix_init_module.cpp +++ /dev/null @@ -1,142 +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. -#ifdef _AIX -#include -#include - -extern "C" -{ -#include -#include -} - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -namespace -{ - static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; - extern "C" void initlibboost_python() - { - Py_InitModule("libboost_python", initial_methods); - } - - struct find_and_open_file - { - FILE* fp; - std::string libpath; // -- search path - std::string filename; // -- filename to look for - std::string fullpath; // -- full path to file - - find_and_open_file( - const std::string& libpath_env - , const std::string& file); - }; - - find_and_open_file::find_and_open_file( - const std::string& libpath_env - , const std::string& file) - : fp(0) - { - char* value = std::getenv(libpath_env.c_str()); - - if(value == 0) - return; - - libpath = value; - - if (libpath == "") - return; - - std::string::size_type pos = 0, prev_pos = 0; - - // -- loop through all search paths looking for file - while((pos = libpath.find_first_of(":",pos)) != std::string::npos) - { - fullpath = libpath.substr(prev_pos,pos - prev_pos) + "/" + file; - if (::access(fullpath.c_str(), R_OK) == 0) - { - struct stat filestat; - ::stat(fullpath.c_str(), &filestat); - if (!S_ISDIR(filestat.st_mode)) - { - fp = std::fopen(fullpath.c_str(), "r"); - if (fp) - { - filename = file; - } - return; - } - } - prev_pos = ++pos; - } - - // -- mop up odd path - if (libpath.find_first_of(":", prev_pos) == std::string::npos) - { - fullpath = libpath.substr(prev_pos, libpath.size() - prev_pos) + "/" + file; - if (::access(fullpath.c_str(), R_OK) == 0) - { - struct stat filestat; - ::stat(fullpath.c_str(),&filestat); - if (!S_ISDIR(filestat.st_mode)) - { - fp = std::fopen(fullpath.c_str(), "r"); - filename = file; - } - } - } - } -} - -void aix_init_module( - so_load_function load_dynamic_module - , char const* module_name - , void (*init_module)()) -{ - static bool initialized; - if (!initialized) - { - char const* const name = "libboost_python.so"; - find_and_open_file dynlib("LIBPATH", name); - if (dynlib.fp == 0) - { - fprintf(stderr, " Error: could not find %s\n", name); - return; - } - - std::string::size_type pos = pos = dynlib.filename.rfind(".so"); - if (pos != dynlib.filename.size() - 3) - { - fprintf(stderr, "dynamic library %s must end with .so\n", dynlib.filename.c_str()); - return; - } - - PyObject* m = - load_dynamic_module( - const_cast(dynlib.filename.substr(0,pos).c_str()), - const_cast(dynlib.fullpath.c_str()), - dynlib.fp); - - if (m == 0) - { - fprintf(stderr, "failed to load library %s\n", name); - return; - } - Py_DECREF(m); - - initialized = true; - } - python::detail::init_module(module_name, init_module); -} - -}}} // namespace boost::python -#endif diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp deleted file mode 100644 index 9849071e..00000000 --- a/src/converter/arg_to_python_base.cpp +++ /dev/null @@ -1,29 +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 - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - arg_to_python_base::arg_to_python_base( - void const volatile* source, registration const& converters) -# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179 - : handle<> -# else - : m_ptr -# endif - (converters.to_python(source)) - { - } -} - -}}} // namespace boost::python::converter diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp deleted file mode 100644 index 72437e8c..00000000 --- a/src/converter/builtin_converters.cpp +++ /dev/null @@ -1,373 +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 -#include - -namespace boost { namespace python { namespace converter { - -shared_ptr_deleter::shared_ptr_deleter(handle<> owner) - : owner(owner) -{} - -shared_ptr_deleter::~shared_ptr_deleter() {} - -void shared_ptr_deleter::operator()(void const*) -{ - owner.reset(); -} - -namespace -{ - // An lvalue conversion function which extracts a char const* from a - // Python String. - void* convert_to_cstring(PyObject* obj) - { - return PyString_Check(obj) ? PyString_AsString(obj) : 0; - } - - // Given a target type and a SlotPolicy describing how to perform a - // given conversion, registers from_python converters which use the - // SlotPolicy to extract the type. - template - struct slot_rvalue_from_python - { - public: - slot_rvalue_from_python() - { - registry::insert( - &slot_rvalue_from_python::convertible - , &slot_rvalue_from_python::construct - , type_id() - ); - } - - private: - static void* convertible(PyObject* obj) - { - unaryfunc* slot = SlotPolicy::get_slot(obj); - return slot && *slot ? slot : 0; - } - - static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) - { - // Get the (intermediate) source object - unaryfunc creator = *static_cast(data->convertible); - handle<> intermediate(creator(obj)); - - // Get the location in which to construct - void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; - new (storage) T(SlotPolicy::extract(intermediate.get())); - - // record successful construction - data->convertible = storage; - } - }; - - // A SlotPolicy for extracting signed integer types from Python objects - struct signed_int_rvalue_from_python_base - { - static unaryfunc* get_slot(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - return (PyInt_Check(obj) || PyLong_Check(obj)) - ? &number_methods->nb_int : 0; - } - }; - - template - struct signed_int_rvalue_from_python : signed_int_rvalue_from_python_base - { - static T extract(PyObject* intermediate) - { - long x = PyInt_AsLong(intermediate); - if (PyErr_Occurred()) - throw_error_already_set(); - return numeric_cast(x); - } - }; - - // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc - // "slot" which just returns its argument. - extern "C" PyObject* identity_unaryfunc(PyObject* x) - { - Py_INCREF(x); - return x; - } - unaryfunc py_object_identity = identity_unaryfunc; - - // A SlotPolicy for extracting unsigned integer types from Python objects - struct unsigned_int_rvalue_from_python_base - { - static unaryfunc* get_slot(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - return (PyInt_Check(obj) || PyLong_Check(obj)) - ? &py_object_identity : 0; - } - }; - - template - struct unsigned_int_rvalue_from_python : unsigned_int_rvalue_from_python_base - { - static T extract(PyObject* intermediate) - { - return numeric_cast( - PyLong_Check(intermediate) - ? PyLong_AsUnsignedLong(intermediate) - : PyInt_AS_LONG(intermediate)); - } - }; - -// Checking Python's macro instead of Boost's - we don't seem to get -// the config right all the time. Furthermore, Python's is defined -// when long long is absent but __int64 is present. - -#ifdef HAVE_LONG_LONG - // A SlotPolicy for extracting long long types from Python objects - - struct long_long_rvalue_from_python_base - { - static unaryfunc* get_slot(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - // Return the identity conversion slot to avoid creating a - // new object. We'll handle that in the extract function - if (PyInt_Check(obj)) - return &number_methods->nb_int; - else if (PyLong_Check(obj)) - return &number_methods->nb_long; - else - return 0; - } - }; - - struct long_long_rvalue_from_python : long_long_rvalue_from_python_base - { - static LONG_LONG extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return PyInt_AS_LONG(intermediate); - } - else - { - LONG_LONG result = PyLong_AsLongLong(intermediate); - - if (PyErr_Occurred()) - throw_error_already_set(); - - return result; - } - } - }; - - struct unsigned_long_long_rvalue_from_python : long_long_rvalue_from_python_base - { - static unsigned LONG_LONG extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return numeric_cast(PyInt_AS_LONG(intermediate)); - } - else - { - unsigned LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate); - - if (PyErr_Occurred()) - throw_error_already_set(); - - return result; - } - } - }; -#endif - - // A SlotPolicy for extracting bool from a Python object - struct bool_rvalue_from_python - { - static unaryfunc* get_slot(PyObject* obj) - { - return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0; - } - - static bool extract(PyObject* intermediate) - { - return PyObject_IsTrue(intermediate); - } - }; - - // A SlotPolicy for extracting floating types from Python objects. - struct float_rvalue_from_python - { - static unaryfunc* get_slot(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 below - if (PyInt_Check(obj)) - return &number_methods->nb_int; - - return (PyLong_Check(obj) || PyFloat_Check(obj)) - ? &number_methods->nb_float : 0; - } - - static double extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return PyInt_AS_LONG(intermediate); - } - else - { - return PyFloat_AS_DOUBLE(intermediate); - } - } - }; - - // A SlotPolicy for extracting C++ strings from Python objects. - struct string_rvalue_from_python - { - // If the underlying object is "string-able" this will succeed - static unaryfunc* get_slot(PyObject* obj) - { - return (PyString_Check(obj)) - ? &obj->ob_type->tp_str : 0; - }; - - // Remember that this will be used to construct the result object - static std::string extract(PyObject* intermediate) - { - return std::string(PyString_AsString(intermediate),PyString_Size(intermediate)); - } - }; - - struct complex_rvalue_from_python - { - static unaryfunc* get_slot(PyObject* obj) - { - if (PyComplex_Check(obj)) - return &py_object_identity; - else - return float_rvalue_from_python::get_slot(obj); - } - - static std::complex extract(PyObject* intermediate) - { - if (PyComplex_Check(intermediate)) - { - return std::complex( - PyComplex_RealAsDouble(intermediate) - , PyComplex_ImagAsDouble(intermediate)); - } - else if (PyInt_Check(intermediate)) - { - return PyInt_AS_LONG(intermediate); - } - else - { - return PyFloat_AS_DOUBLE(intermediate); - } - } - }; -} - -BOOST_PYTHON_DECL PyObject* do_return_to_python(char x) -{ - return PyString_FromStringAndSize(&x, 1); -} - -BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x) -{ - return x ? PyString_FromString(x) : boost::python::detail::none(); -} - -BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x) -{ - return x ? x : boost::python::detail::none(); -} - -BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject* x) -{ - if (x == 0) - return boost::python::detail::none(); - - Py_INCREF(x); - return x; -} - -#define REGISTER_INT_CONVERTERS(signedness, U) \ - slot_rvalue_from_python< \ - signedness U \ - ,signedness##_int_rvalue_from_python \ - >() - -#define REGISTER_INT_CONVERTERS2(U) \ - REGISTER_INT_CONVERTERS(signed, U); \ - REGISTER_INT_CONVERTERS(unsigned, U) - -void initialize_builtin_converters() -{ - // booleans - slot_rvalue_from_python(); - - // integer types - REGISTER_INT_CONVERTERS2(char); - REGISTER_INT_CONVERTERS2(short); - REGISTER_INT_CONVERTERS2(int); - REGISTER_INT_CONVERTERS2(long); - -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG - slot_rvalue_from_python(); - slot_rvalue_from_python(); -# endif - - // floating types - slot_rvalue_from_python(); - slot_rvalue_from_python(); - slot_rvalue_from_python(); - - slot_rvalue_from_python,complex_rvalue_from_python>(); - slot_rvalue_from_python,complex_rvalue_from_python>(); - slot_rvalue_from_python,complex_rvalue_from_python>(); - - // Add an lvalue converter for char which gets us char const* - registry::insert(convert_to_cstring,type_id()); - - // Register by-value converters to std::string - slot_rvalue_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 e633debf..00000000 --- a/src/converter/from_python.cpp +++ /dev/null @@ -1,294 +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 { - -// rvalue_from_python_stage1 -- do the first stage of a conversion -// from a Python object to a C++ rvalue. -// -// source - the Python object to be converted -// converters - the registry entry for the target type T -// -// Postcondition: where x is the result, one of: -// -// 1. x.convertible == 0, indicating failure -// -// 2. x.construct == 0, x.convertible is the address of an object of -// type T. Indicates a successful lvalue conversion -// -// 3. where y is of type rvalue_from_python_data, -// x.construct(source, y) constructs an object of type T -// in y.storage.bytes and then sets y.convertible == y.storage.bytes, -// or else throws an exception and has no effect. -BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( - PyObject* source - , registration const& converters) -{ - rvalue_from_python_stage1_data data; - - // First check to see if it's embedded in an extension class - // instance, as a special case. - data.convertible = objects::find_instance_impl(source, converters.target_type); - if (data.convertible) - { - data.construct = 0; - } - else - { - for (rvalue_from_python_chain const* chain = converters.rvalue_chain; - chain != 0; - chain = chain->next) - { - void* r = chain->convertible(source); - if (r != 0) - { - data.convertible = r; - data.construct = chain->construct; - break; - } - } - } - return data; -} - -// rvalue_result_from_python -- return the address of a C++ object which -// can be used as the result of calling a Python function. -// -// src - the Python object to be converted -// -// data - a reference to the base part of a -// rvalue_from_python_data object, where T is the -// target type of the conversion. -// -// Requires: data.convertible == ®istered::converters -// -BOOST_PYTHON_DECL void* rvalue_result_from_python( - PyObject* src, rvalue_from_python_stage1_data& data) -{ - // Retrieve the registration - // Cast in two steps for less-capable compilers - void const* converters_ = data.convertible; - registration const& converters = *static_cast(converters_); - - // Look for an eligible converter - data = rvalue_from_python_stage1(src, converters); - return rvalue_from_python_stage2(src, data, converters); -} - -BOOST_PYTHON_DECL void* rvalue_from_python_stage2( - PyObject* source, rvalue_from_python_stage1_data& data, registration const& converters) -{ - if (!data.convertible) - { - handle<> msg( - ::PyString_FromFormat( - "No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s" - , converters.target_type.name() - , source->ob_type->tp_name - )); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - throw_error_already_set(); - } - - // If a construct function was registered (i.e. we found an - // rvalue conversion), call it now. - if (data.construct != 0) - data.construct(source, &data); - - // Return the address of the resulting C++ object - return data.convertible; -} - -BOOST_PYTHON_DECL void* get_lvalue_from_python( - PyObject* source - , registration const& converters) -{ - // Check to see if it's embedded in a class instance - void* x = objects::find_instance_impl(source, converters.target_type); - if (x) - return x; - - lvalue_from_python_chain const* chain = converters.lvalue_chain; - for (;chain != 0; chain = chain->next) - { - void* r = chain->convert(source); - if (r != 0) - return r; - } - return 0; -} - -namespace -{ - // Prevent looping in implicit conversions. This could/should be - // much more efficient, but will work for now. - typedef std::vector visited_t; - static visited_t visited; - - inline bool visit(rvalue_from_python_chain const* chain) - { - visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); - if (p != visited.end() && *p == chain) - return false; - visited.insert(p, chain); - return true; - } - - // RAII class for managing global visited marks. - struct unvisit - { - unvisit(rvalue_from_python_chain const* chain) - : chain(chain) {} - - ~unvisit() - { - visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); - assert(p != visited.end()); - visited.erase(p); - } - private: - rvalue_from_python_chain const* chain; - }; -} - - -BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python( - PyObject* source - , registration const& converters) -{ - if (objects::find_instance_impl(source, converters.target_type)) - return true; - - rvalue_from_python_chain const* chain = converters.rvalue_chain; - - if (!visit(chain)) - return false; - - unvisit protect(chain); - - for (;chain != 0; chain = chain->next) - { - if (chain->convertible(source)) - return true; - } - - return false; -} - -namespace -{ - void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type) - { - handle<> msg( - ::PyString_FromFormat( - "No registered converter was able to extract a C++ %s to type %s" - " from this Python object of type %s" - , ref_type - , converters.target_type.name() - , source->ob_type->tp_name - )); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - - void* lvalue_result_from_python( - PyObject* source - , registration const& converters - , char const* ref_type) - { - handle<> holder(source); - if (source->ob_refcnt <= 2) - { - handle<> msg( - ::PyString_FromFormat( - "Attempt to return dangling %s to object of type: %s" - , ref_type - , converters.target_type.name())); - - PyErr_SetObject(PyExc_ReferenceError, msg.get()); - - throw_error_already_set(); - } - - void* result = get_lvalue_from_python(source, converters); - if (!result) - (throw_no_lvalue_from_python)(source, converters, ref_type); - return result; - } - -} - -BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject* source, registration const& converters) -{ - (throw_no_lvalue_from_python)(source, converters, "pointer"); -} - -BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject* source, registration const& converters) -{ - (throw_no_lvalue_from_python)(source, converters, "reference"); -} - -BOOST_PYTHON_DECL void* reference_result_from_python( - PyObject* source - , registration const& converters) -{ - return (lvalue_result_from_python)(source, converters, "reference"); -} - -BOOST_PYTHON_DECL void* pointer_result_from_python( - PyObject* source - , registration const& converters) -{ - if (source == Py_None) - { - Py_DECREF(source); - return 0; - } - return (lvalue_result_from_python)(source, converters, "pointer"); -} - -BOOST_PYTHON_DECL void void_result_from_python(PyObject* o) -{ - Py_DECREF(expect_non_null(o)); -} - -} // namespace boost::python::converter - -BOOST_PYTHON_DECL PyObject* -pytype_check(PyTypeObject* type_, PyObject* source) -{ - if (!PyObject_IsInstance(source, python::upcast(type_))) - { - ::PyErr_Format( - PyExc_TypeError - , "Expecting an object of type %s; got an object of type %s instead" - , type_->tp_name - , source->ob_type->tp_name - ); - throw_error_already_set(); - } - return source; -} - -}} // namespace boost::python diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp deleted file mode 100644 index b4891941..00000000 --- a/src/converter/registry.cpp +++ /dev/null @@ -1,187 +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 - -#ifdef BOOST_PYTHON_TRACE_REGISTRY -# include -#endif - -namespace boost { namespace python { namespace converter { - -BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const -{ - if (this->m_class_object == 0) - { - ::PyErr_Format( - PyExc_TypeError - , const_cast("No Python class registered for C++ class %s") - , target_type.name()); - - throw_error_already_set(); - } - - return this->m_class_object; -} - -BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source) const -{ - if (this->m_to_python == 0) - { - handle<> msg( - ::PyString_FromFormat( - "No to_python (by-value) converter found for C++ type: %s" - , this->target_type.name())); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - - return source == 0 - ? incref(Py_None) - : this->m_to_python(const_cast(source)); -} - -namespace // -{ - typedef registration entry; - - typedef std::set registry_t; - - registry_t& entries() - { - static registry_t registry; - -# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION - 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(); - } -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "registry: "; - for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p) - { - std::cout << p->target_type << "; "; - } - std::cout << '\n'; -# endif -# endif - return registry; - } - - entry* get(type_info type) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - registry_t::iterator p = entries().find(entry(type)); - - std::cout << "looking up " << type - << (p == entries().end() || p->target_type != type - ? "...NOT found\n" : "...found\n"); -# endif - return const_cast( - &*entries().insert(entry(type)).first - ); - } -} // namespace - -namespace registry -{ - void insert(to_python_function_t f, type_info source_t) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "inserting to_python " << source_t << "\n"; -# endif - to_python_function_t& slot = get(source_t)->m_to_python; - - 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; - } - - // Insert an lvalue from_python converter - void insert(convertible_function convert, type_info key) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "inserting lvalue from_python " << key << "\n"; -# endif - entry* found = get(key); - lvalue_from_python_chain *registration = new lvalue_from_python_chain; - registration->convert = convert; - registration->next = found->lvalue_chain; - found->lvalue_chain = registration; - - insert(convert, 0, key); - } - - // Insert an rvalue from_python converter - void insert(void* (*convertible)(PyObject*) - , constructor_function construct - , type_info key) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "inserting rvalue from_python " << key << "\n"; -# endif - entry* found = get(key); - rvalue_from_python_chain *registration = new rvalue_from_python_chain; - registration->convertible = convertible; - registration->construct = construct; - registration->next = found->rvalue_chain; - found->rvalue_chain = registration; - } - - // Insert an rvalue from_python converter - void push_back(void* (*convertible)(PyObject*) - , constructor_function construct - , type_info key) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "push_back rvalue from_python " << key << "\n"; -# endif - rvalue_from_python_chain** found = &get(key)->rvalue_chain; - while (*found != 0) - found = &(*found)->next; - - rvalue_from_python_chain *registration = new rvalue_from_python_chain; - registration->convertible = convertible; - registration->construct = construct; - registration->next = 0; - *found = registration; - } - - registration const& lookup(type_info key) - { - return *get(key); - } - - registration const* query(type_info type) - { - registry_t::iterator p = entries().find(entry(type)); -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "querying " << type - << (p == entries().end() || p->target_type != type - ? "...NOT found\n" : "...found\n"); -# endif - return (p == entries().end() || p->target_type != type) ? 0 : &*p; - } -} // 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 74bcd39b..00000000 --- a/src/converter/type_id.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 -#include -#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT -# include -#else -# include -#endif - -namespace boost { namespace python { - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_info const& x) -{ - return os << x.name(); -} - -namespace detail -{ - BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, detail::decorated_type_info const& x) - { - os << x.m_base_type; - if (x.m_decoration & decorated_type_info::const_) - os << " const"; - if (x.m_decoration & decorated_type_info::volatile_) - os << " volatile"; - if (x.m_decoration & decorated_type_info::reference) - os << "&"; - return os; - } -} -}} // namespace boost::python::converter diff --git a/src/dict.cpp b/src/dict.cpp deleted file mode 100644 index f1b8df84..00000000 --- a/src/dict.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include - -namespace boost { namespace python { namespace detail { -namespace -{ - // When returning list objects from methods, it may turn out that the - // derived class is returning something else, perhaps something not - // even derived from list. Since it is generally harmless for a - // Boost.Python wrapper object to hold an object of a different - // type, and because calling list() with an object may in fact - // perform a conversion, the least-bad alternative is to assume that - // we have a Python list object and stuff it into the list result. - list assume_list(object const& o) - { - return list(detail::borrowed_reference(o.ptr())); - } - - // No PyDict_CheckExact; roll our own. - inline bool check_exact(dict_base const* p) - { - return p->ptr()->ob_type == &PyDict_Type; - } -} - -detail::new_reference dict_base::call(object const& arg_) -{ - return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyDict_Type, "(O)", - arg_.ptr()); -} - -dict_base::dict_base() - : object(detail::new_reference(PyDict_New())) -{} - -dict_base::dict_base(object_cref data) - : object(call(data)) -{} - -void dict_base::clear() -{ - if (check_exact(this)) - PyDict_Clear(this->ptr()); - else - this->attr("clear")(); -} - -dict dict_base::copy() -{ - if (check_exact(this)) - { - return dict(detail::new_reference( - PyDict_Copy(this->ptr()))); - } - else - { - return dict(detail::borrowed_reference( - this->attr("copy")().ptr() - )); - } -} - -object dict_base::get(object_cref k) const -{ - if (check_exact(this)) - { - PyObject* result = PyDict_GetItem(this->ptr(),k.ptr()); - return object(detail::borrowed_reference(result ? result : Py_None)); - } - else - { - return this->attr("get")(k); - } -} - -object dict_base::get(object_cref k, object_cref d) const -{ - return this->attr("get")(k,d); -} - -bool dict_base::has_key(object_cref k) const -{ - return extract(this->attr("has_key")(k)); -} - -list dict_base::items() const -{ - if (check_exact(this)) - { - return list(detail::new_reference( - PyDict_Items(this->ptr()))); - } - else - { - return assume_list(this->attr("items")()); - } -} - -object dict_base::iteritems() const -{ - return this->attr("iteritems")(); -} - -object dict_base::iterkeys() const -{ - return this->attr("iterkeys")(); -} - -object dict_base::itervalues() const -{ - return this->attr("itervalues")(); -} - -list dict_base::keys() const -{ - if (check_exact(this)) - { - return list(detail::new_reference( - PyDict_Keys(this->ptr()))); - } - else - { - return assume_list(this->attr("keys")()); - } -} - -tuple dict_base::popitem() -{ - return tuple(detail::borrowed_reference( - this->attr("popitem")().ptr() - )); -} - -object dict_base::setdefault(object_cref k) -{ - return this->attr("setdefault")(k); -} - -object dict_base::setdefault(object_cref k, object_cref d) -{ - return this->attr("setdefault")(k,d); -} - -void dict_base::update(object_cref other) -{ - if (check_exact(this)) - { - if (PyDict_Update(this->ptr(),other.ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("update")(other); - } -} - -list dict_base::values() const -{ - if (check_exact(this)) - { - return list(detail::new_reference( - PyDict_Values(this->ptr()))); - } - else - { - return assume_list(this->attr("values")()); - } -} - -}}} // namespace boost::python diff --git a/src/errors.cpp b/src/errors.cpp deleted file mode 100644 index 8cda9f0e..00000000 --- a/src/errors.cpp +++ /dev/null @@ -1,113 +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 -#include -#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 - { - if (detail::exception_handler::chain) - return detail::exception_handler::chain->handle(f); - 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 bad_numeric_cast& x) - { - PyErr_SetString(PyExc_OverflowError, x.what()); - } - catch(const std::exception& x) - { - PyErr_SetString(PyExc_RuntimeError, x.what()); - } - catch(...) - { - PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); - } - return true; -} - -void BOOST_PYTHON_DECL throw_argument_error() -{ - throw argument_error(); -} - -void BOOST_PYTHON_DECL throw_error_already_set() -{ - throw error_already_set(); -} - -namespace detail { - - BOOST_PYTHON_DECL void expect_complex(PyObject* p) - { - if (!PyComplex_Check(p)) - { - PyErr_SetString(PyExc_TypeError, "expected a complex number"); - boost::python::throw_argument_error(); - } - } - -// needed by void_adaptor (see void_adaptor.hpp) -BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 }; - -bool exception_handler::operator()(function0 const& f) const -{ - if (m_next) - { - return m_next->handle(f); - } - else - { - f(); - return false; - } -} - -exception_handler::exception_handler(handler_function const& impl) - : m_impl(impl) - , m_next(0) -{ - if (chain != 0) - tail->m_next = this; - else - chain = this; - tail = this; -} - -exception_handler* exception_handler::chain; -exception_handler* exception_handler::tail; - -BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f) -{ - // the constructor links the new object into a handler chain, so - // this object isn't actaully leaked (until, of course, the - // interpreter exits). - new exception_handler(f); -} - -} // namespace boost::python::detail - -}} // namespace boost::python - - diff --git a/src/list.cpp b/src/list.cpp deleted file mode 100644 index aab01bc3..00000000 --- a/src/list.cpp +++ /dev/null @@ -1,135 +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 - -namespace boost { namespace python { namespace detail { - -detail::new_non_null_reference list_base::call(object const& arg_) -{ - return (detail::new_non_null_reference) - (expect_non_null)( - PyObject_CallFunction( - (PyObject*)&PyList_Type, "(O)", - arg_.ptr())); -} - -list_base::list_base() - : object(detail::new_reference(PyList_New(0))) -{} - -list_base::list_base(object_cref sequence) - : object(list_base::call(sequence)) -{} - -void list_base::append(object_cref x) -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Append(this->ptr(), x.ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("append")(x); - } -} - -long list_base::count(object_cref value) const -{ - object result_obj(this->attr("count")(value)); - long result = PyInt_AsLong(result_obj.ptr()); - if (result == -1) - throw_error_already_set(); - return result; -} - -void list_base::extend(object_cref sequence) -{ - this->attr("extend")(sequence); -} - -long list_base::index(object_cref value) const -{ - object result_obj(this->attr("index")(value)); - long result = PyInt_AsLong(result_obj.ptr()); - if (result == -1) - throw_error_already_set(); - return result; -} - -void list_base::insert(int index, object_cref item) -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Insert(this->ptr(), index, item.ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("insert")(index, item); - } -} - -void list_base::insert(object const& index, object_cref x) -{ - long index_ = PyInt_AsLong(index.ptr()); - if (index_ == -1 && PyErr_Occurred()) - throw_error_already_set(); - this->insert(index_, x); -} - -object list_base::pop() -{ - return this->attr("pop")(); -} - -object list_base::pop(long index) -{ - return this->pop(object(index)); -} - -object list_base::pop(object const& index) -{ - return this->attr("pop")(index); -} - -void list_base::remove(object_cref value) -{ - this->attr("remove")(value); -} - -void list_base::reverse() -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Reverse(this->ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("reverse")(); - } -} - -void list_base::sort() -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Sort(this->ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("sort")(); - } -} - -void list_base::sort(object_cref cmpfunc) -{ - this->attr("sort")(cmpfunc); -} - -}}} // namespace boost::python diff --git a/src/long.cpp b/src/long.cpp deleted file mode 100644 index bfc09257..00000000 --- a/src/long.cpp +++ /dev/null @@ -1,40 +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 - -namespace boost { namespace python { namespace detail { - -new_non_null_reference long_base::call(object const& arg_) -{ - return (detail::new_non_null_reference)PyObject_CallFunction( - (PyObject*)&PyLong_Type, "(O)", - arg_.ptr()); -} - -new_non_null_reference long_base::call(object const& arg_, object const& base) -{ - return (detail::new_non_null_reference)PyObject_CallFunction( - (PyObject*)&PyLong_Type, "(OO)", - arg_.ptr(), base.ptr()); -} - -long_base::long_base() - : object( - detail::new_reference( - PyObject_CallFunction((PyObject*)&PyLong_Type, "()")) - ) -{} - -long_base::long_base(object_cref arg) - : object(long_base::call(arg)) -{} - -long_base::long_base(object_cref arg, object_cref base) - : object(long_base::call(arg, base)) -{} - - -}}} // namespace boost::python diff --git a/src/module.cpp b/src/module.cpp deleted file mode 100644 index 42bb7a8c..00000000 --- a/src/module.cpp +++ /dev/null @@ -1,52 +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 -#include - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char const* doc) -{ - // Use function::add_to_namespace to achieve overloading if - // appropriate. - scope current; - objects::add_to_namespace(current, name, x, doc); -} - -namespace -{ - PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; -} - -BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)()) -{ - - PyObject* m - = Py_InitModule(const_cast(name), initial_methods); - - if (m != 0) - { - // Create the current module scope - scope current_module( - (object( - ((borrowed_reference_t*)m) - )) - ); - - handle_exception(init_function); - } -} - -}}} // namespace boost::python::detail - -namespace boost { namespace python { - -BOOST_PYTHON_DECL PyObject* scope::current_scope = 0; - -}} diff --git a/src/numeric.cpp b/src/numeric.cpp deleted file mode 100644 index 7d275ff0..00000000 --- a/src/numeric.cpp +++ /dev/null @@ -1,313 +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 - -namespace boost { namespace python { namespace numeric { - -namespace -{ - enum state_t { failed = -1, unknown, succeeded }; - state_t state = unknown; - std::string module_name; - std::string type_name; - - handle<> array_module; - handle<> array_type; - handle<> array_function; - - void throw_load_failure() - { - PyErr_Format( - PyExc_ImportError - , "No module named '%s' or its type '%s' did not follow the NumPy protocol" - , module_name.c_str(), type_name.c_str()); - throw_error_already_set(); - - } - - bool load(bool throw_on_error) - { - if (!state) - { - if (module_name.size() == 0) - { - module_name = "numarray"; - type_name = "NDArray"; - if (load(false)) - return true; - module_name = "Numeric"; - type_name = "ArrayType"; - } - - state = failed; - PyObject* module = ::PyImport_Import(object(module_name).ptr()); - if (module) - { - PyObject* type = ::PyObject_GetAttrString(module, const_cast(type_name.c_str())); - - if (type && PyType_Check(type)) - { - array_type = handle<>(type); - PyObject* function = ::PyObject_GetAttrString(module, const_cast("array")); - - if (function && PyCallable_Check(function)) - { - array_function = handle<>(function); - state = succeeded; - } - } - } - } - - if (state == succeeded) - return true; - - if (throw_on_error) - throw_load_failure(); - - PyErr_Clear(); - return false; - } - - object demand_array_function() - { - load(true); - return object(array_function); - } -} - -void array::set_module_and_type(char const* package_name, char const* type_attribute_name) -{ - state = unknown; - module_name = package_name ? package_name : "" ; - type_name = type_attribute_name ? type_attribute_name : "" ; -} - - -namespace aux -{ - bool array_object_manager_traits::check(PyObject* obj) - { - if (!load(false)) - return false; - return ::PyObject_IsInstance(obj, array_type.get()); - } - - python::detail::new_non_null_reference - array_object_manager_traits::adopt(PyObject* obj) - { - load(true); - return detail::new_non_null_reference( - pytype_check(downcast(array_type.get()), obj)); - } - - -# define BOOST_PYTHON_AS_OBJECT(z, n, _) object(x##n) -# define BOOST_PP_LOCAL_MACRO(n) \ - array_base::array_base(BOOST_PP_ENUM_PARAMS(n, object const& x)) \ - : object(demand_array_function()(BOOST_PP_ENUM_PARAMS(n, x))) \ - {} -# define BOOST_PP_LOCAL_LIMITS (1, 6) -# include BOOST_PP_LOCAL_ITERATE() -# undef BOOST_PYTHON_AS_OBJECT - - array_base::array_base(BOOST_PP_ENUM_PARAMS(7, object const& x)) - : object(demand_array_function()(BOOST_PP_ENUM_PARAMS(7, x))) - {} - - object array_base::argmax(long axis) - { - return attr("argmax")(axis); - } - - object array_base::argmin(long axis) - { - return attr("argmin")(axis); - } - - object array_base::argsort(long axis) - { - return attr("argsort")(axis); - } - - object array_base::astype(object const& type) - { - return attr("astype")(type); - } - - void array_base::byteswap() - { - attr("byteswap")(); - } - - object array_base::copy() const - { - return attr("copy")(); - } - - object array_base::diagonal(long offset, long axis1, long axis2) const - { - return attr("diagonal")(offset, axis1, axis2); - } - - void array_base::info() const - { - attr("info")(); - } - - bool array_base::is_c_array() const - { - return extract(attr("is_c_array")()); - } - - bool array_base::isbyteswapped() const - { - return extract(attr("isbyteswapped")()); - } - - object array_base::new_(object type) const - { - return attr("new")(type); - } - - void array_base::sort() - { - attr("sort")(); - } - - object array_base::trace(long offset, long axis1, long axis2) const - { - return attr("trace")(offset, axis1, axis2); - } - - object array_base::type() const - { - return attr("type")(); - } - - char array_base::typecode() const - { - return extract(attr("typecode")()); - } - - object array_base::factory(object const& buffer - , object const& type - , object const& shape - , bool copy - , bool savespace - , object typecode) - { - return attr("array")(buffer, type, shape, copy, savespace, typecode); - } - - object array_base::getflat() const - { - return attr("getflat")(); - } - - long array_base::getrank() const - { - return extract(attr("getrank")()); - } - - object array_base::getshape() const - { - return attr("getshape")(); - } - - bool array_base::isaligned() const - { - return extract(attr("isaligned")); - } - - bool array_base::iscontiguous() const - { - return extract(attr("isaligned")); - } - - long array_base::itemsize() const - { - return extract(attr("itemsize")); - } - - long array_base::nelements() const - { - return extract(attr("nelements")); - } - - object array_base::nonzero() const - { - return attr("nonzero")(); - } - - void array_base::put(object const& indices, object const& values) - { - attr("put")(indices, values); - } - - void array_base::ravel() - { - attr("ravel")(); - } - - object array_base::repeat(object const& repeats, long axis) - { - return attr("repeat")(repeats, axis); - } - - void array_base::resize(object const& shape) - { - attr("resize")(shape); - } - - void array_base::setflat(object const& flat) - { - attr("setflat")(flat); - } - - void array_base::setshape(object const& shape) - { - attr("setshape")(shape); - } - - void array_base::swapaxes(long axis1, long axis2) - { - attr("swapaxes")(axis1, axis2); - } - - object array_base::take(object const& sequence, long axis) const - { - return attr("take")(sequence, axis); - } - - void array_base::tofile(object const& file) const - { - attr("tofile")(file); - } - - str array_base::tostring() const - { - return str(attr("tostring")()); - } - - void array_base::transpose(object const& axes) - { - attr("transpose")(axes); - } - - object array_base::view() const - { - return attr("view")(); - } -} - -}}} // namespace boost::python::numeric diff --git a/src/object/class.cpp b/src/object/class.cpp deleted file mode 100644 index ff14c9b7..00000000 --- a/src/object/class.cpp +++ /dev/null @@ -1,514 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -# ifdef BOOST_PYTHON_SELF_IS_CLASS -namespace self_ns -{ - self_t self; -} -# endif - -instance_holder::instance_holder() - : m_next(0) -{ -} - -instance_holder::~instance_holder() -{ -} - -// This is copied from typeobject.c in the Python sources. Even though -// class_metatype_object doesn't set Py_TPFLAGS_HAVE_GC, that bit gets -// filled in by the base class initialization process in -// PyType_Ready(). However, tp_is_gc is *not* copied from the base -// type, making it assume that classes are GC-able even if (like -// class_type_object) they're statically allocated. -static int -type_is_gc(PyTypeObject *python_type) -{ - return python_type->tp_flags & Py_TPFLAGS_HEAPTYPE; -} - -static 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, // filled in with type_new /* tp_new */ - 0, // filled in with __PyObject_GC_Del /* tp_free */ - (inquiry)type_is_gc, /* tp_is_gc */ -}; - -// 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 = ((objects::instance<>*)self)->objects; - ((objects::instance<>*)self)->objects = this; -} - - -namespace objects -{ -// Get the metatype object for all extension classes. - BOOST_PYTHON_DECL type_handle 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 type_handle(); - } - return type_handle(borrowed(&class_metatype_object)); - } - extern "C" - { - static void instance_dealloc(PyObject* inst) - { - instance<>* kill_me = (instance<>*)inst; - - for (instance_holder* p = kill_me->objects, *next; p != 0; p = next) - { - next = p->next(); - p->~instance_holder(); - instance_holder::deallocate(inst, dynamic_cast(p)); - } - - // Python 2.2.1 won't add weak references automatically when - // tp_itemsize > 0, so we need to manage that - // ourselves. Accordingly, we also have to clean up the - // weakrefs ourselves. - if (kill_me->weakrefs != NULL) - PyObject_ClearWeakRefs(inst); - - Py_XDECREF(kill_me->dict); - - inst->ob_type->tp_free(inst); - } - - static PyObject * - instance_new(PyTypeObject* type_, PyObject* args, PyObject *kw) - { - // Attempt to find the __instance_size__ attribute. If not present, no problem. - PyObject* d = type_->tp_dict; - PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__"); - - long instance_size = 0; - if (instance_size != 0) - instance_size = PyInt_AsLong(instance_size_obj); - - if (instance_size < 0) - instance_size = 0; - PyErr_Clear(); // Clear any errors that may have occurred. - - instance<>* result = (instance<>*)type_->tp_alloc(type_, instance_size); - if (result) - { - // Guido says we can use ob_size for any purpose we - // like, so we'll store the total size of the object - // there. A negative number indicates that the extra - // instance memory is not yet allocated to any holders. - result->ob_size = -(offsetof(instance<>,storage) + instance_size); - } - return (PyObject*)result; - } - - static PyObject* instance_get_dict(PyObject* op, void*) - { - instance<>* inst = downcast >(op); - if (inst->dict == 0) - inst->dict = PyDict_New(); - return python::xincref(inst->dict); - } - - static int instance_set_dict(PyObject* op, PyObject* dict, void*) - { - instance<>* inst = downcast >(op); - python::xdecref(inst->dict); - inst->dict = python::incref(dict); - return 0; - } - } - - - static PyGetSetDef instance_getsets[] = { - {"__dict__", instance_get_dict, instance_set_dict, NULL}, - {0} - }; - - - static PyMemberDef instance_members[] = { - {"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0}, - {0} - }; - - static PyTypeObject class_type_object = { - PyObject_HEAD_INIT(0) //&class_metatype_object) - 0, - "Boost.Python.instance", - offsetof(instance<>,storage), /* tp_basicsize */ - 1, /* tp_itemsize */ - instance_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 */ - 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 */ - offsetof(instance<>,weakrefs), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - instance_members, /* tp_members */ - instance_getsets, /* tp_getset */ - 0, //&PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(instance<>,dict), /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - instance_new /* tp_new */ - }; - - BOOST_PYTHON_DECL type_handle class_type() - { - if (class_type_object.tp_dict == 0) - { - class_type_object.ob_type = incref(class_metatype().get()); - class_type_object.tp_base = &PyBaseObject_Type; - if (PyType_Ready(&class_type_object)) - return type_handle(); - } - return type_handle(borrowed(&class_type_object)); - } - - BOOST_PYTHON_DECL void* - find_instance_impl(PyObject* inst, type_info type) - { - if (inst->ob_type->ob_type != &class_metatype_object) - return 0; - - instance<>* self = reinterpret_cast*>(inst); - - for (instance_holder* match = self->objects; match != 0; match = match->next()) - { - void* const found = match->holds(type); - if (found) - return found; - } - return 0; - } - - object module_prefix() - { - return object( - PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) - ? object(scope().attr("__name__")) - : api::getattr(scope(), "__module__", str()) - ); - } - - namespace - { - // Find a registered class object corresponding to id. Return a - // null handle if no such class is registered. - inline type_handle query_class(class_id id) - { - converter::registration const* p = converter::registry::query(id); - return type_handle( - python::borrowed( - python::allow_null(p ? p->m_class_object : 0)) - ); - } - - // Find a registered class corresponding to id. If not found, - // throw an appropriate exception. - type_handle get_class(class_id id) - { - type_handle result(query_class(id)); - - if (result.get() == 0) - { - object report("extension class wrapper for base class "); - report = report + id.name() + " has not been created yet"; - PyErr_SetObject(PyExc_RuntimeError, report.ptr()); - throw_error_already_set(); - } - return result; - } - - // class_base constructor - // - // name - the name of the new Python class - // - // num_types - one more than the number of declared bases - // - // types - array of python::type_info, the first item - // corresponding to the class being created, and the - // rest corresponding to its declared bases. - // - inline object - new_class(char const* name, std::size_t num_types, class_id const* const types, char const* doc) - { - assert(num_types >= 1); - - // Build a tuple of the base Python type objects. If no bases - // were declared, we'll use our class_type() as the single base - // class. - std::size_t const num_bases = std::max(num_types - 1, static_cast(1)); - handle<> bases(PyTuple_New(num_bases)); - - for (std::size_t i = 1; i <= num_bases; ++i) - { - type_handle c = (i >= num_types) ? class_type() : get_class(types[i]); - // PyTuple_SET_ITEM steals this reference - PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); - } - - // Call the class metatype to create a new class - dict d; - - object m = module_prefix(); - if (m) d["__module__"] = m; - - if (doc != 0) - d["__doc__"] = doc; - - object result = object(class_metatype())(name, bases, d); - assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type)); - - if (scope().ptr() != Py_None) - scope().attr(name) = result; - - return result; - } - } - - class_base::class_base( - char const* name, std::size_t num_types, class_id const* const types, char const* doc) - : object(new_class(name, num_types, types, doc)) - { - // Insert the new class object in the registry - converter::registration& converters = const_cast( - converter::registry::lookup(types[0])); - - // Class object is leaked, for now - converters.m_class_object = (PyTypeObject*)incref(this->ptr()); - } - - void class_base::set_instance_size(std::size_t instance_size) - { - this->attr("__instance_size__") = instance_size; - } - - extern "C" - { - // This declaration needed due to broken Python 2.2 headers - extern DL_IMPORT(PyTypeObject) PyProperty_Type; - } - - void class_base::add_property(char const* name, object const& fget) - { - object property( - (python::detail::new_reference) - PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr())); - - this->setattr(name, property); - } - - void class_base::add_property(char const* name, object const& fget, object const& fset) - { - object property( - (python::detail::new_reference) - PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr())); - - this->setattr(name, property); - } - - void class_base::setattr(char const* name, object const& x) - { - if (PyObject_SetAttrString(this->ptr(), const_cast(name), x.ptr()) < 0) - throw_error_already_set(); - } - - namespace - { - extern "C" PyObject* no_init(PyObject*, PyObject*) - { - ::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python"); - return NULL; - } - static ::PyMethodDef no_init_def = { - "__init__", no_init, METH_VARARGS, - "Raises an exception\n" - "This class cannot be instantiated from Python\n" - }; - } - - void class_base::def_no_init() - { - handle<> f(::PyCFunction_New(&no_init_def, 0)); - this->setattr("__init__", object(f)); - } - - void class_base::enable_pickling(bool getstate_manages_dict) - { - setattr("__reduce__", object(make_instance_reduce_function())); - setattr("__safe_for_unpickling__", object(true)); - - if (getstate_manages_dict) - { - setattr("__getstate_manages_dict__", object(true)); - } - } - - namespace - { - PyObject* callable_check(PyObject* callable) - { - if (PyCallable_Check(expect_non_null(callable))) - return callable; - - ::PyErr_Format( - PyExc_TypeError - , "staticmethod expects callable object; got an object of type %s, which is not callable" - , callable->ob_type->tp_name - ); - - throw_error_already_set(); - return 0; - } - } - - void class_base::make_method_static(const char * method_name) - { - PyTypeObject* self = downcast(this->ptr()); - dict d((handle<>(borrowed(self->tp_dict)))); - - object method(d[method_name]); - - this->attr(method_name) = object( - handle<>( - PyStaticMethod_New((callable_check)(method.ptr()) ) - )); - } - - BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) - { - return query_class(id); - } -} // namespace objects - - -void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size) -{ - assert(self_->ob_type->ob_type == &class_metatype_object); - objects::instance<>* self = (objects::instance<>*)self_; - - int total_size_needed = holder_offset + holder_size; - - if (-self->ob_size >= total_size_needed) - { - // holder_offset should at least point into the variable-sized part - assert(holder_offset >= offsetof(objects::instance<>,storage)); - - // Record the fact that the storage is occupied, noting where it starts - self->ob_size = holder_offset; - return (char*)self + holder_offset; - } - else - { - void* const result = PyMem_Malloc(holder_size); - if (result == 0) - throw std::bad_alloc(); - return result; - } -} - -void instance_holder::deallocate(PyObject* self_, void* storage) throw() -{ - assert(self_->ob_type->ob_type == &class_metatype_object); - objects::instance<>* self = (objects::instance<>*)self_; - if (storage != (char*)self + self->ob_size) - { - PyMem_Free(storage); - } -} - -}} // namespace boost::python diff --git a/src/object/enum.cpp b/src/object/enum.cpp deleted file mode 100644 index c297abb7..00000000 --- a/src/object/enum.cpp +++ /dev/null @@ -1,225 +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 - -namespace boost { namespace python { namespace objects { - -struct enum_object -{ - PyIntObject base_object; - PyObject* name; -}; - -static PyMemberDef enum_members[] = { - {"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY}, - {0} -}; - - -extern "C" -{ - static int - enum_print(PyObject *v, BOOST_CSTD_::FILE *fp, int flags) - { - PyObject* s - = (flags & Py_PRINT_RAW) ? v->ob_type->tp_str(v) : v->ob_type->tp_repr(v); - if (s == 0) - return -1; - - char const* text = PyString_AsString(s); - if (text == 0) - return -1; - - BOOST_CSTD_::fprintf(fp, text); - return 0; - } - - /* flags -- not used but required by interface */ - static PyObject* enum_repr(PyObject* self_) - { - enum_object* self = downcast(self_); - if (!self->name) - { - return PyString_FromFormat("%s(%ld)", self_->ob_type->tp_name, PyInt_AS_LONG(self_)); - } - else - { - char* name = PyString_AsString(self->name); - if (name == 0) - return 0; - - return PyString_FromFormat("%s.%s", self_->ob_type->tp_name, name); - } - } - - static PyObject* enum_str(PyObject* self_) - { - enum_object* self = downcast(self_); - if (!self->name) - { - return PyInt_Type.tp_str(self_); - } - else - { - return incref(self->name); - } - } -} - -static PyTypeObject enum_type_object = { - PyObject_HEAD_INIT(0) // &PyType_Type - 0, - "Boost.Python.enum", - sizeof(enum_object), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - enum_print, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - enum_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - enum_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_CHECKTYPES - | 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 */ - enum_members, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyInt_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0 /* tp_new */ -}; - -object module_prefix(); - -namespace -{ - object new_enum_type(char const* name) - { - if (enum_type_object.tp_dict == 0) - { - enum_type_object.ob_type = incref(&PyType_Type); - enum_type_object.tp_base = &PyInt_Type; - if (PyType_Ready(&enum_type_object)) - throw_error_already_set(); - } - - type_handle metatype(borrowed(&PyType_Type)); - type_handle base(borrowed(&enum_type_object)); - - // suppress the instance __dict__ in these enum objects. There - // may be a slicker way, but this'll do for now. - dict d; - d["__slots__"] = tuple(); - d["values"] = dict(); - - object module_name = module_prefix(); - if (module_name) - module_name += '.'; - - object result = (object(metatype))( - module_name + name, make_tuple(base), d); - - scope().attr(name) = result; - - return result; - } -} - -enum_base::enum_base( - char const* name - , converter::to_python_function_t to_python - , converter::convertible_function convertible - , converter::constructor_function construct - , type_info id - ) - : object(new_enum_type(name)) -{ - converter::registration& converters - = const_cast( - converter::registry::lookup(id)); - - converters.m_class_object = downcast(this->ptr()); - converter::registry::insert(to_python, id); - converter::registry::insert(convertible, construct, id); -} - -void enum_base::add_value(char const* name_, long value) -{ - // Convert name to Python string - object name(name_); - - // Create a new enum instance by calling the class with a value - object x = (*this)(value); - - // Store the object in the enum class - (*this).attr(name_) = x; - - dict d = extract(this->attr("values"))(); - d[value] = x; - - // Set the name field in the new enum instanec - enum_object* p = downcast(x.ptr()); - Py_XDECREF(p->name); - p->name = incref(name.ptr()); -} - -void enum_base::export_values() -{ - dict d = extract(this->attr("values"))(); - list values = d.values(); - scope current; - - for (unsigned i = 0, max = len(values); i < max; ++i) - { - api::setattr(current, object(values[i].attr("name")), values[i]); - } - } - -PyObject* enum_base::to_python(PyTypeObject* type_, long x) -{ - object type((type_handle(borrowed(type_)))); - - dict d = extract(type.attr("values"))(); - object v = d.get(x, object()); - return incref( - (v == object() ? type(x) : v).ptr()); -} - -}}} // namespace boost::python::object diff --git a/src/object/function.cpp b/src/object/function.cpp deleted file mode 100644 index 761a9866..00000000 --- a/src/object/function.cpp +++ /dev/null @@ -1,527 +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 - -#include -#include - -namespace boost { namespace python { namespace objects { - -extern PyTypeObject function_type; - -function::function( - py_function const& implementation - , unsigned min_arity - , unsigned max_arity - , python::detail::keyword const* names_and_defaults - , unsigned num_keywords - ) - : m_fn(implementation) - , m_min_arity(min_arity) - // was using std::max here, but a problem with MinGW-2.95 and - // our directory prevents it. - , m_max_arity(max_arity > min_arity ? max_arity : min_arity) -{ - if (names_and_defaults != 0) - { - unsigned keyword_offset - = m_max_arity > num_keywords ? m_max_arity - num_keywords : 0; - - - unsigned tuple_size = num_keywords ? m_max_arity : 0; - m_arg_names = object(handle<>(PyTuple_New(tuple_size))); - - if (num_keywords != 0) - { - for (unsigned j = 0; j < keyword_offset; ++j) - PyTuple_SET_ITEM(m_arg_names.ptr(), j, incref(Py_None)); - } - - for (unsigned i = 0; i < num_keywords; ++i) - { - PyTuple_SET_ITEM( - m_arg_names.ptr() - , i + keyword_offset - , expect_non_null( - PyString_FromString(const_cast(names_and_defaults[i].name)) - ) - ); - } - } - - PyObject* p = this; - if (function_type.ob_type == 0) - { - function_type.ob_type = &PyType_Type; - ::PyType_Ready(&function_type); - } - PyObject_INIT(p, &function_type); -} - -function::~function() -{ -} - -PyObject* function::call(PyObject* args, PyObject* keywords) const -{ - std::size_t nargs = PyTuple_GET_SIZE(args); - std::size_t nkeywords = keywords ? PyDict_Size(keywords) : 0; - std::size_t total_args = nargs + nkeywords; - - function const* f = this; - - // Try overloads looking for a match - do - { - // Check for a plausible number of arguments - if (total_args >= f->m_min_arity && total_args <= f->m_max_arity) - { - // This will be the args that actually get passed - handle<> args2(allow_null(borrowed(args))); - - if (nkeywords > 0) // Keyword arguments were supplied - { - if (f->m_arg_names.ptr() == Py_None) // this overload doesn't accept keywords - { - args2 = handle<>(); // signal failure - } - else - { - std::size_t max_args - = static_cast(PyTuple_Size(f->m_arg_names.ptr())); - - // "all keywords are none" is a special case - // indicating we will accept any number of keyword - // arguments - if (max_args == 0) - { - // no argument preprocessing - } - else if (max_args < total_args) - { - args2 = handle<>(); - } - else - { - // build a new arg tuple - args2 = handle<>(PyTuple_New(total_args)); - - // Fill in the positional arguments - for (std::size_t i = 0; i < nargs; ++i) - PyTuple_SET_ITEM(args2.get(), i, incref(PyTuple_GET_ITEM(args, i))); - - // Grab remaining arguments by name from the keyword dictionary - for (std::size_t j = nargs; j < total_args; ++j) - { - PyObject* value = PyDict_GetItem( - keywords, PyTuple_GET_ITEM(f->m_arg_names.ptr(), j)); - - if (!value) - { - PyErr_Clear(); - args2 = handle<>(); - break; - } - PyTuple_SET_ITEM(args2.get(), j, incref(value)); - } - } - } - } - - // Call the function. Pass keywords in case it's a - // function accepting any number of keywords - PyObject* result = args2 ? f->m_fn(args2.get(), keywords) : 0; - - // 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.get(); - } - 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(handle const& overload_) -{ - function* parent = this; - - while (parent->m_overloads) - parent = parent->m_overloads.get(); - - parent->m_overloads = overload_; - - // If we have no documentation, get the docs from the overload - if (!m_doc) - m_doc = overload_->m_doc; -} - -namespace -{ - char const* const binary_operator_names[] = - { - "add__", - "and__", - "div__", - "divmod__", - "eq__", - "floordiv__", - "ge__", - "gt__", - "le__", - "lshift__", - "lt__", - "mod__", - "mul__", - "ne__", - "or__", - "pow__", - "radd__", - "rand__", - "rdiv__", - "rdivmod__", - "rfloordiv__", - "rlshift__", - "rmod__", - "rmul__", - "ror__", - "rpow__", - "rrshift__", - "rshift__", - "rsub__", - "rtruediv__", - "rxor__", - "sub__", - "truediv__", - "xor__" - }; - - struct less_cstring - { - bool operator()(char const* x, char const* y) const - { - return BOOST_CSTD_::strcmp(x,y) < 0; - } - }; - - inline bool is_binary_operator(char const* name) - { - return name[0] == '_' - && name[1] == '_' - && std::binary_search( - &binary_operator_names[0] - , binary_operator_names + sizeof(binary_operator_names)/sizeof(*binary_operator_names) - , name + 2 - , less_cstring() - ); - } - - // Something for the end of the chain of binary operators - PyObject* not_implemented_impl(PyObject*, PyObject*) - { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - handle not_implemented_function() - { - static object keeper( - function_object(¬_implemented_impl, 2, 3 - , python::detail::keyword_range()) - ); - return handle(borrowed(downcast(keeper.ptr()))); - } -} - -void function::add_to_namespace( - object const& name_space, char const* name_, object const& attribute) -{ - str const name(name_); - PyObject* const ns = name_space.ptr(); - - if (attribute.ptr()->ob_type == &function_type) - { - function* new_func = downcast(attribute.ptr()); - 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(); - - // This isn't quite typesafe. We'll shoot first by assuming - // the thing is a function*, then ask questions later. The code works nicer that way. - handle existing( - allow_null(downcast(::PyObject_GetItem(dict, name.ptr()))) - ); - - if (existing) - { - if (existing->ob_type == &function_type) - { - new_func->add_overload(existing); - } - else if (existing->ob_type == &PyStaticMethod_Type) - { - char const* name_space_name = extract(name_space.attr("__name__")); - - ::PyErr_Format( - PyExc_RuntimeError - , "Boost.Python - All overloads must be exported " - "before calling \'class_<...>(\"%s\").staticmethod(\"%s\")\'" - , name_space_name - , name_ - ); - throw_error_already_set(); - } - } - else if (is_binary_operator(name_)) - { - // Binary operators need an additional overload which - // returns NotImplemented, so that Python will try the - // __rxxx__ functions on the other operand. We add this - // when no overloads for the operator already exist. - new_func->add_overload(not_implemented_function()); - } - - // A function is named the first time it is added to a namespace. - if (new_func->name().ptr() == Py_None) - new_func->m_name = name; - } - - // The PyObject_GetAttrString() call above left an active error - PyErr_Clear(); - if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0) - throw_error_already_set(); -} - -void function::add_to_namespace( - object const& name_space, char const* name_, object const& attribute, char const* doc) -{ - add_to_namespace(name_space, name_, attribute); - if (doc != 0) - { - object attr_copy(attribute); - attr_copy.attr("__doc__") = doc; - } -} - -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute) -{ - function::add_to_namespace(name_space, name, attribute); -} - -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc) -{ - function::add_to_namespace(name_space, name, attribute, doc); -} - - -namespace -{ - struct bind_return - { - bind_return(PyObject*& result, function const* f, PyObject* args, PyObject* keywords) - : m_result(result) - , m_f(f) - , m_args(args) - , m_keywords(keywords) - {} - - void operator()() const - { - m_result = m_f->call(m_args, m_keywords); - } - - private: - PyObject*& m_result; - function const* m_f; - PyObject* m_args; - PyObject* m_keywords; - }; -} - -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 *args, PyObject *kw) - { - PyObject* result = 0; - handle_exception(bind_return(result, static_cast(func), args, kw)); - return result; - } - - // - // Here we're using the function's tp_getset rather than its - // tp_members to set up __doc__ and __name__, because tp_members - // really depends on having a POD object type (it relies on - // offsets). It might make sense to reformulate function as a POD - // at some point, but this is much more expedient. - // - static PyObject* function_get_doc(PyObject* op, void*) - { - function* f = downcast(op); - return python::incref(f->doc().ptr()); - } - - static int function_set_doc(PyObject* op, PyObject* doc, void*) - { - function* f = downcast(op); - f->doc(doc ? object(python::detail::borrowed_reference(doc)) : object()); - return 0; - } - - static PyObject* function_get_name(PyObject* op, void*) - { - function* f = downcast(op); - if (f->name().ptr() == Py_None) - return PyString_InternFromString(""); - else - return python::incref(f->name().ptr()); - } -} - -static PyGetSetDef function_getsetlist[] = { - {"__name__", (getter)function_get_name, 0 }, - {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, - {NULL} /* Sentinel */ -}; - -PyTypeObject function_type = { - PyObject_HEAD_INIT(0) - 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 */ - function_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 */ -}; - -object function_object( - py_function const& f, unsigned min_arity, unsigned max_arity - , python::detail::keyword_range const& keywords) -{ - return python::object( - python::detail::new_non_null_reference( - new function( - f, min_arity, max_arity, keywords.first, keywords.second - keywords.first))); -} - -object function_object( - py_function const& f - , unsigned arity - , python::detail::keyword_range const& kw) -{ - return function_object(f, arity, arity, kw); -} - -object function_object(py_function const& f, unsigned arity) -{ - return function_object(f, arity, arity, python::detail::keyword_range()); -} - - -handle<> function_handle_impl(py_function const& f, unsigned min_arity, unsigned max_arity) -{ - return python::handle<>( - allow_null( - new function(f, min_arity, max_arity, 0, 0))); -} - -} - -namespace detail -{ - object BOOST_PYTHON_DECL make_raw_function(objects::py_function f, std::size_t min_args) - { - static keyword k; - - return objects::function_object( - f - , min_args - , std::numeric_limits::max() - , keyword_range(&k,&k)); - } -} - -}} // namespace boost::python::objects diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp deleted file mode 100644 index 13dfaef0..00000000 --- a/src/object/inheritance.cpp +++ /dev/null @@ -1,496 +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 -#if _MSC_FULL_VER >= 13102171 && _MSC_FULL_VER <= 13102179 -# include -#endif -#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::type_info 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_NO_STD_ITERATOR_TRAITS - , *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() - , boost::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, boost::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(boost::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/object/iterator.cpp b/src/object/iterator.cpp deleted file mode 100644 index 1718ee59..00000000 --- a/src/object/iterator.cpp +++ /dev/null @@ -1,31 +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 - -namespace boost { namespace python { namespace objects { - -static PyObject* identity(PyObject* args_, PyObject*) -{ - PyObject* x = PyTuple_GET_ITEM(args_,0); - Py_INCREF(x); - return x; -} - -BOOST_PYTHON_DECL object const& identity_function() -{ - static object result(function_object(&identity, 1)); - return result; -} - -void set_stop_iteration_error() -{ - PyErr_SetObject(PyExc_StopIteration, Py_None); -} - -}}} // namespace boost::python::objects diff --git a/src/object/life_support.cpp b/src/object/life_support.cpp deleted file mode 100644 index ae414bbe..00000000 --- a/src/object/life_support.cpp +++ /dev/null @@ -1,113 +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 - -namespace boost { namespace python { namespace objects { - -struct life_support -{ - PyObject_HEAD - PyObject* patient; -}; - -extern "C" -{ - static void - life_support_dealloc(PyObject* self) - { - Py_XDECREF(((life_support*)self)->patient); - self->ob_type->tp_free(self); - } - - static PyObject * - life_support_call(PyObject *self, PyObject *arg, PyObject *kw) - { - // Let the patient die now - Py_XDECREF(((life_support*)self)->patient); - ((life_support*)self)->patient = 0; - // Let the weak reference die. This probably kills us. - Py_XDECREF(PyTuple_GET_ITEM(arg, 0)); - return detail::none(); - } -} - -PyTypeObject life_support_type = { - PyObject_HEAD_INIT(0)//(&PyType_Type) - 0, - "Boost.Python.life_support", - sizeof(life_support), - 0, - life_support_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 */ - life_support_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(PyLife_SupportObject, 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 */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, //offsetof(PyLife_SupportObject, func_dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, - 0 /* tp_new */ -}; - -PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient) -{ - if (nurse == Py_None) - return incref(nurse); - - if (life_support_type.ob_type == 0) - { - life_support_type.ob_type = &PyType_Type; - PyType_Ready(&life_support_type); - } - - life_support* system = PyObject_New(life_support, &life_support_type); - if (!system) - return 0; - - system->patient = 0; - - // We're going to leak this reference, but don't worry; the - // life_support system decrements it when the nurse dies. - PyObject* weakref = PyWeakref_NewRef(nurse, (PyObject*)system); - if (!weakref) - { - Py_XDECREF(system); - return 0; - } - - system->patient = patient; - Py_XINCREF(patient); // hang on to the patient until death - return weakref; -} - -}}} // namespace boost::python::objects diff --git a/src/object/pickle_support.cpp b/src/object/pickle_support.cpp deleted file mode 100644 index 6f37517f..00000000 --- a/src/object/pickle_support.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// (C) Copyright R.W. Grosse-Kunstleve 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 - -namespace boost { namespace python { - -namespace { - - tuple instance_reduce(object instance_obj) - { - list result; - object instance_class(instance_obj.attr("__class__")); - result.append(instance_class); - object none; - object getinitargs = getattr(instance_obj, "__getinitargs__", none); - tuple initargs; - if (getinitargs.ptr() != none.ptr()) { - initargs = tuple(getinitargs()); - } - result.append(initargs); - object getstate = getattr(instance_obj, "__getstate__", none); - object instance_dict = getattr(instance_obj, "__dict__", none); - long len_instance_dict = 0; - if (instance_dict.ptr() != none.ptr()) { - len_instance_dict = len(instance_dict); - } - if (getstate.ptr() != none.ptr()) { - if (len_instance_dict > 0) { - object getstate_manages_dict = getattr( - instance_obj, "__getstate_manages_dict__", none); - if (getstate_manages_dict.ptr() == none.ptr()) { - PyErr_SetString(PyExc_RuntimeError, - "Incomplete pickle support" - " (__getstate_manages_dict__ not set)"); - throw_error_already_set(); - } - } - result.append(getstate()); - } - else if (len_instance_dict > 0) { - result.append(instance_dict); - } - return tuple(result); - } - -} // namespace - -object const& make_instance_reduce_function() -{ - static object result(&instance_reduce); - return result; -} - -}} // namespace boost::python diff --git a/src/object_operators.cpp b/src/object_operators.cpp deleted file mode 100644 index 40cdeba3..00000000 --- a/src/object_operators.cpp +++ /dev/null @@ -1,57 +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 api { - -#define BOOST_PYTHON_BINARY_OPERATOR(op, name) \ -BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \ -{ \ - return object( \ - detail::new_reference( \ - PyNumber_##name(l.ptr(), r.ptr())) \ - ); \ -} - -BOOST_PYTHON_BINARY_OPERATOR(+, Add) -BOOST_PYTHON_BINARY_OPERATOR(-, Subtract) -BOOST_PYTHON_BINARY_OPERATOR(*, Multiply) -BOOST_PYTHON_BINARY_OPERATOR(/, Divide) -BOOST_PYTHON_BINARY_OPERATOR(%, Remainder) -BOOST_PYTHON_BINARY_OPERATOR(<<, Lshift) -BOOST_PYTHON_BINARY_OPERATOR(>>, Rshift) -BOOST_PYTHON_BINARY_OPERATOR(&, And) -BOOST_PYTHON_BINARY_OPERATOR(^, Xor) -BOOST_PYTHON_BINARY_OPERATOR(|, Or) -#undef BOOST_PYTHON_BINARY_OPERATOR - -#define BOOST_PYTHON_INPLACE_OPERATOR(op, name) \ -BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \ -{ \ - return l = object( \ - (detail::new_reference) \ - PyNumber_InPlace##name(l.ptr(), r.ptr())); \ -} - -BOOST_PYTHON_INPLACE_OPERATOR(+, Add) -BOOST_PYTHON_INPLACE_OPERATOR(-, Subtract) -BOOST_PYTHON_INPLACE_OPERATOR(*, Multiply) -BOOST_PYTHON_INPLACE_OPERATOR(/, Divide) -BOOST_PYTHON_INPLACE_OPERATOR(%, Remainder) -BOOST_PYTHON_INPLACE_OPERATOR(<<, Lshift) -BOOST_PYTHON_INPLACE_OPERATOR(>>, Rshift) -BOOST_PYTHON_INPLACE_OPERATOR(&, And) -BOOST_PYTHON_INPLACE_OPERATOR(^, Xor) -BOOST_PYTHON_INPLACE_OPERATOR(|, Or) -#undef BOOST_PYTHON_INPLACE_OPERATOR - -object::object(handle<> const& x) - : object_base(python::incref(python::expect_non_null(x.get()))) -{} - -}}} // namespace boost::python diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp deleted file mode 100755 index 11979f8f..00000000 --- a/src/object_protocol.cpp +++ /dev/null @@ -1,191 +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 - -namespace boost { namespace python { namespace api { - -BOOST_PYTHON_DECL object getattr(object const& target, object const& key) -{ - return object(detail::new_reference(PyObject_GetAttr(target.ptr(), key.ptr()))); -} - -BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_) -{ - PyObject* result = PyObject_GetAttr(target.ptr(), key.ptr()); - if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) - { - PyErr_Clear(); - return default_; - } - return object(detail::new_reference(result)); -} - -BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value) -{ - if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) - throw_error_already_set(); -} - -BOOST_PYTHON_DECL void delattr(object const& target, object const& key) -{ - if (PyObject_DelAttr(target.ptr(), key.ptr()) == -1) - throw_error_already_set(); -} - -BOOST_PYTHON_DECL object getattr(object const& target, char const* key) -{ - return object( - detail::new_reference( - PyObject_GetAttrString(target.ptr(), const_cast(key)) - )); -} - -BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_) -{ - PyObject* result = PyObject_GetAttrString(target.ptr(), const_cast(key)); - if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) - { - PyErr_Clear(); - return default_; - } - return object(detail::new_reference(result)); - -} -BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value) -{ - if (PyObject_SetAttrString( - target.ptr(), const_cast(key), value.ptr()) == -1 - ) - { - throw_error_already_set(); - } -} - -BOOST_PYTHON_DECL void delattr(object const& target, char const* key) -{ - if (PyObject_DelAttrString( - target.ptr(), const_cast(key)) == -1 - ) - { - throw_error_already_set(); - } -} - -BOOST_PYTHON_DECL object getitem(object const& target, object const& key) -{ - return object(detail::new_reference( - PyObject_GetItem(target.ptr(), key.ptr()))); -} - -BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value) -{ - if (PyObject_SetItem(target.ptr(), key.ptr(), value.ptr()) == -1) - throw_error_already_set(); -} - -BOOST_PYTHON_DECL void delitem(object const& target, object const& key) -{ - if (PyObject_DelItem(target.ptr(), key.ptr()) == -1) - throw_error_already_set(); -} - -namespace // slicing code copied directly out of the Python implementation -{ - #undef ISINT - #define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x)) - - static PyObject * - apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */ - { - PyTypeObject *tp = u->ob_type; - PySequenceMethods *sq = tp->tp_as_sequence; - - if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) { - int ilow = 0, ihigh = INT_MAX; - if (!_PyEval_SliceIndex(v, &ilow)) - return NULL; - if (!_PyEval_SliceIndex(w, &ihigh)) - return NULL; - return PySequence_GetSlice(u, ilow, ihigh); - } - else { - PyObject *slice = PySlice_New(v, w, NULL); - if (slice != NULL) { - PyObject *res = PyObject_GetItem(u, slice); - Py_DECREF(slice); - return res; - } - else - return NULL; - } - } - - static int - assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x) - /* u[v:w] = x */ - { - PyTypeObject *tp = u->ob_type; - PySequenceMethods *sq = tp->tp_as_sequence; - - if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) { - int ilow = 0, ihigh = INT_MAX; - if (!_PyEval_SliceIndex(v, &ilow)) - return -1; - if (!_PyEval_SliceIndex(w, &ihigh)) - return -1; - if (x == NULL) - return PySequence_DelSlice(u, ilow, ihigh); - else - return PySequence_SetSlice(u, ilow, ihigh, x); - } - else { - PyObject *slice = PySlice_New(v, w, NULL); - if (slice != NULL) { - int res; - if (x != NULL) - res = PyObject_SetItem(u, slice, x); - else - res = PyObject_DelItem(u, slice); - Py_DECREF(slice); - return res; - } - else - return -1; - } - } -} - -BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end) -{ - return object( - detail::new_reference( - apply_slice(target.ptr(), begin.get(), end.get()))); -} - -BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value) -{ - if (assign_slice( - target.ptr(), begin.get(), end.get(), value.ptr()) == -1 - ) - { - throw_error_already_set(); - } -} - -BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end) -{ - if (assign_slice( - target.ptr(), begin.get(), end.get(), 0) == -1 - ) - { - throw_error_already_set(); - } -} - -}}} // namespace boost::python::api diff --git a/src/str.cpp b/src/str.cpp deleted file mode 100644 index a8a2383f..00000000 --- a/src/str.cpp +++ /dev/null @@ -1,324 +0,0 @@ -#include -#include - -namespace boost { namespace python { namespace detail { - -detail::new_reference str_base::call(object const& arg_) -{ - return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyString_Type, "(O)", - arg_.ptr()); -} - -str_base::str_base() - : object(detail::new_reference(PyString_FromString(""))) -{} - -str_base::str_base(const char* s) - : object(detail::new_reference(PyString_FromString(s))) -{} - -str_base::str_base(object_cref other) - : object(str_base::call(other)) -{} - -namespace -{ - new_reference new_attr_reference(object const* obj, char const* name) - { - return new_reference(incref(object(obj->attr(name)).ptr())); - } -} - -#define BOOST_PYTHON_FORMAT_OBJECT(z, n, data) "O" -#define BOOST_PYTHON_OBJECT_PTR(z, n, data) , x##n .ptr() - -#define BOOST_PYTHON_DEFINE_STR_METHOD(name, arity) \ -str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const \ -{ \ - return str(new_reference( \ - expect_non_null( \ - PyObject_CallMethod( \ - this->ptr(), #name, \ - "(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \ - BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \ -} - -BOOST_PYTHON_DEFINE_STR_METHOD(capitalize, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(center, 1) - -long str_base::count(object_cref sub) const -{ - return extract(this->attr("count")(sub)); -} - -long str_base::count(object_cref sub, object_cref start) const -{ - return extract(this->attr("count")(sub,start)); -} - -long str_base::count(object_cref sub, object_cref start, object_cref end) const -{ - return extract(this->attr("count")(sub,start,end)); -} - -object str_base::decode() const -{ - return this->attr("decode")(); -} - -object str_base::decode(object_cref encoding) const -{ - return this->attr("decode")(encoding); -} - -object str_base::decode(object_cref encoding, object_cref errors) const -{ - return this->attr("decode")(encoding,errors); -} - -object str_base::encode() const -{ - return this->attr("encode")(); -} - -object str_base::encode(object_cref encoding) const -{ - return this->attr("encode")(encoding); -} - -object str_base::encode(object_cref encoding, object_cref errors) const -{ - return this->attr("encode")(encoding,errors); -} - -bool str_base::endswith(object_cref suffix) const -{ - bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 1) - -long str_base::find(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("find")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::find(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("find")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::find(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::index(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("index")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::index(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("index")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::index(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isalnum() const -{ - bool result = PyInt_AsLong(this->attr("isalnum")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isalpha() const -{ - bool result = PyInt_AsLong(this->attr("isalpha")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isdigit() const -{ - bool result = PyInt_AsLong(this->attr("isdigit")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::islower() const -{ - bool result = PyInt_AsLong(this->attr("islower")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isspace() const -{ - bool result = PyInt_AsLong(this->attr("isspace")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::istitle() const -{ - bool result = PyInt_AsLong(this->attr("istitle")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isupper() const -{ - bool result = PyInt_AsLong(this->attr("isupper")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(join, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(ljust, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(lower, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(lstrip, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(replace, 2) -BOOST_PYTHON_DEFINE_STR_METHOD(replace, 3) - -long str_base::rfind(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("rfind")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rfind(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rfind(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rindex(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("rindex")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rindex(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rindex(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(rjust, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(rstrip, 0) - -list str_base::split() const -{ - return list(this->attr("split")()); -} - -list str_base::split(object_cref sep) const -{ - return list(this->attr("split")(sep)); -} - -list str_base::split(object_cref sep, object_cref maxsplit) const -{ - return list(this->attr("split")(sep,maxsplit)); -} - -list str_base::splitlines() const -{ - return list(this->attr("splitlines")()); -} - -list str_base::splitlines(object_cref keepends) const -{ - return list(this->attr("splitlines")(keepends)); -} - -bool str_base::startswith(object_cref prefix) const -{ - bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::startswith(object_cref prefix, object_cref start) const -{ - bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::startswith(object_cref prefix, object_cref start, object_cref end) const -{ - bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(strip, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(swapcase, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(title, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(translate, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2) -BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0) - -}}} // namespace boost::python diff --git a/src/tuple.cpp b/src/tuple.cpp deleted file mode 100644 index 2762ab27..00000000 --- a/src/tuple.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include - -namespace boost { namespace python { namespace detail { - -detail::new_reference tuple_base::call(object const& arg_) -{ - return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyTuple_Type, "(O)", - arg_.ptr()); -} - -tuple_base::tuple_base() - : object(detail::new_reference(PyTuple_New(0))) -{} - -tuple_base::tuple_base(object_cref sequence) - : object(call(sequence)) -{} - -}}} // namespace boost::python diff --git a/test/args.cpp b/test/args.cpp deleted file mode 100644 index a65933cb..00000000 --- a/test/args.cpp +++ /dev/null @@ -1,92 +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 "test_class.hpp" - -using namespace boost::python; - -tuple f(int x = 1, double y = 4.25, char const* z = "wow") -{ - return make_tuple(x, y, z); -} - -BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3) - -typedef test_class<> Y; - -struct X -{ - X(int a0 = 0, int a1 = 1) : inner0(a0), inner1(a1) {} - tuple f(int x = 1, double y = 4.25, char const* z = "wow") - { - return make_tuple(x, y, z); - } - - Y const& inner(bool n) const { return n ? inner1 : inner0; } - - Y inner0; - Y inner1; -}; - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3) - - -tuple raw_func(tuple args, dict kw) -{ - return make_tuple(args, kw); -} - -BOOST_PYTHON_MODULE(args_ext) -{ - def("f", f, args("x", "y", "z") - , "This is f's docstring" - ); - - def("raw", raw_function(raw_func)); - -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 - // MSVC6 gives a fatal error LNK1179: invalid or corrupt file: - // duplicate comdat error if we try to re-use the exact type of f - // here, so substitute long for int. - tuple (*f)(long,double,char const*) = 0; -#endif - def("f1", f, f_overloads("f1's docstring", args("x", "y", "z"))); - def("f2", f, f_overloads(args("x", "y", "z"))); - def("f3", f, f_overloads(args("x", "y", "z"), "f3's docstring")); - - class_("Y", init(args("value"), "Y's docstring")) - .def("value", &Y::value) - .def("raw", raw_function(raw_func)) - ; - - class_("X", "This is X's docstring") - .def(init >(args("a0", "a1"))) - .def("f", &X::f - , "This is X.f's docstring" - , args("x", "y", "z")) - - // Just to prove that all the different argument combinations work - .def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring") - .def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n")) - - .def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring") - .def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n")) - - .def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>()) - .def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>()) - - .def("f1", &X::f, X_f_overloads(args("x", "y", "z"))) - ; - - def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>()); -} diff --git a/test/args.py b/test/args.py deleted file mode 100644 index 2c9218b1..00000000 --- a/test/args.py +++ /dev/null @@ -1,169 +0,0 @@ -""" ->>> from args_ext import * - ->>> raw(3, 4, foo = 'bar', baz = 42) -((3, 4), {'foo': 'bar', 'baz': 42}) - ->>> f(x= 1, y = 3, z = 'hello') -(1, 3.0, 'hello') - ->>> f(z = 'hello', x = 3, y = 2.5) -(3, 2.5, 'hello') - ->>> f(1, z = 'hi', y = 3) -(1, 3.0, 'hi') - ->>> try: f(1, 2, 'hello', bar = 'baz') -... except TypeError: pass -... else: print 'expected an exception: unknown keyword' - - - Exercise the functions using default stubs - ->>> f1(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> f1(y = .125, x = 2) -(2, 0.125, 'wow') ->>> f1(x = 2) -(2, 4.25, 'wow') ->>> f1() -(1, 4.25, 'wow') - ->>> f2(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> f2(y = .125, x = 2) -(2, 0.125, 'wow') ->>> f2(x = 2) -(2, 4.25, 'wow') ->>> f2() -(1, 4.25, 'wow') - ->>> f3(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> f3(y = .125, x = 2) -(2, 0.125, 'wow') ->>> f3(x = 2) -(2, 4.25, 'wow') ->>> f3() -(1, 4.25, 'wow') - - Member function tests - ->>> q = X() ->>> q.f(x= 1, y = 3, z = 'hello') -(1, 3.0, 'hello') - ->>> q.f(z = 'hello', x = 3, y = 2.5) -(3, 2.5, 'hello') - ->>> q.f(1, z = 'hi', y = 3) -(1, 3.0, 'hi') - ->>> try: q.f(1, 2, 'hello', bar = 'baz') -... except TypeError: pass -... else: print 'expected an exception: unknown keyword' - - Exercise member functions using default stubs - ->>> q.f1(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> q.f1(y = .125, x = 2) -(2, 0.125, 'wow') ->>> q.f1(x = 2) -(2, 4.25, 'wow') ->>> q.f1() -(1, 4.25, 'wow') - ->>> X.f.__doc__ -"This is X.f's docstring" - ->>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5) ->>> for f in xfuncs: -... print f(q,1).value(), -... print f(q, n = 1).value(), -... print f(q, n = 0).value(), -... print f.__doc__ -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring - ->>> x = X(a1 = 44, a0 = 22) ->>> x.inner0(0).value() -22 ->>> x.inner0(1).value() -44 - ->>> x = X(a0 = 7) ->>> x.inner0(0).value() -7 ->>> x.inner0(1).value() -1 - ->>> inner(n = 1, self = q).value() -1 - ->>> y = Y(value = 33) ->>> y.raw(this = 1, that = 'the other')[1] -{'this': 1, 'that': 'the other'} - -""" -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/test/as_to_python_function.cpp b/test/as_to_python_function.cpp deleted file mode 100644 index 814749d1..00000000 --- a/test/as_to_python_function.cpp +++ /dev/null @@ -1,14 +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 - -struct hopefully_illegal -{ - static PyObject* convert(int&); -}; - -PyObject* x = boost::python::converter::as_to_python_function::convert(0); diff --git a/test/auto_ptr.cpp b/test/auto_ptr.cpp deleted file mode 100644 index 22e2df73..00000000 --- a/test/auto_ptr.cpp +++ /dev/null @@ -1,91 +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 "test_class.hpp" -#include - -using namespace boost::python; - -typedef test_class<> X; - -struct Y : X -{ - Y(int n) : X(n) {}; -}; - -int look(std::auto_ptr const& x) -{ - return (x.get()) ? x->value() : -1; -} - -int steal(std::auto_ptr x) -{ - return x->value(); -} - -int maybe_steal(std::auto_ptr& x, bool doit) -{ - int n = x->value(); - if (doit) - x.release(); - return n; -} - -std::auto_ptr make() -{ - return std::auto_ptr(new X(77)); -} - -std::auto_ptr callback(object f) -{ - std::auto_ptr x(new X(77)); - return call >(f.ptr(), x); -} - -std::auto_ptr extract_(object o) -{ - return extract&>(o) -#if BOOST_MSVC <= 1300 - () -#endif - ; -} - -BOOST_PYTHON_MODULE(auto_ptr_ext) -{ - class_, boost::noncopyable>("X", init()) - .def("value", &X::value) - ; - - class_, bases, boost::noncopyable>("Y", init()) - ; - - // VC6 auto_ptrs do not have converting constructors -#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 306) - scope().attr("broken_auto_ptr") = 1; -#else - scope().attr("broken_auto_ptr") = 0; - implicitly_convertible, std::auto_ptr >(); -#endif - - def("look", look); - def("steal", steal); - def("maybe_steal", maybe_steal); - def("make", make); - def("callback", callback); - def("extract", extract_); -} - -#include "module_tail.cpp" - diff --git a/test/auto_ptr.py b/test/auto_ptr.py deleted file mode 100644 index cd83208f..00000000 --- a/test/auto_ptr.py +++ /dev/null @@ -1,77 +0,0 @@ -''' ->>> from auto_ptr_ext import * ->>> x = X(42) ->>> x.value() -42 ->>> look(x), look(x) -(42, 42) - ->>> maybe_steal(x, 0) -42 ->>> look(x) -42 - ->>> maybe_steal(x, 1) -42 ->>> broken_auto_ptr and -1 or look(x) --1 - ->>> x = X(69) ->>> steal(x) -69 ->>> broken_auto_ptr and -1 or look(x) --1 - ->>> if not broken_auto_ptr: -... try: x.value() -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> x = make() ->>> look(x) -77 - ->>> z = callback(lambda z: z) ->>> z.value() -77 - ->>> extract(x).value() -77 - -# -# Test derived to base conversions -# - ->>> y = Y(42) ->>> y.value() -42 - ->>> try: maybe_steal(y, 0) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> y.value() -42 - ->>> broken_auto_ptr and 42 or steal(y) -42 - ->>> if not broken_auto_ptr: -... try: y.value() -... except TypeError: pass -... else: print 'expected a TypeError exception' - -''' - -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/test/back_reference.cpp b/test/back_reference.cpp deleted file mode 100644 index 75233c6b..00000000 --- a/test/back_reference.cpp +++ /dev/null @@ -1,111 +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 - -// This test shows that a class can be wrapped "as itself" but also -// acquire a back-reference iff has_back_reference<> is appropriately -// specialized. -using namespace boost::python; - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; - -int X::counter; - -struct Y : X -{ - Y(PyObject* self, int x) : X(x) {}; - Y(PyObject* self, Y const& rhs) : X(rhs), self(self) {}; - private: - Y(Y const&); - PyObject* self; -}; - -struct Z : X -{ - Z(PyObject* self, int x) : X(x) {}; - Z(PyObject* self, Z const& rhs) : X(rhs), self(self) {}; - private: - Z(Z const&); - PyObject* self; -}; - -Y const& copy_Y(Y const& y) { return y; } -Z const& copy_Z(Z const& z) { return z; } - -namespace boost { namespace python -{ - template <> - struct has_back_reference - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template <> - struct has_back_reference - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; -}} - -// prove that back_references get initialized with the right PyObject* -object y_identity(back_reference y) -{ - return y.source(); -} - -// prove that back_references contain the right value -bool y_equality(back_reference y1, Y const& y2) -{ - return &y1.get() == &y2; -} - -BOOST_PYTHON_MODULE(back_reference_ext) -{ - def("copy_Y", copy_Y, return_value_policy()); - def("copy_Z", copy_Z, return_value_policy()); - def("x_instances", &X::count); - - class_("Y", init()) - .def("value", &Y::value) - .def("set", &Y::set) - ; - - class_ >("Z", init()) - .def("value", &Z::value) - .def("set", &Z::set) - ; - - def("y_identity", y_identity); - def("y_equality", y_equality); - -} - -#include "module_tail.cpp" diff --git a/test/back_reference.py b/test/back_reference.py deleted file mode 100644 index 7eac13c3..00000000 --- a/test/back_reference.py +++ /dev/null @@ -1,29 +0,0 @@ -''' ->>> from back_reference_ext import * ->>> y = Y(3) ->>> z = Z(4) ->>> x_instances() -2 ->>> y2 = copy_Y(y) ->>> x_instances() -3 ->>> z2 = copy_Z(z) ->>> x_instances() -4 ->>> assert y_identity(y) is y ->>> y_equality(y, y) -1 -''' - -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/test/bases.cpp b/test/bases.cpp deleted file mode 100644 index e4f91990..00000000 --- a/test/bases.cpp +++ /dev/null @@ -1,63 +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 - -struct A; -struct B; - -template -struct choose_bases - : boost::python::detail::select_bases< - X - , typename boost::python::detail::select_bases< - Y - , typename boost::python::detail::select_bases::type - >::type> -{ - -}; - -int main() -{ - BOOST_STATIC_ASSERT((boost::python::detail::specifies_bases< - boost::python::bases >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - boost::python::bases& >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - void* >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - int >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - int[5] >::value)); - - typedef boost::python::detail::select_bases< - int - , boost::python::detail::select_bases::type > collected1; - - BOOST_STATIC_ASSERT((boost::is_same >::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,boost::python::bases<> >::value)); - - typedef boost::python::detail::select_bases< - int - , boost::python::detail::select_bases< - boost::python::bases - , boost::python::detail::select_bases< - A - >::type - >::type - > collected2; - - BOOST_STATIC_ASSERT((boost::is_same >::value)); - BOOST_STATIC_ASSERT((boost::is_same,long>::type,boost::python::bases >::value)); - - return 0; -} diff --git a/test/ben_scott1.cpp b/test/ben_scott1.cpp deleted file mode 100644 index 3c0d5522..00000000 --- a/test/ben_scott1.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -using namespace boost::python; -using namespace boost; - -struct Product {}; -typedef shared_ptr ProductPtr; - - -struct Creator -{ - virtual ~Creator() {} - virtual ProductPtr create() = 0; -}; - - -struct Factory -{ - void reg(Creator* c) { mC = c; } - ProductPtr create() - { - std::cout << "Name: " << (typeid(*mC)).name() << std::endl; - return mC->create(); - } - -private: - Creator* mC; -}; - -struct CreatorWrap : public Creator -{ - CreatorWrap(PyObject* self) : mSelf(self) {} - ProductPtr create() { return call_method(mSelf, "create"); } - PyObject* mSelf; -}; - -BOOST_PYTHON_MODULE(ben_scott1_ext) -{ - class_("Product"); - - class_("Creator") - .def("create", &CreatorWrap::create) - ; - - class_("Factory") - .def("reg", &Factory::reg, with_custodian_and_ward<1,2>()) - .def("create", &Factory::create) - ; -} - -#include "../test/module_tail.cpp" diff --git a/test/ben_scott1.py b/test/ben_scott1.py deleted file mode 100644 index 1475e3d0..00000000 --- a/test/ben_scott1.py +++ /dev/null @@ -1,14 +0,0 @@ -# This regression test checks that call_method(...) where T is a -# non-reference, non-pointer type that happens to be held inside the -# result object (and thus is found as an lvalue) works. -from ben_scott1_ext import * - -class CreatorImpl(Creator): - def create(self): - return Product() - -factory = Factory() -c = CreatorImpl() -factory.reg(c) - -a = factory.create() diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp deleted file mode 100644 index 4f3b107d..00000000 --- a/test/bienstman1.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include - -struct A {}; - -struct V -{ - - virtual void f() = 0; - - const A* inside() {return &a;} - - A a; -}; - -const A* outside(const V& v) {return &v.a;} - -BOOST_PYTHON_MODULE(bienstman1_ext) -{ - using namespace boost::python; - using boost::shared_ptr; - using boost::python::return_value_policy; - using boost::python::reference_existing_object; - - class_("A"); - - class_("V", no_init) - .def("inside", &V::inside, - return_value_policy()) - .def("outside", outside, - return_value_policy()) - ; -} - diff --git a/test/bienstman1.py b/test/bienstman1.py deleted file mode 100644 index d5ec22b5..00000000 --- a/test/bienstman1.py +++ /dev/null @@ -1,18 +0,0 @@ -''' -# Try to reproduce a Numeric interaction bug if Numeric is installed. ->>> from bienstman1_ext import * ->>> try: from Numeric import * -... except: pass -''' -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/test/bienstman2.cpp b/test/bienstman2.cpp deleted file mode 100644 index 17ade499..00000000 --- a/test/bienstman2.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -struct C {}; - -struct D {}; - -struct E -{ - const D fe (const C&) {return D();} - const D fe2(const C&, const C&) {return D();} -}; - -BOOST_PYTHON_MODULE(bienstman2_ext) -{ - using namespace boost::python; - - class_("C"); - class_("D"); - class_("E") - .def("fe", &E::fe) // this compiles. - .def("fe2", &E::fe2) // this doesn't... well, now it does ;-) - ; -} diff --git a/test/bienstman2.py b/test/bienstman2.py deleted file mode 100644 index 45ee4134..00000000 --- a/test/bienstman2.py +++ /dev/null @@ -1,15 +0,0 @@ -''' ->>> import bienstman2_ext -''' -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/test/bienstman3.cpp b/test/bienstman3.cpp deleted file mode 100644 index 9248ef8f..00000000 --- a/test/bienstman3.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -struct V -{ - virtual void f() = 0; -}; - -struct B -{ - B(const V&) {} -}; - -BOOST_PYTHON_MODULE(bienstman3_ext) -{ - using namespace boost::python; - - class_("V", no_init); - class_("B", init()); - -} diff --git a/test/bienstman3.py b/test/bienstman3.py deleted file mode 100644 index 90efdd53..00000000 --- a/test/bienstman3.py +++ /dev/null @@ -1,25 +0,0 @@ -''' ->>> from bienstman3_ext import * - ->>> try: -... V() -... except RuntimeError, x: -... print x -... else: -... print 'expected an exception' -... -This class cannot be instantiated from Python - -''' -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/test/bienstman4.cpp b/test/bienstman4.cpp deleted file mode 100644 index 124d76a5..00000000 --- a/test/bienstman4.cpp +++ /dev/null @@ -1,40 +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 - -struct Type1 {}; - -struct Term {Term(Type1 const&) {} }; - -struct Expression {void add(Term const&) {} }; - -BOOST_PYTHON_MODULE(bienstman4_ext) -{ - using namespace boost::python; - using boost::mpl::list; - - implicitly_convertible(); - - class_("Expression") - .def("add", &Expression::add) - ; - - class_("T1") - ; - - class_("Term", init()) - ; - - Type1 t1; - Expression e; - e.add(t1); -} - diff --git a/test/bienstman4.py b/test/bienstman4.py deleted file mode 100644 index 2fede1fc..00000000 --- a/test/bienstman4.py +++ /dev/null @@ -1,18 +0,0 @@ -''' ->>> from bienstman4_ext import * ->>> t1 = T1() ->>> e = Expression() ->>> e.add(t1) -''' -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/test/bienstman5.cpp b/test/bienstman5.cpp deleted file mode 100644 index 72875663..00000000 --- a/test/bienstman5.cpp +++ /dev/null @@ -1,24 +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 - -struct M {M(const std::complex&) {} }; - -BOOST_PYTHON_MODULE(bienstman5_ext) -{ - using namespace boost::python; - - class_("M", init const&>()) - ; -} - - diff --git a/test/bienstman5.py b/test/bienstman5.py deleted file mode 100644 index 10c35ff4..00000000 --- a/test/bienstman5.py +++ /dev/null @@ -1,16 +0,0 @@ -''' ->>> from bienstman5_ext import * ->>> m = M(1j) -''' -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/test/borrowed.cpp b/test/borrowed.cpp deleted file mode 100755 index 0f8d3112..00000000 --- a/test/borrowed.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -using namespace boost::python; - -template -void assert_borrowed_ptr(T const& x) -{ - BOOST_STATIC_ASSERT(boost::python::detail::is_borrowed_ptr::value); -} - -template -void assert_not_borrowed_ptr(T const& x) -{ - BOOST_STATIC_ASSERT(!boost::python::detail::is_borrowed_ptr::value); -} - -int main() -{ - assert_borrowed_ptr(borrowed((PyObject*)0)); - assert_borrowed_ptr(borrowed((PyTypeObject*)0)); - assert_borrowed_ptr((detail::borrowed const*)0); - assert_borrowed_ptr((detail::borrowed volatile*)0); - assert_borrowed_ptr((detail::borrowed const volatile*)0); - assert_not_borrowed_ptr((PyObject*)0); - assert_not_borrowed_ptr(0); - return 0; -} diff --git a/test/callbacks.cpp b/test/callbacks.cpp deleted file mode 100644 index 1cfe2914..00000000 --- a/test/callbacks.cpp +++ /dev/null @@ -1,148 +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 - -using namespace boost::python; -BOOST_STATIC_ASSERT(converter::is_object_manager >::value); - -int apply_int_int(PyObject* f, int x) -{ - return call(f, x); -} - -void apply_void_int(PyObject* f, int x) -{ - call(f, x); -} - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; - -X apply_X_X(PyObject* f, X x) -{ - return call(f, x); -} - -void apply_void_X_ref(PyObject* f, X& x) -{ - call(f, boost::ref(x)); -} - -X& apply_X_ref_handle(PyObject* f, handle<> obj) -{ - return call(f, obj); -} - -X* apply_X_ptr_handle_cref(PyObject* f, handle<> const& obj) -{ - return call(f, obj); -} - -void apply_void_X_cref(PyObject* f, X const& x) -{ - call(f, boost::cref(x)); -} - -void apply_void_X_ptr(PyObject* f, X* x) -{ - call(f, ptr(x)); -} - -void apply_void_X_deep_ptr(PyObject* f, X* x) -{ - call(f, x); -} - -char const* apply_cstring_cstring(PyObject* f, char const* s) -{ - return call(f, s); -} - -char const* apply_cstring_pyobject(PyObject* f, PyObject* s) -{ - return call(f, borrowed(s)); -} - -char apply_char_char(PyObject* f, char c) -{ - return call(f, c); -} - -char const* apply_to_string_literal(PyObject* f) -{ - return call(f, "hello, world"); -} - -handle<> apply_to_own_type(handle<> x) -{ - // Tests that we can return handle<> from a callback and that we - // can pass arbitrary handle. - return call >(x.get(), type_handle(borrowed(x->ob_type))); -} - -object apply_object_object(PyObject* f, object x) -{ - return call(f, x); -} - -int X::counter; - -BOOST_PYTHON_MODULE(callbacks_ext) -{ - def("apply_object_object", apply_object_object); - def("apply_to_own_type", apply_to_own_type); - def("apply_int_int", apply_int_int); - def("apply_void_int", apply_void_int); - def("apply_X_X", apply_X_X); - def("apply_void_X_ref", apply_void_X_ref); - def("apply_void_X_cref", apply_void_X_cref); - def("apply_void_X_ptr", apply_void_X_ptr); - def("apply_void_X_deep_ptr", apply_void_X_deep_ptr); - - def("apply_X_ptr_handle_cref", apply_X_ptr_handle_cref - , return_value_policy()); - - def("apply_X_ref_handle", apply_X_ref_handle - , return_value_policy()); - - def("apply_cstring_cstring", apply_cstring_cstring); - def("apply_cstring_pyobject", apply_cstring_pyobject); - def("apply_char_char", apply_char_char); - def("apply_to_string_literal", apply_to_string_literal); - - - class_("X", init()) - .def(init()) - .def("value", &X::value) - .def("set", &X::set) - ; - - def("x_count", &X::count); -} - -#include "module_tail.cpp" diff --git a/test/callbacks.py b/test/callbacks.py deleted file mode 100644 index 937961fd..00000000 --- a/test/callbacks.py +++ /dev/null @@ -1,133 +0,0 @@ -''' ->>> from callbacks_ext import * - ->>> def double(x): -... return x + x -... ->>> apply_int_int(double, 42) -84 ->>> apply_void_int(double, 42) - ->>> def identity(x): -... return x - -Once we have array conversion support, this test will fail. Er, -succeed: - ->>> try: apply_to_string_literal(identity) -... except: pass # expected -... else: print 'expected an exception!' - ->>> x = apply_X_X(identity, X(42)) ->>> x.value() -42 ->>> x_count() -1 ->>> del x ->>> x_count() -0 - ->>> def increment(x): -... x.set(x.value() + 1) -... ->>> x = X(42) ->>> apply_void_X_ref(increment, x) ->>> x.value() -43 - ->>> apply_void_X_cref(increment, x) ->>> x.value() # const-ness is not respected, sorry! -44 - ->>> last_x = 1 ->>> def decrement(x): -... global last_x -... last_x = x -... if x is not None: -... x.set(x.value() - 1) - ->>> apply_void_X_ptr(decrement, x) ->>> x.value() -43 ->>> last_x.value() -43 ->>> increment(last_x) ->>> x.value() -44 ->>> last_x.value() -44 - ->>> apply_void_X_ptr(decrement, None) ->>> assert last_x is None ->>> x.value() -44 - ->>> last_x = 1 ->>> apply_void_X_deep_ptr(decrement, None) ->>> assert last_x is None ->>> x.value() -44 - ->>> apply_void_X_deep_ptr(decrement, x) ->>> x.value() -44 ->>> last_x.value() -43 - ->>> y = apply_X_ref_handle(identity, x) ->>> assert y.value() == x.value() ->>> increment(x) ->>> assert y.value() == x.value() - ->>> y = apply_X_ptr_handle_cref(identity, x) ->>> assert y.value() == x.value() ->>> increment(x) ->>> assert y.value() == x.value() - ->>> y = apply_X_ptr_handle_cref(identity, None) ->>> y - ->>> def new_x(ignored): -... return X(666) -... ->>> try: apply_X_ref_handle(new_x, 1) -... except ReferenceError: pass -... else: print 'no error' - ->>> try: apply_X_ptr_handle_cref(new_x, 1) -... except ReferenceError: pass -... else: print 'no error' - ->>> try: apply_cstring_cstring(identity, 'hello') -... except ReferenceError: pass -... else: print 'no error' - ->>> apply_char_char(identity, 'x') -'x' - ->>> apply_cstring_pyobject(identity, 'hello') -'hello' - ->>> apply_cstring_pyobject(identity, None) - - ->>> apply_char_char(identity, 'x') -'x' - ->>> assert apply_to_own_type(identity) is type(identity) - ->>> assert apply_object_object(identity, identity) is identity -''' - -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/test/cltree.cpp b/test/cltree.cpp deleted file mode 100755 index 099d5cb7..00000000 --- a/test/cltree.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include - -/* Non-modifiable definitions */ - -class basic { -public: - basic() { name = "cltree.basic"; } - std::string repr() { return name+"()"; } -protected: - std::string name; -}; - -class constant: public basic { -public: - constant() { name = "cltree.constant"; } -}; - -class symbol: public basic { -public: - symbol() { name = "cltree.symbol"; } -}; - -class variable: public basic { -public: - variable() { name = "cltree.variable"; } -}; - -/* EOF: Non-modifiable definitions */ - -class symbol_wrapper: public symbol { -public: - symbol_wrapper(PyObject* self): symbol() { - name = "cltree.wrapped_symbol"; - } -}; - -class variable_wrapper: public variable { -public: - variable_wrapper(PyObject* self): variable() { - name = "cltree.wrapped_variable"; - } - - // This constructor is introduced only because cannot use - // boost::noncopyable, see below. - variable_wrapper(PyObject* self,variable v): variable(v) {} - -}; - -BOOST_PYTHON_MODULE(cltree) -{ - boost::python::class_("basic") - .def("__repr__",&basic::repr) - ; - - boost::python::class_, boost::noncopyable>("constant") - ; - - - boost::python::class_("symbol") - ; - - boost::python::class_, variable_wrapper>("variable") - ; -} - -#include "module_tail.cpp" - 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/copy_ctor_mutates_rhs.cpp b/test/copy_ctor_mutates_rhs.cpp deleted file mode 100755 index 7244ab0e..00000000 --- a/test/copy_ctor_mutates_rhs.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in 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 - -struct foo -{ - operator std::auto_ptr&() const; -}; - -int main() -{ - using namespace boost::python::detail; - BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value); - BOOST_STATIC_ASSERT(copy_ctor_mutates_rhs >::value); - BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value); - BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value); - return 0; -} diff --git a/test/data_members.cpp b/test/data_members.cpp deleted file mode 100644 index 13c46b0d..00000000 --- a/test/data_members.cpp +++ /dev/null @@ -1,80 +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 "test_class.hpp" - -#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -# include // works around a KCC intermediate code generation bug -#endif - - -using namespace boost::python; - -typedef test_class<> X; - -typedef test_class<1> Y; - -double get_fair_value(X const& x) { return x.value(); } - - -struct VarBase -{ - VarBase(std::string name_) : name(name_) {} - - std::string const name; - std::string get_name1() const { return name; } -}; - -struct Var : VarBase -{ - Var(std::string name_) : VarBase(name_), value(), name2(name.c_str()), y(6) {} - std::string const& get_name2() const { return name; } - float value; - char const* name2; - Y y; -}; - -BOOST_PYTHON_MODULE(data_members_ext) -{ - class_("X", init()) - .def("value", &X::value) - .def("set", &X::set) - .def_readonly("x", &X::x) - .add_property("fair_value", get_fair_value) - ; - - class_("Y", init()) - .def("value", &Y::value) - .def("set", &Y::set) - .def_readwrite("x", &Y::x) - ; - - class_("Var", init()) - .def_readonly("name", &Var::name) - .def_readonly("name2", -#if __MWERKS__ <= 0x2407 // Old MWerks mis-deduces the type here as `char* Var::*' - (char const* Var::*) -#endif - &Var::name2 - ) - .def_readwrite("value", &Var::value) - .def_readonly("y", &Var::y) - - // Test return_by_value for plain values and for - // pointers... return_by_value was implemented as a - // side-effect of implementing data member support, so it made - // sense to add the test here. - .def("get_name1", &Var::get_name1, return_value_policy()) - .def("get_name2", &Var::get_name2, return_value_policy()) - - .add_property("name3", &Var::get_name1) - ; -} - -#include "module_tail.cpp" diff --git a/test/data_members.py b/test/data_members.py deleted file mode 100644 index 989c3c32..00000000 --- a/test/data_members.py +++ /dev/null @@ -1,55 +0,0 @@ -''' ->>> from data_members_ext import * - ->>> x = X(42) ->>> x.x -42 ->>> try: x.x = 77 -... except AttributeError: pass -... else: print 'no error' - ->>> x.fair_value -42.0 ->>> y = Y(69) ->>> y.x -69 ->>> y.x = 77 ->>> y.x -77 - ->>> v = Var("pi") ->>> v.value = 3.14 ->>> v.name -'pi' ->>> v.name2 -'pi' - ->>> v.get_name1() -'pi' - ->>> v.get_name2() -'pi' - ->>> v.y.x -6 ->>> v.y.x = -7 ->>> v.y.x --7 - ->>> v.name3 -'pi' - -''' - -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/test/defaults.cpp b/test/defaults.cpp deleted file mode 100644 index 1c173a79..00000000 --- a/test/defaults.cpp +++ /dev/null @@ -1,173 +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 - -#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -# include // works around a KCC intermediate code generation bug -#endif - -using namespace boost::python; - -char const* const format = "int(%s); char(%s); string(%s); double(%s); "; - -/////////////////////////////////////////////////////////////////////////////// -// -// Overloaded functions -// -/////////////////////////////////////////////////////////////////////////////// -object -bar(int a, char b, std::string c, double d) -{ - return format % make_tuple(a, b, c, d); -} - -object -bar(int a, char b, std::string c) -{ - return format % make_tuple(a, b, c, 0.0); -} - -object -bar(int a, char b) -{ - return format % make_tuple(a, b, "default", 0.0); -} - -object -bar(int a) -{ - return format % make_tuple(a, 'D', "default", 0.0); -} - -BOOST_PYTHON_FUNCTION_OVERLOADS(bar_stubs, bar, 1, 4) - -/////////////////////////////////////////////////////////////////////////////// -// -// Functions with default arguments -// -/////////////////////////////////////////////////////////////////////////////// -object -foo(int a, char b = 'D', std::string c = "default", double d = 0.0) -{ - return format % make_tuple(a, b, c, d); -} - -BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) - -/////////////////////////////////////////////////////////////////////////////// -// -// Overloaded member functions with default arguments -// -/////////////////////////////////////////////////////////////////////////////// -struct Y { - - Y() {} - - object - get_state() const - { - return format % make_tuple(a, b, c, d); - } - - int a; char b; std::string c; double d; -}; - - -struct X { - - X() {} - - X(int a, char b = 'D', std::string c = "constructor", double d = 0.0) - : state(format % make_tuple(a, b, c, d)) - {} - - X(std::string s, bool b) - : state("Got exactly two arguments from constructor: string(%s); bool(%s); " % make_tuple(s, b)) - {} - - object - bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const - { - return format % make_tuple(a, b, c, d); - } - - Y const& - bar2(int a = 0, char b = 'D', std::string c = "default", double d = 0.0) - { - // tests zero arg member function and return_internal_reference policy - y.a = a; - y.b = b; - y.c = c; - y.d = d; - return y; - } - - object - foo(int a, bool b=false) const - { - return "int(%s); bool(%s); " % make_tuple(a, b); - } - - object - foo(std::string a, bool b=false) const - { - return "string(%s); bool(%s); " % make_tuple(a, b); - } - - object - foo(list a, list b, bool c=false) const - { - return "list(%s); list(%s); bool(%s); " % make_tuple(a, b, c); - } - - object - get_state() const - { - return state; - } - - Y y; - object state; -}; - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs, bar, 1, 4) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs2, bar2, 0, 4) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) - -/////////////////////////////////////////////////////////////////////////////// - -BOOST_PYTHON_MODULE(defaults_ext) -{ - def("foo", foo, foo_stubs()); - def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()); - - class_("Y", init<>("doc of Y init")) // this should work - .def("get_state", &Y::get_state) - ; - - class_("X") - - .def(init >("doc of init")) - .def(init()[default_call_policies()]) // what's a good policy here? - .def("get_state", &X::get_state) - .def("bar", &X::bar, X_bar_stubs()) - .def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()]) - .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) - .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) - .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) - ; -} - -#include "module_tail.cpp" - diff --git a/test/defaults.py b/test/defaults.py deleted file mode 100644 index 168c5de3..00000000 --- a/test/defaults.py +++ /dev/null @@ -1,174 +0,0 @@ -""" ->>> False = 0 # Python 2.2 needs these ->>> True = 1 - ->>> from defaults_ext import * ->>> bar(1) -'int(1); char(D); string(default); double(0.0); ' - ->>> bar(2, 'X') -'int(2); char(X); string(default); double(0.0); ' - ->>> bar(3, 'Y', "Hello World") -'int(3); char(Y); string(Hello World); double(0.0); ' - ->>> bar(4, 'Z', "Hi There", 3.3) -'int(4); char(Z); string(Hi There); double(3.3); ' - ->>> foo(1) -'int(1); char(D); string(default); double(0.0); ' - ->>> foo(2, 'X') -'int(2); char(X); string(default); double(0.0); ' - ->>> foo(3, 'Y', "Hello World") -'int(3); char(Y); string(Hello World); double(0.0); ' - ->>> foo(4, 'Z', "Hi There", 3.3) -'int(4); char(Z); string(Hi There); double(3.3); ' - ->>> x = X() ->>> x.bar(1) -'int(1); char(D); string(default); double(0.0); ' - ->>> x.bar(2, 'X') -'int(2); char(X); string(default); double(0.0); ' - ->>> x.bar(3, 'Y', "Hello World") -'int(3); char(Y); string(Hello World); double(0.0); ' - ->>> x.bar(4, 'Z', "Hi There", 3.3) -'int(4); char(Z); string(Hi There); double(3.3); ' - ->>> x.foo(5) -'int(5); bool(0); ' - ->>> x.foo(6, 0) -'int(6); bool(0); ' - ->>> x.foo(7, 1) -'int(7); bool(1); ' - ->>> x.foo("A") -'string(A); bool(0); ' - ->>> x.foo("B", False) -'string(B); bool(0); ' - ->>> x.foo("C", True) -'string(C); bool(1); ' - ->>> x.foo([0,1,2], [2,3,4]) -'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' - ->>> x.foo([0,1,2], [2,3,4], False) -'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' - ->>> x.foo([0,1,2], [2,3,4], True) -'list([0, 1, 2]); list([2, 3, 4]); bool(1); ' - ->>> x = X(1) ->>> x.get_state() -'int(1); char(D); string(constructor); double(0.0); ' - ->>> x = X(1, 'X') ->>> x.get_state() -'int(1); char(X); string(constructor); double(0.0); ' - ->>> x = X(1, 'X', "Yabadabadoo") ->>> x.get_state() -'int(1); char(X); string(Yabadabadoo); double(0.0); ' - ->>> x = X(1, 'X', "Phoenix", 3.65) ->>> x.get_state() -'int(1); char(X); string(Phoenix); double(3.65); ' - ->>> x.bar2().get_state() -'int(0); char(D); string(default); double(0.0); ' - ->>> x.bar2(1).get_state() -'int(1); char(D); string(default); double(0.0); ' - ->>> x.bar2(1, 'K').get_state() -'int(1); char(K); string(default); double(0.0); ' - ->>> x.bar2(1, 'K', "Kim").get_state() -'int(1); char(K); string(Kim); double(0.0); ' - ->>> x.bar2(1, 'K', "Kim", 9.9).get_state() -'int(1); char(K); string(Kim); double(9.9); ' - ->>> x = X("Phoenix", 1) ->>> x.get_state() -'Got exactly two arguments from constructor: string(Phoenix); bool(1); ' - ->>> def printdoc(x): -... print x.__doc__ - ->>> printdoc(X.__init__) -doc of init - ->>> printdoc(Y.__init__) -doc of Y init - ->>> printdoc(X.bar2) -doc of X::bar2 - -""" -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/test/destroy_test.cpp b/test/destroy_test.cpp deleted file mode 100644 index 38d5d1d5..00000000 --- a/test/destroy_test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include - -struct bar; - -namespace boost -{ - // lie to the library about bar so we can show that its destructor is optimized away. - template <> - struct has_trivial_destructor - { - BOOST_STATIC_CONSTANT(bool, value=true); - }; -} - - -int count; -int marks[] = { - -1 - , -1, -1 - , -1, -1, -1, -1 - , -1 -}; -int* kills = marks; - -struct foo -{ - foo() : n(count++) {} - ~foo() - { - *kills++ = n; - } - int n; -}; - -struct bar : foo {}; - -void assert_destructions(int n) -{ - for (int i = 0; i < n; ++i) - assert(marks[i] == i); - assert(marks[n] == -1); -} - -int main() -{ - assert_destructions(0); - typedef int a[2]; - - foo* f1 = new foo; - boost::python::detail::destroy_referent(f1); - assert_destructions(1); - - foo* f2 = new foo[2]; - typedef foo x[2]; - - boost::python::detail::destroy_referent(f2); - assert_destructions(3); - - typedef foo y[2][2]; - x* f3 = new y; - boost::python::detail::destroy_referent(f3); - assert_destructions(7); - - bar* b1 = new bar; - boost::python::detail::destroy_referent(b1); - assert_destructions(7); - - bar* b2 = new bar[2]; - typedef bar xb[2]; - - boost::python::detail::destroy_referent(b2); - assert_destructions(7); - - typedef bar yb[2][2]; - xb* b3 = new yb; - boost::python::detail::destroy_referent(b3); - assert_destructions(7); - - return 0; -} diff --git a/test/dict.cpp b/test/dict.cpp deleted file mode 100644 index de6d4a86..00000000 --- a/test/dict.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -object new_dict() -{ - return dict(); -} - -object data_dict() -{ - dict tmp1; - tmp1["key1"] = "value1"; - - dict tmp2; - tmp2["key2"] = "value2"; - tmp1[1] = tmp2; - return tmp1; -} - -object dict_from_sequence(object sequence) -{ - return dict(sequence); -} - -object dict_keys(dict data) -{ - return data.keys(); -} - -object dict_values(dict data) -{ - return data.values(); -} - -object dict_items(dict data) -{ - return data.items(); -} - -void work_with_dict(dict data1, dict data2) -{ - if (!data1.has_key("k1")) { - throw std::runtime_error("dict does not have key 'k1'"); - } - data1.update(data2); -} - -void test_templates(object print) -{ - std::string key = "key"; - - dict tmp; - tmp[1] = "a test string"; - print(tmp.get(1)); - //print(tmp[1]); - tmp[1.5] = 13; - print(tmp.get(1.5)); - print(tmp.get(44)); - print(tmp); - print(tmp.get(2,"default")); - print(tmp.has_key(key)); - print(tmp.setdefault(3,"default")); - //print(tmp[3]); -} - -BOOST_PYTHON_MODULE(dict_ext) -{ - def("new_dict", new_dict); - def("data_dict", data_dict); - def("dict_keys", dict_keys); - def("dict_values", dict_values); - def("dict_items", dict_items); - def("dict_from_sequence", dict_from_sequence); - def("work_with_dict", work_with_dict); - def("test_templates", test_templates); -} diff --git a/test/dict.py b/test/dict.py deleted file mode 100644 index c99d2e9b..00000000 --- a/test/dict.py +++ /dev/null @@ -1,41 +0,0 @@ -""" ->>> from dict_ext import * ->>> def printer(*args): -... for x in args: print x, -... print -... ->>> print new_dict() -{} ->>> print data_dict() -{1: {'key2': 'value2'}, 'key1': 'value1'} ->>> tmp = data_dict() ->>> print dict_keys(tmp) -[1, 'key1'] ->>> print dict_values(tmp) -[{'key2': 'value2'}, 'value1'] ->>> print dict_items(tmp) -[(1, {'key2': 'value2'}), ('key1', 'value1')] ->>> print dict_from_sequence([(1,1),(2,2),(3,3)]) -{1: 1, 2: 2, 3: 3} ->>> test_templates(printer) -a test string -13 -None -{1.5: 13, 1: 'a test string'} -default -0 -default -""" - -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/test/docstring.cpp b/test/docstring.cpp deleted file mode 100644 index 65893d02..00000000 --- a/test/docstring.cpp +++ /dev/null @@ -1,60 +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 "test_class.hpp" - -// Just use math.h here; trying to use std::pow() causes too much -// trouble for non-conforming compilers and libraries. -#include - -using namespace boost::python; - -typedef test_class<> X; - -X* create(int x) -{ - return new X(x); -} - -unsigned long fact(unsigned long n) -{ - return n <= 1 ? n : n * fact(n - 1); -} - -BOOST_PYTHON_MODULE(docstring_ext) -{ - scope().attr("__doc__") = - "A simple test module for documentation strings\n" - "Exercised by docstring.py" - ; - - class_("X", - "A simple class wrapper around a C++ int\n" - "includes some error-checking" - - , init( - "this is the __init__ function\n" - "its documentation has two lines." - ) - - ) - .def("value", &X::value, - "gets the value of the object") - ; - - def("create", create, return_value_policy(), - "creates a new X object"); - - def("fact", fact, "compute the factorial"); -} - -#include "module_tail.cpp" diff --git a/test/docstring.py b/test/docstring.py deleted file mode 100644 index 15cfdaf1..00000000 --- a/test/docstring.py +++ /dev/null @@ -1,54 +0,0 @@ -''' ->>> from docstring_ext import * - ->>> def printdoc(x): -... print x.__doc__ - ->>> printdoc(X) -A simple class wrapper around a C++ int -includes some error-checking - ->>> printdoc(X.__init__) -this is the __init__ function -its documentation has two lines. - ->>> printdoc(X.value) -gets the value of the object - ->>> printdoc(create) -creates a new X object - ->>> printdoc(fact) -compute the factorial -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - - import docstring_ext - - result = doctest.testmod(sys.modules.get(__name__)) - - import pydoc - import re - docmodule = lambda m: re.sub(".\10", "", pydoc.text.docmodule(m)) - try: - print 'printing module help:' - print docmodule(docstring_ext) - except object, x: - print '********* failed **********' - print x - result = list(result) - result[0] += 1 - return tuple(result) - - return result - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/embedding.cpp b/test/embedding.cpp deleted file mode 100644 index 5a86f2cf..00000000 --- a/test/embedding.cpp +++ /dev/null @@ -1,122 +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. - -// embedded_hello -- A simple Boost.Python embedding example -- by -// Dirk Gerrits - -#include -#include -#include -#include - -namespace python = boost::python; - -// An abstract base class -class Base : public boost::noncopyable -{ -public: - virtual ~Base() {}; - - virtual std::string hello() = 0; -}; - -// C++ derived class -class CppDerived : public Base -{ -public: - virtual ~CppDerived() {} - - std::string hello() - { - return "Hello from C++!"; - } -}; - -// Familiar Boost.Python wrapper class for Base -struct BaseWrap : public Base -{ - BaseWrap(PyObject* self_) - : self(self_) {} - - std::string hello() { return python::call_method(self, "hello"); } - - PyObject* self; -}; - -// Pack the Base class wrapper into a module -BOOST_PYTHON_MODULE(embedded_hello) -{ - python::class_("Base") - ; - -} - - -void test() -{ -//- INITIALIZATION -----------------------------------------------------------// - - // Register the module with the interpreter - if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1) - throw std::runtime_error("Failed to add embedded_hello to the interpreter's " - "builtin modules"); - - // Initialize the interpreter - Py_Initialize(); - - // Retrieve the main module - python::handle<> main_module( - python::borrowed(PyImport_AddModule("__main__")) ); - - // Retrieve the main modules namespace - python::handle<> main_namespace( - python::borrowed(PyModule_GetDict(main_module.get())) ); - - // Define the derived class in Python. - // (You'll normally want to put this in a .py file.) - python::handle<> result( - PyRun_String( - "from embedded_hello import * \n" - "class PythonDerived(Base): \n" - " def hello(self): \n" - " return 'Hello from Python!' \n", - Py_file_input, main_namespace.get(), main_namespace.get()) - ); - // Result is not needed - result.reset(); - - // Extract the raw Python object representing the just defined derived class - python::handle<> class_ptr( - PyRun_String("PythonDerived\n", Py_eval_input, - main_namespace.get(), main_namespace.get()) ); - - // Wrap the raw Python object in a Boost.Python object - python::object PythonDerived(class_ptr); - -//- MAIN PROGRAM -------------------------------------------------------------// - - // Creating and using instances of the C++ class is as easy as always. - CppDerived cpp; - std::cout << cpp.hello() << std::endl; - - // But now creating and using instances of the Python class is almost - // as easy! - python::object py_base = PythonDerived(); - Base& py = python::extract(py_base)(); - std::cout << py.hello() << std::endl; -} - -int main() -{ - if (python::handle_exception(test)) - { - if (PyErr_Occurred()) - PyErr_Print(); - return 1; - } - return 0; -} -#include "module_tail.cpp" diff --git a/test/enum.cpp b/test/enum.cpp deleted file mode 100644 index 1a4f178b..00000000 --- a/test/enum.cpp +++ /dev/null @@ -1,48 +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 -#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) -# include -# include -#endif -using namespace boost::python; - -enum color { red = 1, green = 2, blue = 4 }; - -#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) -namespace boost // Pro7 has a hard time detecting enums -{ - template <> struct is_enum : boost::mpl::true_ {}; -} -#endif - -color identity_(color x) { return x; } - -struct colorized { - colorized() : x(red) {} - color x; -}; - -BOOST_PYTHON_MODULE(enum_ext) -{ - enum_("color") - .value("red", red) - .value("green", green) - .value("blue", blue) - .export_values() - ; - - def("identity", identity_); - - class_("colorized") - .def_readwrite("x", &colorized::x) - ; -} - -#include "module_tail.cpp" diff --git a/test/enum.py b/test/enum.py deleted file mode 100644 index e99e401e..00000000 --- a/test/enum.py +++ /dev/null @@ -1,59 +0,0 @@ -''' ->>> from enum_ext import * - ->>> identity(color.red) -enum_ext.color.red - ->>> identity(color.green) -enum_ext.color.green - ->>> identity(color.blue) -enum_ext.color.blue - ->>> identity(color(1)) -enum_ext.color.red - ->>> identity(color(2)) -enum_ext.color.green - ->>> identity(color(3)) -enum_ext.color(3) - ->>> identity(color(4)) -enum_ext.color.blue - - --- check export to scope --- - ->>> identity(red) -enum_ext.color.red - ->>> identity(green) -enum_ext.color.green - ->>> identity(blue) -enum_ext.color.blue - ->>> try: identity(1) -... except TypeError: pass -... else: print 'expected a TypeError' - ->>> c = colorized() ->>> c.x -enum_ext.color.red ->>> c.x = green ->>> c.x -enum_ext.color.green -''' - -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/test/exception_translator.cpp b/test/exception_translator.cpp deleted file mode 100644 index f9c38ab9..00000000 --- a/test/exception_translator.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -struct error {}; - -void translate(error const& e) -{ - PyErr_SetString(PyExc_RuntimeError, "!!!error!!!"); -} - -void throw_error() -{ - throw error(); - -} - -BOOST_PYTHON_MODULE(exception_translator_ext) -{ - using namespace boost::python; - register_exception_translator(&translate); - - def("throw_error", throw_error); -} - diff --git a/test/exception_translator.py b/test/exception_translator.py deleted file mode 100644 index 78fe3507..00000000 --- a/test/exception_translator.py +++ /dev/null @@ -1,22 +0,0 @@ -''' ->>> from exception_translator_ext import * ->>> try: -... throw_error(); -... except RuntimeError, x: -... print x -... else: -... print 'Expected a RuntimeError!' -!!!error!!! -''' -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/test/extract.cpp b/test/extract.cpp deleted file mode 100644 index a7749043..00000000 --- a/test/extract.cpp +++ /dev/null @@ -1,140 +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 "test_class.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -typedef test_class<> X; - -bool extract_bool(object x) { return extract(x); } - -boost::python::list extract_list(object x) -{ - extract get_list((x)); - - // Make sure we always have the right idea about whether it's a list - bool is_list_1 = get_list.check(); - bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type); - assert(is_list_1 == is_list_2); - - return get_list(); -} - -char const* extract_cstring(object x) -{ - return extract(x); -} - -std::string extract_string(object x) -{ - std::string s = extract(x); - return s; -} - -std::string const& extract_string_cref(object x) -{ -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 -# pragma warning(push) -# pragma warning(disable:4172) // msvc lies about returning a reference to temporary -#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 700 -# pragma warning(push) -# pragma warning(disable:473) // intel/win32 does too -#endif - - return extract(x); - -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 700 -# pragma warning(pop) -#endif -} - -X extract_X(object x) -{ - return extract(x); -} - -X* extract_X_ptr(object x) { return extract(x); } - -X& extract_X_ref(object x) -{ - extract get_x(x); - return get_x; -} - -int double_X(object n) -{ - extract x(n); - return x().value() + x().value(); -} - -bool check_bool(object x) { return extract(x).check(); } -bool check_list(object x) { return extract(x).check(); } -bool check_cstring(object x) { return extract(x).check(); } -bool check_string(object x) { return extract(x).check(); } -bool check_string_cref(object x) { return extract(x).check(); } -bool check_X(object x) { return extract(x).check(); } -bool check_X_ptr(object x) { return extract(x).check(); } -bool check_X_ref(object x) { return extract(x).check(); } - -std::string x_rep(X const& x) -{ - return "X(" + boost::lexical_cast(x.value()) + ")"; -} - -BOOST_PYTHON_MODULE(extract_ext) -{ - implicitly_convertible(); - - def("extract_bool", extract_bool); - def("extract_list", extract_list); - def("extract_cstring", extract_cstring); - def("extract_string", extract_string); - def("extract_string_cref", extract_string_cref, return_value_policy()); - def("extract_X", extract_X); - def("extract_X_ptr", extract_X_ptr, return_value_policy()); - def("extract_X_ref", extract_X_ref, return_value_policy()); - - def("check_bool", check_bool); - def("check_list", check_list); - def("check_cstring", check_cstring); - def("check_string", check_string); - def("check_string_cref", check_string_cref); - def("check_X", check_X); - def("check_X_ptr", check_X_ptr); - def("check_X_ref", check_X_ref); - - def("double_X", double_X); - - def("count_Xs", &X::count); - ; - - object x_class( - class_("X", init()) - .def( "__repr__", x_rep)); - - // Instantiate an X object through the Python interface - object x_obj = x_class(3); - - // Get the C++ object out of the Python object - X const& x = extract(x_obj); - assert(x.value() == 3); -} - - -#include "module_tail.cpp" - diff --git a/test/extract.py b/test/extract.py deleted file mode 100644 index 328049dd..00000000 --- a/test/extract.py +++ /dev/null @@ -1,102 +0,0 @@ -''' - >>> from extract_ext import * - -Just about anything has a truth value in Python - - >>> assert check_bool(None) - >>> extract_bool(None) - 0 - - >>> assert check_bool(2) - >>> extract_bool(2) - 1 - - >>> assert not check_bool('') - -Check that object manager types work properly. These are a different -case because they wrap Python objects instead of being wrapped by them. - - >>> assert not check_list(2) - >>> try: x = extract_list(2) - ... except TypeError, x: - ... if str(x) != 'Expecting an object of type list; got an object of type int instead': - ... print x - ... else: - ... print 'expected an exception, got', x, 'instead' - -Can't extract a list from a tuple. Use list(x) to convert a sequence -to a list: - - >>> assert not check_list((1, 2, 3)) - >>> assert check_list([1, 2, 3]) - >>> extract_list([1, 2, 3]) - [1, 2, 3] - -Can get a char const* from a Python string: - - >>> assert check_cstring('hello') - >>> extract_cstring('hello') - 'hello' - -Can't get a char const* from a Python int: - - >>> assert not check_cstring(1) - >>> try: x = extract_cstring(1) - ... except TypeError: pass - ... else: - ... print 'expected an exception, got', x, 'instead' - -Extract an std::string (class) rvalue from a native Python type - - >>> assert check_string('hello') - >>> extract_string('hello') - 'hello' - -Constant references are not treated as rvalues for the purposes of -extract: - - >>> assert not check_string_cref('hello') - -We can extract lvalues where appropriate: - - >>> x = X(42) - >>> check_X(x) - 1 - >>> extract_X(x) - X(42) - - >>> check_X_ptr(x) - 1 - >>> extract_X_ptr(x) - X(42) - >>> extract_X_ref(x) - X(42) - -Demonstrate that double-extraction of an rvalue works, and all created -copies of the object are destroyed: - - >>> n = count_Xs() - >>> double_X(333) - 666 - >>> count_Xs() - n - 0 - -General check for cleanliness: - - >>> del x - >>> count_Xs() - 0 -''' - -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/test/if_else.cpp b/test/if_else.cpp deleted file mode 100644 index e2b50f28..00000000 --- a/test/if_else.cpp +++ /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. -#include -#include -#include - - typedef char c1; - typedef char c2[2]; - typedef char c3[3]; - typedef char c4[4]; - -template -struct choose -{ - typedef typename boost::python::detail::if_< - (sizeof(c1) == size) - >::template then< - c1 - >::template elif< - (sizeof(c2) == size) - >::template then< - c2 - >::template elif< - (sizeof(c3) == size) - >::template then< - c3 - >::template elif< - (sizeof(c4) == size) - >::template then< - c4 - >::template else_::type type; -}; - -int main() -{ - BOOST_STATIC_ASSERT((boost::is_same::type,c1>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,c2>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,c3>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,c4>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,void*>::value)); - return 0; -} diff --git a/test/implicit.cpp b/test/implicit.cpp deleted file mode 100644 index c4728548..00000000 --- a/test/implicit.cpp +++ /dev/null @@ -1,48 +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 "test_class.hpp" - -using namespace boost::python; - -typedef test_class<> X; - -int x_value(X const& x) -{ - return x.value(); -} - -X make_x(int n) { return X(n); } - - -// foo/bar -- a regression for a vc7 bug workaround -struct bar {}; -struct foo -{ - virtual void f() = 0; - operator bar() const { return bar(); } -}; - -BOOST_PYTHON_MODULE(implicit_ext) -{ - implicitly_convertible(); - implicitly_convertible(); - - def("x_value", x_value); - def("make_x", make_x); - - class_("X", init()) - .def("value", &X::value) - .def("set", &X::set) - ; - - implicitly_convertible(); -} - -#include "module_tail.cpp" diff --git a/test/implicit.py b/test/implicit.py deleted file mode 100644 index e0d8c067..00000000 --- a/test/implicit.py +++ /dev/null @@ -1,26 +0,0 @@ -''' ->>> from implicit_ext import * ->>> x_value(X(42)) -42 ->>> x_value(42) -42 ->>> x = make_x(X(42)) ->>> x.value() -42 ->>> try: make_x('fool') -... except TypeError: pass -... else: print 'no error' -''' - -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/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp deleted file mode 100644 index 26c6e895..00000000 --- a/test/indirect_traits_test.cpp +++ /dev/null @@ -1,105 +0,0 @@ -//#include -#include -#include - -//#define print(expr) printf("%s ==> %s\n", #expr, expr) - -// not all the compilers can handle an incomplete class type here. -struct X {}; - -int main() -{ - using namespace boost::python::detail; - - typedef void (X::*pmf)(); - - assert(is_reference_to_function::value); - assert(!is_reference_to_function::value); - assert(!is_reference_to_function::value); - assert(!is_reference_to_function::value); - - assert(!is_pointer_to_function::value); - assert(is_pointer_to_function::value); - assert(!is_pointer_to_function::value); - assert(!is_pointer_to_function::value); - assert(!is_pointer_to_function::value); - - assert(!is_reference_to_function_pointer::value); - assert(!is_reference_to_function_pointer::value); - assert(!is_reference_to_function_pointer::value); - assert(is_reference_to_function_pointer::value); - assert(is_reference_to_function_pointer::value); - assert(!is_reference_to_function_pointer::value); - - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(!is_reference_to_pointer::value); - - assert(!is_reference_to_pointer::value); - assert(!is_reference_to_pointer::value); - assert(!is_reference_to_pointer::value); - - assert(!is_reference_to_const::value); - assert(is_reference_to_const::value); - assert(!is_reference_to_const::value); - assert(is_reference_to_const::value); - - assert(!is_reference_to_const::value); - assert(!is_reference_to_const::value); - assert(!is_reference_to_const::value); - - assert(is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - assert(is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - - assert(!is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - - assert(!is_reference_to_volatile::value); - assert(!is_reference_to_volatile::value); - assert(is_reference_to_volatile::value); - assert(is_reference_to_volatile::value); - - assert(!is_reference_to_volatile::value); - assert(!is_reference_to_volatile::value); - assert(!is_reference_to_volatile::value); - - assert(!is_reference_to_class::value); - assert(!is_reference_to_class::value); - assert(!is_reference_to_class::value); - - assert(!is_reference_to_class::value); - assert(is_reference_to_class::value); - assert(is_reference_to_class::value); - assert(is_reference_to_class::value); - assert(is_reference_to_class::value); - - assert(!is_pointer_to_class::value); - assert(!is_pointer_to_class::value); - assert(!is_pointer_to_class::value); - - assert(!is_pointer_to_class::value); - assert(!is_pointer_to_class::value); - assert(is_pointer_to_class::value); - assert(is_pointer_to_class::value); - assert(is_pointer_to_class::value); - assert(is_pointer_to_class::value); - - assert(is_reference_to_member_function_pointer::value); - assert(is_reference_to_member_function_pointer::value); - assert(is_reference_to_member_function_pointer::value); - assert(is_reference_to_member_function_pointer::value); - assert(!is_reference_to_member_function_pointer::value); - assert(!is_reference_to_member_function_pointer::value); - assert(!is_reference_to_member_function_pointer::value); - - return 0; -} diff --git a/test/input_iterator.cpp b/test/input_iterator.cpp deleted file mode 100644 index eacae455..00000000 --- a/test/input_iterator.cpp +++ /dev/null @@ -1,49 +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 - -using namespace boost::python; - -typedef std::list list_int; - -// Prove that we can handle InputIterators which return rvalues. -struct doubler -{ - typedef int result_type; - int operator()(int x) const { return x * 2; } -}; - -typedef boost::transform_iterator_generator::type doubling_iterator; -typedef std::pair list_range2; - -list_range2 range2(list_int& x) -{ - return list_range2( - boost::make_transform_iterator(x.begin(), doubler()) - , boost::make_transform_iterator(x.end(), doubler())); -} - -// We do this in a separate module from iterators_ext (iterators.cpp) -// to work around an MSVC6 linker bug, which causes it to complain -// about a "duplicate comdat" if the input iterator is instantiated in -// the same module with the others. -BOOST_PYTHON_MODULE(input_iterator) -{ - def("range2", &::range2); - - class_("list_range2") - // We can wrap InputIterators which return by-value - .def("__iter__" - , range(&list_range2::first, &list_range2::second)) - ; -} - -#include "module_tail.cpp" diff --git a/test/iterator.cpp b/test/iterator.cpp deleted file mode 100644 index a52e0710..00000000 --- a/test/iterator.cpp +++ /dev/null @@ -1,138 +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 - -using namespace boost::python; - -typedef std::list list_int; -typedef std::list list_list; - - -void push_back(list_int& x, int y) -{ - x.push_back(y); -} - -void push_list_back(list_list& x, list_int const& y) -{ - x.push_back(y); -} - -int back(list_int& x) -{ - return x.back(); -} - -typedef std::pair list_range; - -struct list_range2 : list_range -{ - list_int::iterator& begin() { return this->first; } - list_int::iterator& end() { return this->second; } -}; - -list_range range(list_int& x) -{ - return list_range(x.begin(), x.end()); -} - -struct two_lists -{ - two_lists() - { - int primes[] = { 2, 3, 5, 7, 11, 13 }; - std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one)); - int evens[] = { 2, 4, 6, 8, 10, 12 }; - std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two)); - } - - struct two_start - { - typedef list_int::iterator result_type; - result_type operator()(two_lists& ll) const { return ll.two.begin(); } - }; - friend struct two_start; - - list_int::iterator one_begin() { return one.begin(); } - list_int::iterator two_begin() { return two.begin(); } - - list_int::iterator one_end() { return one.end(); } - list_int::iterator two_end() { return two.end(); } - -private: - list_int one; - list_int two; -}; - -BOOST_PYTHON_MODULE(iterator_ext) -{ - using boost::python::iterator; // gcc 2.96 bug workaround - def("range", &::range); - - class_("list_int") - .def("push_back", push_back) - .def("back", back) - .def("__iter__", iterator()) - ; - - class_("list_range") - - // We can specify data members - .def("__iter__" - , range(&list_range::first, &list_range::second)) - ; - - // No runtime tests for this one yet - class_("list_range2") - - // We can specify member functions returning a non-const reference - .def("__iter__", range(&list_range2::begin, &list_range2::end)) - ; - - class_("two_lists") - - // We can spcify member functions - .add_property( - "primes" - , range(&two_lists::one_begin, &two_lists::one_end)) - - // Prove that we can explicitly specify call policies - .add_property( - "evens" - , range >( - &two_lists::two_begin, &two_lists::two_end)) - - // Prove that we can specify call policies and target - .add_property( - "twosies" - , range, two_lists>( - // And we can use adaptable function objects when - // partial specialization is available. -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - two_lists::two_start() -# else - &two_lists::two_begin -# endif - , &two_lists::two_end)) - ; - - class_("list_list") - .def("push_back", push_list_back) - .def("__iter__", iterator >()) - ; -} - -#include "module_tail.cpp" diff --git a/test/iterator.py b/test/iterator.py deleted file mode 100644 index 2f2f8e02..00000000 --- a/test/iterator.py +++ /dev/null @@ -1,72 +0,0 @@ -''' ->>> from iterator_ext import * ->>> from input_iterator import * ->>> x = list_int() ->>> x.push_back(1) ->>> x.back() -1 ->>> x.push_back(3) ->>> x.push_back(5) ->>> for y in x: -... print y -1 -3 -5 ->>> z = range(x) ->>> for y in z: -... print y -1 -3 -5 - - Range2 wraps a transform_iterator which doubles the elements it - traverses. This proves we can wrap input iterators - ->>> z2 = range2(x) ->>> for y in z2: -... print y -2 -6 -10 - ->>> l2 = two_lists() ->>> for y in l2.primes: -... print y -2 -3 -5 -7 -11 -13 ->>> for y in l2.evens: -... print y -2 -4 -6 -8 -10 -12 ->>> ll = list_list() ->>> ll.push_back(x) ->>> x.push_back(7) ->>> ll.push_back(x) ->>> for a in ll: -... for b in a: -... print b, -... print -... -1 3 5 -1 3 5 7 -''' -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/test/list.cpp b/test/list.cpp deleted file mode 100644 index 15871e6a..00000000 --- a/test/list.cpp +++ /dev/null @@ -1,145 +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 "test_class.hpp" - -using namespace boost::python; - -object new_list() -{ - return list(); -} - -list listify(object x) -{ - return list(x); -} - -object listify_string(char const* s) -{ - return list(s); -} - -std::string x_rep(test_class<> const& x) -{ - return "X(" + boost::lexical_cast(x.value()) + ")"; -} - -object apply_object_list(object f, list x) -{ - return f(x); -} - -list apply_list_list(object f, list x) -{ - return call(f.ptr(), x); -} - -void append_object(list& x, object y) -{ - x.append(y); -} - -void append_list(list& x, list const& y) -{ - x.append(y); -} - -typedef test_class<> X; - -int notcmp(object const& x, object const& y) -{ - return y < x ? -1 : y > x ? 1 : 0; -} - -void exercise(list x, object y, object print) -{ - x.append(y); - x.append(5); - x.append(X(3)); - - print("after append:"); - print(x); - - print("number of", y, "instances:", x.count(y)); - - print("number of 5s:", x.count(5)); - - x.extend("xyz"); - print("after extend:"); - print(x); - print("index of", y, "is:", x.index(y)); - print("index of 'l' is:", x.index("l")); - - x.insert(4, 666); - print("after inserting 666:"); - print(x); - print("inserting with object as index:"); - x.insert(x[x.index(5)], "---"); - print(x); - - print("popping..."); - x.pop(); - print(x); - x.pop(x[x.index(5)]); - print(x); - x.pop(x.index(5)); - print(x); - - print("removing", y); - x.remove(y); - print(x); - print("removing", 666); - x.remove(666); - print(x); - - print("reversing..."); - x.reverse(); - print(x); - - print("sorted:"); - x.pop(2); // make sorting predictable - x.sort(); - print(x); - - print("reverse sorted:"); - x.sort(¬cmp); - print(x); - - list w; - w.append(5); - w.append(6); - w += "hi"; - assert(w[0] == 5); - assert(w[1] == 6); - assert(w[2] == 'h'); - assert(w[3] == 'i'); -} - -BOOST_PYTHON_MODULE(list_ext) -{ - def("new_list", new_list); - def("listify", listify); - def("listify_string", listify_string); - def("apply_object_list", apply_object_list); - def("apply_list_list", apply_list_list); - - def("append_object", append_object); - def("append_list", append_list); - - def("exercise", exercise); - - class_("X", init()) - .def( "__repr__", x_rep) - ; -} - diff --git a/test/list.py b/test/list.py deleted file mode 100644 index 0357b9a2..00000000 --- a/test/list.py +++ /dev/null @@ -1,113 +0,0 @@ -''' ->>> from list_ext import * - ->>> new_list() -[] - ->>> listify((1,2,3)) -[1, 2, 3] - ->>> letters = listify_string('hello') ->>> letters -['h', 'e', 'l', 'l', 'o'] - ->>> X(22) -X(22) - ->>> def identity(x): -... return x ->>> assert apply_object_list(identity, letters) is letters - - 5 is not convertible to a list - ->>> try: result = apply_object_list(identity, 5) -... except TypeError: pass -... else: print 'expected an exception, got', result, 'instead' - ->>> assert apply_list_list(identity, letters) is letters - - 5 is not convertible to a list as a return value - ->>> try: result = apply_list_list(len, letters) -... except TypeError: pass -... else: print 'expected an exception, got', result, 'instead' - ->>> append_object(letters, '.') ->>> letters -['h', 'e', 'l', 'l', 'o', '.'] - - tuples do not automatically convert to lists when passed as arguments - ->>> try: append_list(letters, (1,2)) -... except TypeError: pass -... else: print 'expected an exception' - ->>> append_list(letters, [1,2]) ->>> letters -['h', 'e', 'l', 'l', 'o', '.', [1, 2]] - - Check that subclass functions are properly called - ->>> class mylist(list): -... def append(self, o): -... list.append(self, o) -... if not hasattr(self, 'nappends'): -... self.nappends = 1 -... else: -... self.nappends += 1 -... ->>> l2 = mylist() ->>> append_object(l2, 'hello') ->>> append_object(l2, 'world') ->>> l2 -['hello', 'world'] ->>> l2.nappends -2 - ->>> def printer(*args): -... for x in args: print x, -... print -... - ->>> y = X(42) ->>> exercise(letters, y, printer) -after append: -['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3)] -number of X(42) instances: 1 -number of 5s: 1 -after extend: -['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] -index of X(42) is: 7 -index of 'l' is: 2 -after inserting 666: -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] -inserting with object as index: -['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] -popping... -['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y'] -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y'] -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), X(3), 'x', 'y'] -removing X(42) -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(3), 'x', 'y'] -removing 666 -['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(3), 'x', 'y'] -reversing... -['y', 'x', X(3), [1, 2], '.', 'o', 'l', 'l', 'e', 'h'] -sorted: -[[1, 2], '.', 'e', 'h', 'l', 'l', 'o', 'x', 'y'] -reverse sorted: -['y', 'x', 'o', 'l', 'l', 'h', 'e', '.', [1, 2]] -''' - -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/test/long.cpp b/test/long.cpp deleted file mode 100644 index cc619987..00000000 --- a/test/long.cpp +++ /dev/null @@ -1,51 +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 - -using namespace boost::python; - -object new_long() -{ - return long_(); -} - -long_ longify(object x) -{ - return long_(x); -} - -object longify_string(char const* s) -{ - return long_(s); -} - -char const* is_long1(long_& x) -{ - long_ y = x; - x += 50; - assert(x == y + 50); - return "yes"; -} - -int is_long2(char const*) -{ - return 0; -} - -BOOST_PYTHON_MODULE(long_ext) -{ - def("new_long", new_long); - def("longify", longify); - def("longify_string", longify_string); - def("is_long", is_long1); - def("is_long", is_long2); - ; -} - diff --git a/test/long.py b/test/long.py deleted file mode 100644 index 7d08e9b7..00000000 --- a/test/long.py +++ /dev/null @@ -1,26 +0,0 @@ -''' ->>> from long_ext import * ->>> new_long() -0L ->>> longify(42) -42L ->>> longify_string('300') -300L ->>> is_long(20L) -'yes' ->>> is_long('20') -0 -''' - -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/test/m1.cpp b/test/m1.cpp deleted file mode 100644 index 8811bac4..00000000 --- a/test/m1.cpp +++ /dev/null @@ -1,276 +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 - -// 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. -// -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; - } -}; - -struct int_from_noddy -{ - static int& execute(NoddyObject& p) - { - return 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); -} - -int f_mutable_ref(simple& s) -{ - return strlen(s.s); -} - -int f_mutable_ptr(simple* s) -{ - return strlen(s->s); -} - -int f_const_ptr(simple const* s) -{ - return strlen(s->s); -} - -int f2(SimpleObject const& s) -{ - return strlen(s.x.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) {} - static char const* name(B*) { 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& b) { return b; } -C take_c(C* c) { return *c; } -D take_d(D* const& d) { return *d; } - -D take_d_shared_ptr(boost::shared_ptr d) { return *d; } - -boost::shared_ptr d_factory() { return boost::shared_ptr(new D); } - -struct Unregistered {}; -Unregistered make_unregistered(int) { return Unregistered(); } - -Unregistered* make_unregistered2(int) { return new Unregistered; } - -BOOST_PYTHON_MODULE(m1) -{ - using namespace boost::python; - using boost::shared_ptr; - - simple_to_python(); - - lvalue_from_pytype(); - - lvalue_from_pytype< -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters - extract_member -#else - extract_simple_object -#endif - , &SimpleType - >(); - - lvalue_from_pytype,&SimpleType>(); - - def("new_noddy", new_noddy); - def("new_simple", new_simple); - - def("make_unregistered", make_unregistered); - def("make_unregistered2", make_unregistered2, return_value_policy()); - - // Expose f() in all its variations - def("f", f); - def("f_mutable_ref", f_mutable_ref); - def("f_mutable_ptr", f_mutable_ptr); - def("f_const_ptr", f_const_ptr); - - def("f2", f2); - - // 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); - - - def("take_d_shared_ptr", take_d_shared_ptr); - def("d_factory", d_factory); - - class_ >("A") - .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 - class_ >("B") - .def("name", &B::name) - ; - - class_ >("C") - .def("name", &C::name) - ; - - class_ >("D") - .def("name", &D::name) - ; - - class_("complicated", - init()) - .def(init()) - .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 3108b2de..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 -#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(m2) -{ - using boost::python::return_value_policy; - using boost::python::copy_const_reference; - using boost::python::copy_non_const_reference; - using boost::python::def; - - 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/member_function_cast.cpp b/test/member_function_cast.cpp deleted file mode 100644 index a754fd36..00000000 --- a/test/member_function_cast.cpp +++ /dev/null @@ -1,55 +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 - -using namespace boost; - -template -void assert_same(S, type* = 0) -{ - BOOST_STATIC_ASSERT((is_same::value)); -} - -template -void assert_mf_cast(F f, type* = 0, type* = 0) -{ - assert_same( - python::detail::member_function_cast::stage1(f).stage2((Target*)0).stage3(f) - ); -} - -struct X -{ - int f() const { return 0; } - void g(char*) {} -}; - -struct Y : X -{ - -}; - -struct Z : Y -{ - int f() const { return 0; } - void g(char*) {} -}; - -int main() -{ - assert_mf_cast(&X::f); - assert_mf_cast(&X::g); - - assert_mf_cast(&Z::f); - assert_mf_cast(&Z::g); - - assert_mf_cast(3); - assert_mf_cast(X()); - return 0; -} diff --git a/test/minimal.cpp b/test/minimal.cpp deleted file mode 100644 index ac6fb4ae..00000000 --- a/test/minimal.cpp +++ /dev/null @@ -1,17 +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 - -#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -# include // works around a KCC intermediate code generation bug -#endif - -BOOST_PYTHON_MODULE(minimal_ext) -{ -} - -#include "module_tail.cpp" diff --git a/test/minimal.py b/test/minimal.py deleted file mode 100644 index fde9840a..00000000 --- a/test/minimal.py +++ /dev/null @@ -1,4 +0,0 @@ -print "IMPORTING minimal_ext" -import minimal_ext -print "DONE IMPORTING minimal_ext" - diff --git a/test/module_tail.cpp b/test/module_tail.cpp deleted file mode 100644 index 763e7dff..00000000 --- a/test/module_tail.cpp +++ /dev/null @@ -1,42 +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 -# pragma warning(push) -# pragma warning(disable:4297) -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -# pragma warning(pop) -# 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/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp deleted file mode 100644 index 8c3e8846..00000000 --- a/test/multi_arg_constructor.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -struct A -{ - A(const double, const double, const double, const double, const double - , const double, const double - , const double, const double - ) {} -}; - -BOOST_PYTHON_MODULE(multi_arg_constructor_ext) -{ - using namespace boost::python; - - class_( - "A" - , init() - ) - ; - -} - diff --git a/test/multi_arg_constructor.py b/test/multi_arg_constructor.py deleted file mode 100644 index fb062e8a..00000000 --- a/test/multi_arg_constructor.py +++ /dev/null @@ -1,16 +0,0 @@ -''' ->>> from multi_arg_constructor_ext import * ->>> a = A(1.0, 2, 3, 4, 5, 6, 7.0, 8.1, 9.3) -''' -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/test/nested.cpp b/test/nested.cpp deleted file mode 100644 index 2ccea6f2..00000000 --- a/test/nested.cpp +++ /dev/null @@ -1,52 +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 "test_class.hpp" -#if __GNUC__ != 2 -# include -#else -# include -#endif - -typedef test_class<> X; -typedef test_class<1> Y; - -std::ostream& operator<<(std::ostream& s, X const& x) -{ - return s << x.value(); -} - -std::ostream& operator<<(std::ostream& s, Y const& x) -{ - return s << x.value(); -} - - -BOOST_PYTHON_MODULE(nested_ext) -{ - using namespace boost::python; - - // Establish X as the current scope. - scope x_class - = class_("X", init()) - .def(str(self)) - ; - - - // Y will now be defined in the current scope - class_("Y", init()) - .def(str(self)) - ; -} - - -#include "module_tail.cpp" - - - diff --git a/test/nested.py b/test/nested.py deleted file mode 100644 index 97ac2a33..00000000 --- a/test/nested.py +++ /dev/null @@ -1,35 +0,0 @@ -''' - >>> from nested_ext import * - - >>> X - - - >>> X.__module__ - 'nested_ext' - - >>> X.__name__ - 'X' - - >>> X.Y - - - >>> X.Y.__module__ - 'nested_ext' - - >>> X.Y.__name__ - 'Y' - -''' - -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/test/newtest.py b/test/newtest.py deleted file mode 100644 index da877151..00000000 --- a/test/newtest.py +++ /dev/null @@ -1,199 +0,0 @@ -""" ->>> from m1 import * - ->>> from m2 import * - - Prove that we get an appropriate error from trying to return a type - for which we have no registered to_python converter - ->>> def check_unregistered(f, msgprefix): -... try: -... f(1) -... except TypeError, x: -... if not str(x).startswith(msgprefix): -... print str(x) -... else: -... print 'expected a TypeError' -... ->>> check_unregistered(make_unregistered, 'No to_python (by-value) converter found for C++ type') ->>> check_unregistered(make_unregistered2, 'No Python class registered for C++ class') - ->>> 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 - ->>> f_mutable_ref(g(s)) -12 - ->>> f_const_ptr(g(s)) -12 - ->>> f_mutable_ptr(g(s)) -12 - ->>> f2(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 quick regression test for a bug where None could be converted - to the target of any member function. To see it, we need to - access the __dict__ directly, to bypass the type check supplied - by the Method property which wraps the method when accessed as an - attribute. - ->>> try: A.__dict__['name'](None) -... except TypeError: pass -... else: print 'expected an exception!' - - ->>> 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' - ->>> take_d_shared_ptr(d).name() -'D' - ->>> d_as_a = d_factory() ->>> dd = take_d(d_as_a) ->>> dd.name() -'D' - -""" - -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/test/numpy.cpp b/test/numpy.cpp deleted file mode 100644 index 8a02f6ee..00000000 --- a/test/numpy.cpp +++ /dev/null @@ -1,105 +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 - -using namespace boost::python; - -// See if we can invoke array() from C++ -object new_array() -{ - return numeric::array( - make_tuple( - make_tuple(1,2,3) - , make_tuple(4,5,6) - , make_tuple(7,8,9) - ) - ); -} - -// test argument conversion -void take_array(numeric::array x) -{ -} - -// A separate function to invoke the info() member. Must happen -// outside any doctests since this prints directly to stdout and the -// result text includes the address of the 'self' array. -void info(numeric::array const& z) -{ - z.info(); -} - -// Tests which work on both Numeric and numarray array objects. Of -// course all of the operators "just work" since numeric::array -// inherits that behavior from object. -void exercise(numeric::array& y, object check) -{ - y[make_tuple(2,1)] = 3; - check(y); - check(y.astype('D')); - check(y.copy()); - check(y.typecode()); -} - -// numarray-specific tests. check is a callable object which we can -// use to record intermediate results, which are later compared with -// the results of corresponding python operations. -void exercise_numarray(numeric::array& y, object check) -{ - check(y.astype()); - - check(y.argmax()); - check(y.argmax(0)); - - check(y.argmin()); - check(y.argmin(0)); - - check(y.argsort()); - check(y.argsort(1)); - - y.byteswap(); - check(y); - - check(y.diagonal()); - check(y.diagonal(1)); - check(y.diagonal(0, 1)); - check(y.diagonal(0, 1, 0)); - - check(y.is_c_array()); - check(y.isbyteswapped()); - - check(y.trace()); - check(y.trace(1)); - check(y.trace(0, 1)); - check(y.trace(0, 1, 0)); - - check(y.new_('D')); - y.sort(); - check(y); - check(y.type()); - - check(y.factory(make_tuple(1.2, 3.4))); - check(y.factory(make_tuple(1.2, 3.4), "Double")); - check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(1,2,1))); - check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2,1,1), false)); - check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2), true, true)); -} - -BOOST_PYTHON_MODULE(numpy_ext) -{ - def("new_array", new_array); - def("take_array", take_array); - def("exercise", exercise); - def("exercise_numarray", exercise_numarray); - def("set_module_and_type", &numeric::array::set_module_and_type); - def("info", info); -} - -#include "module_tail.cpp" diff --git a/test/numpy.py b/test/numpy.py deleted file mode 100644 index b4c3ec62..00000000 --- a/test/numpy.py +++ /dev/null @@ -1,175 +0,0 @@ -def numeric_tests(): - ''' - >>> from numpy_ext import * - >>> x = new_array() - >>> x[1,1] = 0.0 - - >>> try: take_array(3) - ... except TypeError: pass - ... else: print 'expected a TypeError' - - >>> take_array(x) - - >>> print x - [[1 2 3] - [4 0 6] - [7 8 9]] - - >>> y = x.copy() - - - >>> p = _printer() - >>> check = p.check - >>> exercise(x, p) - >>> y[2,1] = 3 - >>> check(y); - - >>> check(y.astype('D')); - - >>> check(y.copy()); - - >>> check(y.typecode()); - - >>> p.results - [] - >>> del p - ''' - pass - -def _numarray_tests(): - ''' - >>> from numpy_ext import * - >>> x = new_array() - >>> y = x.copy() - >>> p = _printer() - >>> check = p.check - >>> exercise_numarray(x, p) - - >>> check(y.astype()); - - >>> check(y.argmax()); - >>> check(y.argmax(0)); - - >>> check(y.argmin()); - >>> check(y.argmin(0)); - - >>> check(y.argsort()); - >>> check(y.argsort(1)); - - >>> y.byteswap(); - >>> check(y); - - >>> check(y.diagonal()); - >>> check(y.diagonal(1)); - >>> check(y.diagonal(0, 1)); - >>> check(y.diagonal(0, 1, 0)); - - >>> check(y.is_c_array()); - >>> check(y.isbyteswapped()); - - >>> check(y.trace()); - >>> check(y.trace(1)); - >>> check(y.trace(0, 1)); - >>> check(y.trace(0, 1, 0)); - - >>> check(y.new('D')); - >>> y.sort(); - >>> check(y); - >>> check(y.type()); - - >>> check(y.array((1.2, 3.4))); - >>> check(y.array((1.2, 3.4), "Double")); - >>> check(y.array((1.2, 3.4), "Double", (1,2,1))); - >>> check(y.array((1.2, 3.4), "Double", (2,1,1), false)); - >>> check(y.array((1.2, 3.4), "Double", (2,), true, true)); - - >>> p.results - [] - >>> del p - ''' - pass - -false = 0; -true = 1; -class _printer(object): - def __init__(self): - self.results = []; - def __call__(self, *stuff): - self.results += [ str(x) for x in stuff ] - def check(self, x): - if self.results[0] == str(x): - del self.results[0] - else: - print ' Expected:\n %s\n but got:\n %s' % (x, self.results[0]) - -def _run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - - # See which of the numeric modules are installed - has_numeric = 0 - try: - import Numeric - m = Numeric - has_numeric = 1 - except ImportError: pass - - has_numarray = 0 - try: - import numarray - m = numarray - has_numarray = 1 - except ImportError: pass - - # Bail if neither one is installed - if not (has_numeric or has_numarray): - return 0 - - # test the info routine outside the doctest. See numpy.cpp for an - # explanation - import numpy_ext - if (has_numarray): - numpy_ext.info(m.array((1,2,3))) - - failures = 0 - - # - # Run tests 4 different ways if both modules are installed, just - # to show that set_module_and_type() is working properly - # - - # run all the tests with default module search - print 'testing default extension module' - failures += doctest.testmod(sys.modules.get(__name__))[0] - - # test against Numeric if installed - if has_numeric: - print 'testing Numeric module explicitly' - numpy_ext.set_module_and_type('Numeric', 'ArrayType') - failures += doctest.testmod(sys.modules.get(__name__))[0] - - global __test__ - if has_numarray: - # Add the _numarray_tests to the list of things to test in - # this case. - __test__ = { 'numarray_tests':_numarray_tests, - 'numeric_tests': numeric_tests } - print 'testing numarray module explicitly' - numpy_ext.set_module_and_type('numarray', 'NDArray') - failures += doctest.testmod(sys.modules.get(__name__))[0] - del __test__ - - # see that we can go back to the default - print 'testing default module again' - numpy_ext.set_module_and_type('', '') - failures += doctest.testmod(sys.modules.get(__name__))[0] - - return failures - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(_run()) diff --git a/test/object.cpp b/test/object.cpp deleted file mode 100755 index bf702099..00000000 --- a/test/object.cpp +++ /dev/null @@ -1,318 +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 - -using namespace boost::python; - -object call_object_3(object f) -{ - return f(3); -} - -object message() -{ - return object("hello, world!"); -} - -object number() -{ - return object(42); -} - -object obj_getattr(object x, char const* name) -{ - return x.attr(name); -} - -object obj_const_getattr(object const& x, char const* name) -{ - return x.attr(name); -} - -void obj_setattr(object x, char const* name, object value) -{ - x.attr(name) = value; -} - -void obj_setattr42(object x, char const* name) -{ - x.attr(name) = 42; -} - -void obj_moveattr(object& x, char const* src, char const* dst) -{ - x.attr(dst) = x.attr(src); -} - -object obj_getitem(object x, object key) -{ - return x[key]; -} - -object obj_getitem3(object x) -{ - return x[3]; -} - -object obj_const_getitem(object const& x, object key) -{ - return x[key]; -} - -void obj_setitem(object x, object key, object value) -{ - x[key] = value; -} - -void obj_setitem42(object x, object key) -{ - x[key] = 42; -} - -void obj_moveitem(object& x, object src, object dst) -{ - x[dst] = x[src]; -} - -void obj_moveitem2(object const& x_src, object k_src, object& x_dst, object k_dst) -{ - x_dst[k_dst] = x_src[k_src]; -} - -bool test(object y) -{ - return y; -} - -bool test_not(object y) -{ - return !y; -} - -bool test_attr(object y, char* name) -{ - return y.attr(name); -} - -bool test_not_attr(object y, char* name) -{ - return !y.attr(name); -} - -bool test_item(object y, object key) -{ - return y[key]; -} - -bool test_not_item(object y, object key) -{ - return !y[key]; -} - -bool check_string_slice() -{ - object s("hello, world"); - - if (s.slice(_,-3) != "hello, wo") - return false; - - if (s.slice(-3,_) != "rld") - return false; - - if (", " != s.slice(5,7)) - return false; - - return s.slice(2,-1).slice(1,-1) == "lo, wor"; -} - -bool check_binary_operators() -{ - int y; - - object x(3); - -#define TEST_BINARY(op) \ - for (y = 1; y < 6; ++y) \ - { \ - if ((x op y) != (3 op y)) \ - return false; \ - } \ - for (y = 1; y < 6; ++y) \ - { \ - if ((y op x) != (y op 3)) \ - return false; \ - } \ - for (y = 1; y < 6; ++y) \ - { \ - object oy(y); \ - if ((oy op x) != (oy op 3)) \ - return false; \ - } - TEST_BINARY(>) - TEST_BINARY(>=) - TEST_BINARY(<) - TEST_BINARY(<=) - TEST_BINARY(==) - TEST_BINARY(!=) - - TEST_BINARY(+) - TEST_BINARY(-) - TEST_BINARY(*) - TEST_BINARY(/) - TEST_BINARY(%) - TEST_BINARY(<<) - TEST_BINARY(>>) - TEST_BINARY(&) - TEST_BINARY(^) - TEST_BINARY(|) - return true; -} - -bool check_inplace(object l, object o) -{ - int y; -#define TEST_INPLACE(op) \ - for (y = 1; y < 6; ++y) \ - { \ - object x(666); \ - x op##= y; \ - if (x != (666 op y)) \ - return false; \ - } \ - for (y = 1; y < 6; ++y) \ - { \ - object x(666); \ - x op##= object(y); \ - if (!(x == (666 op y))) \ - return false; \ - } - TEST_INPLACE(+) - TEST_INPLACE(-) - TEST_INPLACE(*) - TEST_INPLACE(/) - TEST_INPLACE(%) - TEST_INPLACE(<<) - TEST_INPLACE(>>) - TEST_INPLACE(&) - TEST_INPLACE(^) - TEST_INPLACE(|) - - l += l; - for (y = 0; y < 6; ++y) - { - if (l[y] != y % 3) - return false; - } - -#define TEST_ITEM_INPLACE(index, op, n, r1, r2) \ - l[index] op##= n; \ - if (l[index] != r1) \ - return false; \ - l[index] op##= object(n); \ - if (!(l[index] == r2)) \ - return false; - - TEST_ITEM_INPLACE(0,+,7,7,14) - TEST_ITEM_INPLACE(1,-,2,-1,-3) - TEST_ITEM_INPLACE(2,*,3,6,18) - TEST_ITEM_INPLACE(2,/,2,9,4) - TEST_ITEM_INPLACE(0,%,4,2,2) - l[0] += 1; - TEST_ITEM_INPLACE(0,<<,2,12,48) - TEST_ITEM_INPLACE(0,>>,1,24,12) - l[4] = 15; - TEST_ITEM_INPLACE(4,&,(16+4+1),5,5) - TEST_ITEM_INPLACE(0,^,1,13,12) - TEST_ITEM_INPLACE(0,|,1,13,13) - - o.attr("x0") = 0; - o.attr("x1") = 1; - o.attr("x2") = 2; - o.attr("x3") = 0; - o.attr("x4") = 1; - -#define TEST_ATTR_INPLACE(index, op, n, r1, r2) \ - o.attr("x" #index) op##= n; \ - if (o.attr("x" #index) != r1) \ - return false; \ - o.attr("x" #index) op##= object(n); \ - if (o.attr("x" #index) != r2) \ - return false; - - TEST_ATTR_INPLACE(0,+,7,7,14) - TEST_ATTR_INPLACE(1,-,2,-1,-3) - TEST_ATTR_INPLACE(2,*,3,6,18) - TEST_ATTR_INPLACE(2,/,2,9,4) - TEST_ATTR_INPLACE(0,%,4,2,2) - o.attr("x0") += 1; - TEST_ATTR_INPLACE(0,<<,2,12,48) - TEST_ATTR_INPLACE(0,>>,1,24,12) - o.attr("x4") = 15; - TEST_ATTR_INPLACE(4,&,(16+4+1),5,5) - TEST_ATTR_INPLACE(0,^,1,13,12) - TEST_ATTR_INPLACE(0,|,1,13,13) - - if (l[0] != o.attr("x0")) - return false; - if (l[1] != o.attr("x1")) - return false; - if (l[2] != o.attr("x2")) - return false; - if (l[3] != o.attr("x3")) - return false; - if (l[4] != o.attr("x4")) - return false; - - // set item 5 to be a list, by calling l.__class__ - l[5] = l.attr("__class__")(); - // append an element - l[5].attr("append")(2); - // Check its value - if (l[5][0] != 2) - return false; - - return true; -} - -BOOST_PYTHON_MODULE(object_ext) -{ - def("call_object_3", call_object_3); - def("message", message); - def("number", number); - - def("obj_getattr", obj_getattr); - def("obj_const_getattr", obj_const_getattr); - def("obj_setattr", obj_setattr); - def("obj_setattr42", obj_setattr42); - def("obj_moveattr", obj_moveattr); - - - def("obj_getitem", obj_getitem); - def("obj_getitem3", obj_getitem); - def("obj_const_getitem", obj_const_getitem); - def("obj_setitem", obj_setitem); - def("obj_setitem42", obj_setitem42); - def("obj_moveitem", obj_moveitem); - def("obj_moveitem2", obj_moveitem2); - - def("test", test); - def("test_not", test_not); - - def("test_attr", test_attr); - def("test_not_attr", test_not_attr); - - def("test_item", test_item); - def("test_not_item", test_not_item); - - def("check_binary_operators", check_binary_operators); - def("check_inplace", check_inplace); - def("check_string_slice", check_string_slice); - ; -} - -#include "module_tail.cpp" diff --git a/test/object.py b/test/object.py deleted file mode 100644 index 02da5ce8..00000000 --- a/test/object.py +++ /dev/null @@ -1,126 +0,0 @@ -''' ->>> from object_ext import * ->>> def print1(x): -... print x ->>> call_object_3(print1) -3 ->>> message() -'hello, world!' ->>> number() -42 - ->>> test('hi') -1 ->>> test(None) -0 ->>> test_not('hi') -0 ->>> test_not(0) -1 - - Attributes - ->>> class X: pass -... ->>> x = X() - ->>> try: obj_getattr(x, 'foo') -... except AttributeError: pass -... else: print 'expected an exception' - ->>> obj_setattr(x, 'foo', 1) ->>> x.foo -1 ->>> obj_getattr(x, 'foo') -1 ->>> obj_const_getattr(x, 'foo') -1 ->>> obj_setattr42(x, 'foo') ->>> x.foo -42 ->>> obj_moveattr(x, 'foo', 'bar') ->>> x.bar -42 ->>> test_attr(x, 'foo') -1 ->>> test_not_attr(x, 'foo') -0 ->>> x.foo = None ->>> test_attr(x, 'foo') -0 ->>> test_not_attr(x, 'foo') -1 - - Items - ->>> d = {} ->>> obj_setitem(d, 'foo', 1) ->>> d['foo'] -1 ->>> obj_getitem(d, 'foo') -1 ->>> obj_const_getitem(d, 'foo') -1 ->>> obj_setitem42(d, 'foo') ->>> obj_getitem(d, 'foo') -42 ->>> d['foo'] -42 ->>> obj_moveitem(d, 'foo', 'bar') ->>> d['bar'] -42 ->>> obj_moveitem2(d, 'bar', d, 'baz') ->>> d['baz'] -42 ->>> test_item(d, 'foo') -1 ->>> test_not_item(d, 'foo') -0 ->>> d['foo'] = None ->>> test_item(d, 'foo') -0 ->>> test_not_item(d, 'foo') -1 - - Slices - ->>> assert check_string_slice() - - Operators - - ->>> assert check_binary_operators() - ->>> class X: pass -... ->>> assert check_inplace(range(3), X()) - - - Now make sure that object is actually managing reference counts - ->>> import weakref ->>> class Z: pass -... ->>> z = Z() ->>> def death(r): print 'death' -... ->>> r = weakref.ref(z, death) ->>> z.foo = 1 ->>> obj_getattr(z, 'foo') -1 ->>> del z -death -''' - -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/test/object_fail1.cpp b/test/object_fail1.cpp deleted file mode 100755 index 3b09e71d..00000000 --- a/test/object_fail1.cpp +++ /dev/null @@ -1,12 +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 - -int f(boost::python::object const& x) -{ - x._("hello") = 1; - return 0; -} diff --git a/test/object_manager.cpp b/test/object_manager.cpp deleted file mode 100755 index 44005aeb..00000000 --- a/test/object_manager.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include - -using namespace boost::python; -using namespace boost::python::converter; - -struct X {}; - -int main() -{ - BOOST_STATIC_ASSERT(is_object_manager >::value); - BOOST_STATIC_ASSERT(!is_object_manager::value); - BOOST_STATIC_ASSERT(!is_object_manager::value); - - BOOST_STATIC_ASSERT(is_reference_to_object_manager&>::value); - BOOST_STATIC_ASSERT(is_reference_to_object_manager const&>::value); - BOOST_STATIC_ASSERT(is_reference_to_object_manager volatile&>::value); - BOOST_STATIC_ASSERT(is_reference_to_object_manager const volatile&>::value); - - BOOST_STATIC_ASSERT(!is_reference_to_object_manager >::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); - - return 0; -} - diff --git a/test/operators.cpp b/test/operators.cpp deleted file mode 100755 index 9096cb68..00000000 --- a/test/operators.cpp +++ /dev/null @@ -1,94 +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 "test_class.hpp" -#if __GNUC__ != 2 -# include -#else -# include -#endif - -// Just use math.h here; trying to use std::pow() causes too much -// trouble for non-conforming compilers and libraries. -#include - -using namespace boost::python; - -struct X : test_class<> -{ - typedef test_class<> base_t; - - X(int x) : base_t(x) {} - X const operator+(X const& r) const { return X(value() + r.value()); } -}; - -X operator-(X const& l, X const& r) { return X(l.value() - r.value()); } -X operator-(int l, X const& r) { return X(l - r.value()); } -X operator-(X const& l, int r) { return X(l.value() - r); } - -X operator-(X const& x) { return X(-x.value()); } - -X& operator-=(X& l, X const& r) { l.set(l.value() - r.value()); return l; } - -bool operator<(X const& x, X const& y) { return x.value() < y.value(); } -bool operator<(X const& x, int y) { return x.value() < y; } -bool operator<(int x, X const& y) { return x < y.value(); } - -X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); } - -X pow(X x, int y) -{ - return X(int(pow(double(x.value()), double(y)))); -} - -X pow(X x, X y) -{ - return X(int(pow(double(x.value()), double(y.value())))); -} - -int pow(int x, X y) -{ - return int(pow(double(x), double(y.value()))); -} - -std::ostream& operator<<(std::ostream& s, X const& x) -{ - return s << x.value(); -} - -BOOST_PYTHON_MODULE(operators_ext) -{ - class_("X", init()) - .def("value", &X::value) - .def(self + self) - .def(self - self) - .def(self - int()) - .def(other() - self) - .def(-self) - .def(self < other()) - .def(self < self) - .def(1 < self) - .def(self -= self) - .def(abs(self)) - .def(str(self)) - - .def(pow(self,self)) - .def(pow(self,int())) - .def(pow(int(),self)) - ; - - class_ >("Z", init()) - .def(int_(self)) - .def(float_(self)) - .def(complex_(self)) - ; -} - -#include "module_tail.cpp" diff --git a/test/operators.py b/test/operators.py deleted file mode 100644 index b18d4d2d..00000000 --- a/test/operators.py +++ /dev/null @@ -1,89 +0,0 @@ -''' ->>> from operators_ext import * ->>> x = X(42) ->>> x.value() -42 ->>> y = x - X(5) ->>> y.value() -37 ->>> y = x - 4 ->>> y.value() -38 ->>> y = 3 - x ->>> y.value() --39 ->>> (-y).value() -39 - ->>> (x + y).value() -3 - ->>> abs(y).value() -39 - ->>> x < 10 -0 ->>> x < 43 -1 - ->>> 10 < x -1 ->>> 43 < x -0 - ->>> x < y -0 ->>> y < x -1 - - ------ ->>> x > 10 -1 ->>> x > 43 -0 - ->>> 10 > x -0 ->>> 43 > x -1 - ->>> x > y -1 ->>> y > x -0 - ->>> y = x - 5 ->>> x -= y ->>> x.value() -5 ->>> str(x) -'5' - ->>> z = Z(10) ->>> int(z) -10 ->>> float(z) -10.0 ->>> complex(z) -(10+0j) - ->>> pow(2,x) -32 ->>> pow(x,2).value() -25 ->>> pow(X(2),x).value() -32 -''' - -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/test/pickle1.cpp b/test/pickle1.cpp deleted file mode 100644 index 794799f8..00000000 --- a/test/pickle1.cpp +++ /dev/null @@ -1,55 +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 -#include -#include - -#include - -namespace { - - // A friendly class. - class world - { - private: - std::string country; - public: - world(const std::string& country) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - }; - - struct world_pickle_suite : boost::python::pickle_suite - { - static - boost::python::tuple - getinitargs(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_country()); - } - }; - -} - -BOOST_PYTHON_MODULE(pickle1_ext) -{ - using namespace boost::python; - class_("world", init()) - .def("greet", &world::greet) - .def_pickle(world_pickle_suite()) - ; -} diff --git a/test/pickle1.py b/test/pickle1.py deleted file mode 100644 index d333919d..00000000 --- a/test/pickle1.py +++ /dev/null @@ -1,31 +0,0 @@ -r'''>>> import pickle1_ext - >>> import pickle - >>> pickle1_ext.world.__module__ - 'pickle1_ext' - >>> pickle1_ext.world.__safe_for_unpickling__ - 1 - >>> pickle1_ext.world.__name__ - 'world' - >>> pickle1_ext.world('Hello').__reduce__() - (, ('Hello',)) - >>> wd = pickle1_ext.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): - 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/test/pickle2.cpp b/test/pickle2.cpp deleted file mode 100644 index 99401973..00000000 --- a/test/pickle2.cpp +++ /dev/null @@ -1,99 +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 guards 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 -#include -#include -#include -#include -#include - -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; - }; - - struct world_pickle_suite : boost::python::pickle_suite - { - static - boost::python::tuple - getinitargs(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_country()); - } - - static - boost::python::tuple - getstate(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_secret_number()); - } - - static - void - setstate(world& w, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 1) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 1-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - long number = extract(state[0]); - if (number != 42) - w.set_secret_number(number); - } - }; - -} - -BOOST_PYTHON_MODULE(pickle2_ext) -{ - boost::python::class_( - "world", boost::python::init()) - .def("greet", &world::greet) - .def("get_secret_number", &world::get_secret_number) - .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_suite()) - ; -} diff --git a/test/pickle2.py b/test/pickle2.py deleted file mode 100644 index ec141bc9..00000000 --- a/test/pickle2.py +++ /dev/null @@ -1,45 +0,0 @@ -r'''>>> import pickle2_ext - >>> import pickle - >>> pickle2_ext.world.__module__ - 'pickle2_ext' - >>> pickle2_ext.world.__safe_for_unpickling__ - 1 - >>> pickle2_ext.world.__name__ - 'world' - >>> pickle2_ext.world('Hello').__reduce__() - (, ('Hello',), (0,)) - >>> for number in (24, 42): - ... wd = pickle2_ext.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_ext.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): - 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/test/pickle3.cpp b/test/pickle3.cpp deleted file mode 100644 index 8f243d39..00000000 --- a/test/pickle3.cpp +++ /dev/null @@ -1,107 +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 -#include -#include -#include -#include -#include -#include -#include - -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; - }; - - struct world_pickle_suite : boost::python::pickle_suite - { - static - boost::python::tuple - getinitargs(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_country()); - } - - static - boost::python::tuple - getstate(boost::python::object w_obj) - { - using namespace boost::python; - world const& w = extract(w_obj)(); - - return make_tuple(w_obj.attr("__dict__"), w.get_secret_number()); - } - - static - void - setstate(boost::python::object w_obj, boost::python::tuple state) - { - using namespace boost::python; - world& w = extract(w_obj)(); - - if (len(state) != 2) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 2-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - // restore the object's __dict__ - dict d = extract(w_obj.attr("__dict__"))(); - d.update(state[0]); - - // restore the internal state of the C++ object - long number = extract(state[1]); - if (number != 42) - w.set_secret_number(number); - } - - static bool getstate_manages_dict() { return true; } - }; - -} - -BOOST_PYTHON_MODULE(pickle3_ext) -{ - boost::python::class_( - "world", boost::python::init()) - .def("greet", &world::greet) - .def("get_secret_number", &world::get_secret_number) - .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_suite()) - ; -} diff --git a/test/pickle3.py b/test/pickle3.py deleted file mode 100644 index b700c1b0..00000000 --- a/test/pickle3.py +++ /dev/null @@ -1,40 +0,0 @@ -r'''>>> import pickle3_ext - >>> import pickle - >>> pickle3_ext.world.__module__ - 'pickle3_ext' - >>> pickle3_ext.world.__safe_for_unpickling__ - 1 - >>> pickle3_ext.world.__getstate_manages_dict__ - 1 - >>> pickle3_ext.world.__name__ - 'world' - >>> pickle3_ext.world('Hello').__reduce__() - (, ('Hello',), ({}, 0)) - >>> for number in (24, 42): - ... wd = pickle3_ext.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): - 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/test/pointee.cpp b/test/pointee.cpp deleted file mode 100644 index 44836b05..00000000 --- a/test/pointee.cpp +++ /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. -#include -#include -#include -#include -#include - -struct A; - -int main() -{ - BOOST_STATIC_ASSERT( - (boost::is_same< - boost::python::pointee >::type - , char** - >::value)); - - BOOST_STATIC_ASSERT( - (boost::is_same< - boost::python::pointee >::type - , A>::value)); - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - BOOST_STATIC_ASSERT( - (boost::is_same< - boost::python::pointee::type - , char - >::value)); -#endif - return 0; -} diff --git a/test/pointer_type_id_test.cpp b/test/pointer_type_id_test.cpp deleted file mode 100644 index e3314e0b..00000000 --- a/test/pointer_type_id_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include - -int main() -{ - using namespace boost::python::converter; - - boost::python::type_info x - = boost::python::type_id(); - - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - return 0; -} diff --git a/test/polymorphism.cpp b/test/polymorphism.cpp deleted file mode 100644 index 02ec7b57..00000000 --- a/test/polymorphism.cpp +++ /dev/null @@ -1,101 +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 - -using namespace boost::python; - -struct Callback -{ - Callback(PyObject* o) : mSelf(o) {} - PyObject* mSelf; -}; - -struct A -{ - virtual ~A(){} - virtual std::string f() { return "A::f()"; } -}; - -struct ACallback : A, Callback -{ - ACallback (PyObject* self) : Callback(self) {} - - - std::string f() - { - return call_method(mSelf, "f"); - } - - std::string default_f() - { - return A::f(); - } -}; - -struct B : A -{ - virtual std::string f() { return "B::f()"; } -}; - -struct C : A -{ - virtual std::string f() { return "C::f()"; } -}; - -A& getBCppObj () -{ - static B b; - return b; -} - -std::string call_f(A& a) { return a.f(); } - -A* factory(unsigned choice) -{ - switch (choice % 3) - { - case 0: return new A; - break; - case 1: return new B; - break; - default: return new C; - break; - } -} - -C& getCCppObj () -{ - static C c; - return c; -} - -BOOST_PYTHON_MODULE_INIT(polymorphism_ext) -{ - class_("A") - .def("f", &A::f, &ACallback::default_f) - ; - - def("getBCppObj", getBCppObj, return_value_policy()); - - class_,boost::noncopyable>("C") - .def("f", &C::f) - ; - - def("getCCppObj", getCCppObj, return_value_policy()); - - def("factory", factory, return_value_policy()); - - def("call_f", call_f); -} - -//#include "module_tail.cpp" diff --git a/test/polymorphism.py b/test/polymorphism.py deleted file mode 100644 index a305bbea..00000000 --- a/test/polymorphism.py +++ /dev/null @@ -1,52 +0,0 @@ -import unittest -from polymorphism_ext import * - -class PolymorphTest(unittest.TestCase): - - def testReturnCpp(self): - - # Python Created Object With Same Id As - # Cpp Created B Object - # b = B(872) - - # Get Reference To Cpp Created B Object - a = getBCppObj() - - # Python Created B Object and Cpp B Object - # Should have same result by calling f() - self.failUnlessEqual ('B::f()', a.f()) - self.failUnlessEqual ('B::f()', call_f(a)) - self.failUnlessEqual ('A::f()', call_f(A())) - - def test_references(self): - # B is not exposed to Python - a = getBCppObj() - self.failUnlessEqual(type(a), A) - - # C is exposed to Python - c = getCCppObj() - self.failUnlessEqual(type(c), C) - - def test_factory(self): - self.failUnlessEqual(type(factory(0)), A) - self.failUnlessEqual(type(factory(1)), A) - self.failUnlessEqual(type(factory(2)), C) - - def testReturnPy(self): - - class D(A): - def f(self): - return 'D.f' - - d = D() - - self.failUnlessEqual ('D.f', d.f()) - self.failUnlessEqual ('D.f', call_f(d)) - -if __name__ == "__main__": - - # remove the option which upsets unittest - import sys - sys.argv = [ x for x in sys.argv if x != '--broken-auto-ptr' ] - - unittest.main() diff --git a/test/raw_pyobject_fail1.cpp b/test/raw_pyobject_fail1.cpp deleted file mode 100755 index 8fe73d68..00000000 --- a/test/raw_pyobject_fail1.cpp +++ /dev/null @@ -1,12 +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 - -int main() -{ - boost::python::converter::arg_to_python x(0); - return 0; -} diff --git a/test/raw_pyobject_fail2.cpp b/test/raw_pyobject_fail2.cpp deleted file mode 100755 index 7a0e79d9..00000000 --- a/test/raw_pyobject_fail2.cpp +++ /dev/null @@ -1,14 +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 - -struct X : PyObject {}; - -int main() -{ - boost::python::converter::arg_to_python x(0); - return 0; -} diff --git a/test/result.cpp b/test/result.cpp deleted file mode 100755 index 19b1cf41..00000000 --- a/test/result.cpp +++ /dev/null @@ -1,112 +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 - -using boost::python::detail::result; -using boost::type; - -void expect_int(type*) {} -void expect_string(type*) {} - -struct X {}; - -int main() -{ - // Test the usage which works for functions, member functions, and data members - expect_int( - result((int(*)())0) - ); - - expect_int( - result((int(*)(char))0) - ); - - expect_int( - result((int(X::*)())0) - ); - - expect_int( - result((int(X::*)(char))0) - ); - - expect_int( - result((int(X::*))0) - ); - - expect_string( - result((char*(*)())0) - ); - - expect_string( - result((char*(*)(char))0) - ); - - expect_string( - result((char*(X::*)())0) - ); - - expect_string( - result((char*(X::*)(char))0) - ); - - expect_string( - result((char*(X::*))0) - ); - - // Show that we can use the general version that works for - // AdaptableFunctions - expect_int( - result((int(*)())0,0) - ); - - expect_int( - result((int(*)(char))0,0) - ); - - expect_int( - result((int(X::*)())0,0) - ); - - expect_int( - result((int(X::*)(char))0,0) - ); - - expect_int( - result((int(X::*))0,0) - ); - - expect_int( - result(std::plus(),0) - ); - - expect_string( - result((char*(*)())0,0) - ); - - expect_string( - result((char*(*)(char))0,0) - ); - - expect_string( - result((char*(X::*)())0,0) - ); - - expect_string( - result((char*(X::*)(char))0,0) - ); - - expect_string( - result((char*(X::*))0,0) - ); - - expect_string( - result(std::plus(),0) - ); - - return 0; -} diff --git a/test/select_arg_to_python_test.cpp b/test/select_arg_to_python_test.cpp deleted file mode 100644 index df925a54..00000000 --- a/test/select_arg_to_python_test.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include -#include - -// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition -#if ((defined(__GNUC__) && __GNUC__ < 3)) \ - || (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) -namespace boost { namespace python { -BOOST_PYTHON_DECL bool handle_exception_impl(function0) -{ - return true; -} -}} -#endif - -int result; - -#define ASSERT_SAME(T1,T2) \ - if (!is_same< T1, T2 >::value) { \ - std::cout << "*********************\n"; \ - std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \ - std::cout << "*********************\n"; \ - result = 1; \ - } - -int main() -{ - using namespace boost::python::converter::detail; - using namespace boost::python::converter; - using namespace boost::python; - using namespace boost; - - - ASSERT_SAME( - select_arg_to_python::type, value_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python >::type, reference_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python >::type, pointer_shallow_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python::type, pointer_deep_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python >::type, object_manager_arg_to_python > - ); - - ASSERT_SAME( - select_arg_to_python::type, object_manager_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python::type, arg_to_python - ); - - return result; -} diff --git a/test/select_from_python_test.cpp b/test/select_from_python_test.cpp deleted file mode 100644 index 34018781..00000000 --- a/test/select_from_python_test.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include -#include -#include - -// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition -#if ((defined(__GNUC__) && __GNUC__ < 3)) \ - || (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) -namespace boost { namespace python { -BOOST_PYTHON_DECL bool handle_exception_impl(function0) -{ - return true; -} -}} -#endif - -int result; - -#define ASSERT_SAME(T1,T2) \ - if (!is_same< T1, T2 >::value) { \ - std::cout << "*********************\n"; \ - std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \ - std::cout << "*********************\n"; \ - result = 1; \ - } - -int main() -{ - using namespace boost::python::converter; - using namespace boost; - - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - return result; -} diff --git a/test/select_holder.cpp b/test/select_holder.cpp deleted file mode 100644 index c373af0a..00000000 --- a/test/select_holder.cpp +++ /dev/null @@ -1,85 +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 - -#define BOOST_INCLUDE_MAIN -#include - -struct BR {}; - -struct Base {}; -struct Derived : Base {}; - -namespace boost { namespace python -{ - // specialization - template <> - struct has_back_reference
- { - BOOST_STATIC_CONSTANT(bool, value = true); - }; -}} // namespace boost::python - -template -void assert_same(U* = 0, T* = 0) -{ - BOOST_TEST((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - -} - -template -void assert_holder(T* = 0, Held* = 0, Holder* = 0) -{ - assert_same( -#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - boost::python::objects::select_holder::execute((Held*)0).get() -#else - boost::python::objects::select_holder::type::get() -#endif - ); -} - -int test_main(int, char * []) -{ - using namespace boost::python::detail; - using namespace boost::python::objects; - - assert_holder >(); - - assert_holder >(); - assert_holder >(); - assert_holder >(); - - assert_holder >(); - - assert_holder - ,pointer_holder,Base> >(); - - assert_holder - ,pointer_holder_back_reference,Base> >(); - - assert_holder - ,pointer_holder_back_reference,BR> > (); - - return 0; -} - -#if !defined(_WIN32) || defined(__GNUC__) -// This definition is needed for MinGW 2.95.2 and KCC on OSF for some -// reason, but will break other Win32 compilers. -namespace boost { namespace python -{ - bool handle_exception_impl(boost::function0) { return false; } -}} -#endif diff --git a/test/shared_ptr.cpp b/test/shared_ptr.cpp deleted file mode 100644 index 39da8652..00000000 --- a/test/shared_ptr.cpp +++ /dev/null @@ -1,137 +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 "test_class.hpp" - -#include - -using namespace boost::python; -using boost::shared_ptr; - -typedef test_class<> X; -typedef test_class<1> Y; - -template -struct functions -{ - static int look(shared_ptr const& x) - { - return (x.get()) ? x->value() : -1; - } - - static void store(shared_ptr x) - { - storage = x; - } - - static void release_store() - { - store(shared_ptr()); - } - - static void modify(shared_ptr& x) - { - x.reset(); - } - - static shared_ptr get() { return storage; } - - static int look_store() - { - return look(get()); - } - - static void expose() - { - def("look", &look); - def("store", &store); - def("modify", &modify); - def("look_store", &look_store); - } - - static shared_ptr storage; -}; - -template shared_ptr functions::storage; - -struct Z : test_class<2> -{ - Z(int x) : test_class<2>(x) {} - virtual int v() { return this->value(); } -}; - -struct ZWrap : Z -{ - ZWrap(PyObject* self, int x) - : Z(x), m_self(self) {} - - - virtual int v() { return call_method(m_self, "v"); } - int default_v() { return Z::v(); } - - - PyObject* m_self; -}; - -struct YY : Y -{ - YY(int n) : Y(n) {} -}; - -shared_ptr factory(int n) -{ - return shared_ptr(n < 42 ? new Y(n) : new YY(n)); -} - -static int stored_v() { return functions::get()->v(); } -static shared_ptr stored_z() { return functions::get(); } - -BOOST_PYTHON_MODULE(shared_ptr_ext) -{ - class_("X", init()) - .def("value", &X::value) - ; - - def("factory", factory); - - functions::expose(); - def("x_count", &X::count); - def("x_release", &functions::release_store); - def("x_look_store", &functions::look_store); - - class_ >("Y", init()) - .def("value", &Y::value) - ; - - class_, boost::noncopyable>("YY", init()) - ; - - functions::expose(); - def("y_count", &Y::count); - def("y_release", &functions::release_store); - def("y_look_store", &functions::look_store); - - class_("Z", init()) - .def("value", &Z::value) - .def("v", &Z::v, &ZWrap::default_v) - ; - - functions::expose(); - def("z_count", &Z::count); - def("z_release", &functions::release_store); - def("z_look_store", &functions::look_store); - def("stored_z", &stored_z); - def("stored_v", &stored_v); -} - -#include "module_tail.cpp" - diff --git a/test/shared_ptr.py b/test/shared_ptr.py deleted file mode 100644 index e86da6df..00000000 --- a/test/shared_ptr.py +++ /dev/null @@ -1,109 +0,0 @@ -''' ->>> from shared_ptr_ext import * - ->>> type(factory(3)) - ->>> type(factory(42)) - - ->>> class P(Z): -... def v(self): -... return -Z.v(self); -... def __del__(self): -... print 'bye' -... ->>> p = P(12) ->>> p.value() -12 ->>> p.v() --12 ->>> look(p) -12 ->>> try: modify(p) -... except TypeError: pass -... else: 'print expected a TypeError' ->>> look(None) --1 ->>> store(p) ->>> del p ->>> stored_v() --12 ->>> z_count() -1 ->>> z_look_store() -12 ->>> z_release() -bye ->>> z_count() -0 - ->>> z = Z(13) ->>> z.value() -13 ->>> z.v() -13 ->>> try: modify(z) -... except TypeError: pass -... else: 'print expected a TypeError' ->>> store(z) ->>> assert stored_z() is z # show that deleter introspection works ->>> del z ->>> stored_v() -13 ->>> z_count() -1 ->>> z_look_store() -13 ->>> z_release() ->>> z_count() -0 - ->>> x = X(17) ->>> x.value() -17 ->>> look(x) -17 ->>> try: modify(x) -... except TypeError: pass -... else: 'print expected a TypeError' ->>> look(None) --1 ->>> store(x) ->>> del x ->>> x_count() -1 ->>> x_look_store() -17 ->>> x_release() ->>> x_count() -0 - - ->>> y = Y(19) ->>> y.value() -19 ->>> modify(y) ->>> look(y) --1 ->>> store(Y(23)) ->>> y_count() -1 ->>> y_look_store() -23 ->>> y_release() ->>> y_count() -0 -''' - -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/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/staticmethod.cpp b/test/staticmethod.cpp deleted file mode 100644 index a62f6275..00000000 --- a/test/staticmethod.cpp +++ /dev/null @@ -1,46 +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 - -using namespace boost::python; - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; -int X::counter; -int getXmagic(){return 7654321;} - -BOOST_PYTHON_MODULE(staticmethod_ext) -{ - class_("X", init()) - .def("value", &X::value) - .def("set", &X::set) - .def("count", &X::count) - .staticmethod("count") - .def("magic", &getXmagic) - .staticmethod("magic") - ; -} - -#include "module_tail.cpp" diff --git a/test/staticmethod.py b/test/staticmethod.py deleted file mode 100644 index 7fcaae60..00000000 --- a/test/staticmethod.py +++ /dev/null @@ -1,52 +0,0 @@ -''' ->>> from staticmethod_ext import * - ->>> class X1(X): -... pass - - ->>> x = X(16) ->>> x1 = X1(17) - - - ->>> x1.count() -2 - ->>> x.count() -2 - ->>> X1.count() -2 - ->>> X.count() -2 - - ->>> x1.magic() -7654321 - ->>> x.magic() -7654321 - ->>> X1.magic() -7654321 - ->>> X.magic() -7654321 - - -''' - -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/test/str.cpp b/test/str.cpp deleted file mode 100644 index e0252a17..00000000 --- a/test/str.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include - -using namespace boost::python; - -object convert_to_string(object data) -{ - return str(data); -} - -void work_with_string(object print) -{ - str data("this is a demo string"); - print(data.split(" ")); - print(data.split(" ",3)); - print(str("<->").join(data.split(" "))); - print(data.capitalize()); - print('[' + data.center(30) + ']'); - print(data.count("t")); - print(data.encode("utf-8")); - print(data.decode("utf-8")); - print(data.endswith("xx")); - print(data.startswith("test")); - print(data.splitlines()); - print(data.strip()); - print(data.swapcase()); - print(data.title()); - - print("find"); - print(data.find("demo")); - print(data.find("demo"),3,5); - print(data.find(std::string("demo"))); - print(data.find(std::string("demo"),9)); - - print("expandtabs"); - str tabstr("\t\ttab\tdemo\t!"); - print(tabstr.expandtabs()); - print(tabstr.expandtabs(4)); - print(tabstr.expandtabs(7.9)); - - print("operators"); - print( str("part1") + str("part2") ); -// print( str("a test string").slice(3,_) ); -// print( str("another test")[5] ); - - print(data.replace("demo",std::string("blabla"))); - print(data.rfind("i",5)); - print(data.rindex("i",5)); - print(data.startswith("asdf")); - print(data.endswith("asdf")); - print(data.translate(str('a')*256)); - - - bool tmp = data.isalnum() || data.isalpha() || data.isdigit() || data.islower() || - data.isspace() || data.istitle() || data.isupper(); - (void)tmp; // ignored. -} - - -BOOST_PYTHON_MODULE(str_ext) -{ - def("convert_to_string",convert_to_string); - def("work_with_string",work_with_string); -} - diff --git a/test/str.py b/test/str.py deleted file mode 100644 index 666096b1..00000000 --- a/test/str.py +++ /dev/null @@ -1,52 +0,0 @@ -""" ->>> from str_ext import * ->>> def printer(*args): -... for x in args: print x, -... print -... ->>> work_with_string(printer) -['this', 'is', 'a', 'demo', 'string'] -['this', 'is', 'a', 'demo string'] -this<->is<->a<->demo<->string -This is a demo string -[ this is a demo string ] -2 -this is a demo string -this is a demo string -0 -0 -['this is a demo string'] -this is a demo string -THIS IS A DEMO STRING -This Is A Demo String -find -10 -10 3 5 -10 -10 -expandtabs - tab demo ! - tab demo ! - tab demo ! -operators -part1part2 -this is a blabla string -18 -18 -0 -0 -aaaaaaaaaaaaaaaaaaaaa -""" - -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/test/string_literal.cpp b/test/string_literal.cpp deleted file mode 100644 index 882fbd4e..00000000 --- a/test/string_literal.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//#include -#include -#include -#include - -using namespace boost::python::detail; - - -template -void expect_string_literal(T const&) -{ - BOOST_STATIC_ASSERT(is_string_literal::value); -} - -int main() -{ - expect_string_literal("hello"); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(is_string_literal::value); - BOOST_STATIC_ASSERT(is_string_literal::value); - - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - return 0; -} diff --git a/test/submod_subclass_api.cpp b/test/submod_subclass_api.cpp deleted file mode 100644 index e716aaf0..00000000 --- a/test/submod_subclass_api.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright David Hawkes 2002. -// Permission is hereby granted to copy, use and modify this software -// for any purpose, including commercial distribution, provided this -// copyright notice is not removed. No warranty WHATSOEVER is provided with this -// software. Any user(s) accepts this software "as is" and as such they will not -// bind the author(s) to any claim of suitabilty for any purpose. - -// embed_test.cpp : substantial test of embedding python in c++ using boost - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost; -using namespace boost::python; - - -// The following macros are for our convenience and coding expediency... -// There is no particular recomendation that they be used elsewhere -// as they are not feature complete and are just sufficient to suport -// the code here - - -#define DEF(fn) def(#fn, fn) -#define DEF_C(c, fn) def(#fn, &c::fn) -#define DEF_C_CB(c, fn) def(#fn, &c##_callback::base_##fn) - -#define CLASS(c) class_ >(#c) -#define CLASS_CB(c) class_, noncopyable >(#c) - -#define START_CALLBACK_CLASS(c) \ -class c##_callback : public c \ -{ \ - typedef c __base__; \ -public: \ - c##_callback(PyObject* self) : m_self(self) {} \ -private: \ - PyObject* m_self; \ -public: - -#define END_CALLBACK_CLASS }; - - -#define CALLBACK_MEMBER0(fn, rtn) \ -rtn fn() { return call_method(m_self, #fn); } \ -rtn base_##fn() { return __base__::fn(); } - - -#define CALLBACK_MEMBER0C(fn, rtn) \ -rtn fn() const { return call_method(m_self, #fn); } \ -rtn base_##fn() const { return __base__::fn(); } -// End of convenience macros - -// useful support classes -template -struct class_object : public object -{ - typedef object base; - class_object() : m_class_ptr(NULL) {} - class_object(object const& o) : base(o) { init(); } - class_object& operator=(object const& o) - { - base::operator=(o); - init(); - return *this; - } - T* operator->() const { return m_class_ptr; } - T& operator*() const { return *m_class_ptr; } -private: - void init() - { - m_class_ptr = arg_from_python(ptr())(ptr()); - } - T* m_class_ptr; -}; - -template -struct item_object : public object -{ - typedef object base; - item_object() {} - item_object(object const& o) : base(o), m_class(arg_from_python(ptr())(ptr())) {} - item_object& operator=(object const& o) - { - base::operator=(o); - init(); - return *this; - } - operator T() { return m_class; } -private: - void init() - { - m_class = arg_from_python(ptr())(ptr()); - } - T m_class; -}; -// end of useful support classes - -// pass our args in this struct -struct main_args { - main_args(int _argc, char* _argv[]) : argc(_argc), argv(_argv) {} - int argc; - char** argv; -}; -int python_main(main_args const &ma); - -// python module init -BOOST_PYTHON_MODULE(python_main) -{ - DEF(python_main); - CLASS(main_args); -} - -// sub module tests -namespace sm { - -int test_func() { return 7; } - -BOOST_PYTHON_MODULE(sm_test) -{ - // define a submodule - boost::python::module(".sm"); - // define a 2nd submodule - boost::python::module(".sm.sm2"); - // define a test function to appear in 2nd submodule - DEF(test_func); -} - -// sub-module tests -int test() -{ - api::run_simple_string("import sm_test"); - if(api::call_statement("_0 = bpl_test('sub modules', sm_test.sm.sm2.test_func, _1)", test_func())) - return 1; - return 0; -} - -} - -// sub class tests -namespace sc { - -class c1 { -public: - c1() {} - class c2 { - public: - c2() : n(2) {} - int n; - }; - c2 t; -}; - -c1::c2 test_func() { - return c1().t; -} - -BOOST_PYTHON_MODULE(sc_test) -{ - class_("c1.c2") - .def_init() - .def_readwrite("n", &c1::c2::n); - CLASS(c1) - .def_init() - .def_readwrite("t", &c1::t); - DEF(test_func); -} - -// sub-class tests -int test() -{ - api::run_simple_string("import sc_test"); - if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1.c2().n, _1.n)", test_func())) - return 1; - if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1().t.n, _1.n)", test_func())) - return 1; - return 0; -} - -} - -// new main that will have a python execution frame -int main(int argc, char* argv[]) -{ - // default return value; - int rtn = 0; - // define all the built-in modules used - PyImport_AppendInittab("python_main", initpython_main); - PyImport_AppendInittab("sm_test", sm::initsm_test); - PyImport_AppendInittab("sc_test", sc::initsc_test); - // initialize python - Py_Initialize(); - // start a new block so that any objects are released prior to finalizing - { - // import our main module - this will also initialise boost - api::run_simple_string("import python_main"); - // We call back here so we have a proper python execution frame to work with - item_object o_rtn(api::call_statement("_0 = python_main.python_main(_1)", main_args(argc, argv))); - rtn = o_rtn; - } - // clean up - Py_Finalize(); - return rtn; -} - -char *bpl_test = -"def bpl_test(name, func, result):\n" -" print 'testing %s...' % name\n" -" if func() != result:\n" -" print 'failed'\n" -" return 1\n" -" else:\n" -" print 'OK'\n" -" return 0\n"; - - -int python_main(main_args const &ma) -{ - api::print("running...\n"); - api::call_statement(bpl_test); - if(sm::test()) - return 1; - if(sc::test()) - return 1; - return 0; -} diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp deleted file mode 100644 index 4f08c534..00000000 --- a/test/test_builtin_converters.cpp +++ /dev/null @@ -1,124 +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 - -template -struct by_value -{ - static T rewrap(T x) - { - return x; - } -}; - -template -struct by_const_reference -{ - static T rewrap(T const& x) - { - return x; - } -}; - -template -struct by_reference -{ - static T rewrap(T& x) - { - return x; - } -}; - -using boost::python::def; -using boost::python::handle; -using boost::python::object; -using boost::python::borrowed; - -// Used to test that arbitrary handle<>s can be returned -handle get_type(handle<> x) -{ - return handle(borrowed(x->ob_type)); -} - -handle<> return_null_handle() -{ - return handle<>(); -} - -char const* rewrap_value_mutable_cstring(char* x) { return x; } - -BOOST_PYTHON_MODULE(builtin_converters) -{ - def("get_type", get_type); - def("return_null_handle", return_null_handle); - - def("rewrap_value_bool", by_value::rewrap); - def("rewrap_value_char", by_value::rewrap); - 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); -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -#ifdef HAVE_LONG_LONG - def("rewrap_value_long_long", by_value::rewrap); - def("rewrap_value_unsigned_long_long", by_value::rewrap); -# endif - 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_complex_float", by_value >::rewrap); - def("rewrap_value_complex_double", by_value >::rewrap); - def("rewrap_value_complex_long_double", by_value >::rewrap); - def("rewrap_value_string", by_value::rewrap); - def("rewrap_value_cstring", by_value::rewrap); - def("rewrap_value_handle", by_value >::rewrap); - def("rewrap_value_object", by_value::rewrap); - - // Expose this to illustrate our failings ;-). See test_builtin_converters.py - def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring); - - - def("rewrap_const_reference_bool", by_const_reference::rewrap); - def("rewrap_const_reference_char", by_const_reference::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); -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG - def("rewrap_const_reference_long_long", by_const_reference::rewrap); - def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap); -# endif - 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_complex_float", by_const_reference >::rewrap); - def("rewrap_const_reference_complex_double", by_const_reference >::rewrap); - def("rewrap_const_reference_complex_long_double", by_const_reference >::rewrap); - def("rewrap_const_reference_string", by_const_reference::rewrap); - def("rewrap_const_reference_cstring", by_const_reference::rewrap); - def("rewrap_const_reference_handle", by_const_reference >::rewrap); - def("rewrap_const_reference_object", by_const_reference::rewrap); - def("rewrap_reference_object", by_reference::rewrap); -} - diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py deleted file mode 100644 index 0b3bc645..00000000 --- a/test/test_builtin_converters.py +++ /dev/null @@ -1,238 +0,0 @@ -r""" ->>> from builtin_converters import * - -# Synthesize idendity functions in case long long not supported ->>> if not 'rewrap_value_long_long' in dir(): -... def rewrap_value_long_long(x): return long(x) -... def rewrap_value_unsigned_long_long(x): return long(x) -... def rewrap_const_reference_long_long(x): return long(x) -... def rewrap_const_reference_unsigned_long_long(x): return long(x) - ->>> rewrap_value_bool(None) -0 ->>> rewrap_value_bool(0) -0 ->>> rewrap_value_bool(33) -1 ->>> rewrap_value_char('x') -'x' - - Note that there's currently silent truncation of strings passed to - char arguments. - ->>> rewrap_value_char('xy') -'x' ->>> 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 - - test unsigned long values which don't fit in a signed long. - strip any 'L' characters in case the platform has > 32 bit longs - ->>> hex(rewrap_value_unsigned_long(0x80000001L)).replace('L','') -'0x80000001' - ->>> rewrap_value_long_long(42) -42L ->>> rewrap_value_unsigned_long_long(42) -42L - - show that we have range checking. - ->>> try: rewrap_value_unsigned_short(-42) -... except OverflowError: pass -... else: print 'expected an OverflowError!' - ->>> try: rewrap_value_int(sys.maxint * 2) -... except OverflowError: pass -... else: print 'expected an OverflowError!' - - ->>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001 ->>> rewrap_value_double(4.2) - 4.2 -0.0 ->>> rewrap_value_long_double(4.2) - 4.2 -0.0 - ->>> assert abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001 - ->>> rewrap_value_cstring('hello, world') -'hello, world' ->>> rewrap_value_string('yo, wassup?') -'yo, wassup?' - - wrap strings with embedded nulls: - ->>> rewrap_value_string('yo,\0wassup?') -'yo,\x00wassup?' - ->>> rewrap_value_handle(1) -1 ->>> x = 'hi' ->>> assert rewrap_value_handle(x) is x ->>> assert rewrap_value_object(x) is x - - Note that we can currently get a mutable pointer into an immutable - Python string: - ->>> rewrap_value_mutable_cstring('hello, world') -'hello, world' - ->>> rewrap_const_reference_bool(None) -0 ->>> rewrap_const_reference_bool(0) -0 - ->>> try: rewrap_const_reference_bool('yes') -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> rewrap_const_reference_char('x') -'x' - - Note that there's currently silent truncation of strings passed to - char arguments. - ->>> rewrap_const_reference_char('xy') -'x' ->>> 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 ->>> rewrap_const_reference_long_long(42) -42L ->>> rewrap_const_reference_unsigned_long_long(42) -42L - - ->>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 ->>> rewrap_const_reference_double(4.2) - 4.2 -0.0 ->>> rewrap_const_reference_long_double(4.2) - 4.2 -0.0 - ->>> assert abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001 - ->>> rewrap_const_reference_cstring('hello, world') -'hello, world' ->>> rewrap_const_reference_string('yo, wassup?') -'yo, wassup?' - ->>> rewrap_const_reference_handle(1) -1 ->>> x = 'hi' ->>> assert rewrap_const_reference_handle(x) is x ->>> assert rewrap_const_reference_object(x) is x ->>> assert rewrap_reference_object(x) is x - - -Check that None <==> NULL - ->>> rewrap_const_reference_cstring(None) - -But None cannot be converted to a string object: - ->>> try: rewrap_const_reference_string(None) -... except TypeError: pass -... else: print 'expected a TypeError exception' - -Now check implicit conversions between floating/integer types - ->>> rewrap_const_reference_float(42) -42.0 - ->>> rewrap_const_reference_float(42L) -42.0 - ->>> try: rewrap_const_reference_int(42.0) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> rewrap_value_float(42) -42.0 - ->>> try: rewrap_value_int(42.0) -... except TypeError: pass -... else: print 'expected a TypeError exception' - -Check that classic classes also work - ->>> class FortyTwo: -... def __int__(self): -... return 42 -... def __float__(self): -... return 42.0 -... def __complex__(self): -... return complex(4+.2j) -... def __str__(self): -... return '42' - ->>> try: rewrap_const_reference_float(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> try: rewrap_value_int(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> try: rewrap_const_reference_string(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> try: rewrap_value_complex_double(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - -# show that arbitrary handle instantiations can be returned ->>> assert get_type(1) is type(1) - ->>> assert return_null_handle() is None -""" - -def run(args = None): - import sys - import doctest - import builtin_converters - - if 'rewrap_value_long_long' in dir(builtin_converters): - print 'LONG_LONG supported, testing...' - else: - print 'LONG_LONG not supported, skipping those tests...' - - 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/test/test_class.hpp b/test/test_class.hpp deleted file mode 100644 index 18164102..00000000 --- a/test/test_class.hpp +++ /dev/null @@ -1,33 +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 TEST_CLASS_DWA2002326_HPP -# define TEST_CLASS_DWA2002326_HPP -# include - -template -struct test_class -{ - explicit test_class(int x) : x(x), magic(7654321 + n) { ++counter; } - test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; } - virtual ~test_class() { assert(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321 + n); this->x = x; } - int value() const { assert(magic == 7654321 + n); return x; } - operator int() const { return x; } - static int count() { return counter; } - - int x; - long magic; - static int counter; - - private: - void operator=(test_class const&); -}; - -template -int test_class::counter; - -#endif // TEST_CLASS_DWA2002326_HPP diff --git a/test/test_cltree.py b/test/test_cltree.py deleted file mode 100644 index 8408f7f2..00000000 --- a/test/test_cltree.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python - -from cltree import basic,symbol,constant,variable - -b = basic() -c = constant() -s = symbol() -v = variable() - -assert isinstance(b,basic) -assert not isinstance(b,symbol) -assert not isinstance(b,constant) -assert not isinstance(b,variable) - -assert isinstance(c,basic) -assert isinstance(c,constant) -assert not isinstance(c,symbol) -assert not isinstance(c,variable) - -assert not isinstance(s,basic) -assert isinstance(s,symbol) -assert not isinstance(s,constant) -assert not isinstance(s,variable) - -assert isinstance(v,basic) -assert not isinstance(v,symbol) -assert not isinstance(v,constant) -assert isinstance(v,variable) - -print 'b=',b -assert repr(b)=='cltree.basic()' -print 's=',s -assert repr(s)!='cltree.wrapped_symbol()' # because not isinstance(s,basic) -print 'c=',c -assert repr(c)=='cltree.constant()' -print 'v=',v -assert repr(v)=='cltree.wrapped_variable()' - - -print 'ok' diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp deleted file mode 100644 index 6631d8ea..00000000 --- a/test/test_pointer_adoption.cpp +++ /dev/null @@ -1,126 +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 - -using namespace boost::python; - -int a_instances = 0; - -int num_a_instances() { return a_instances; } - -struct inner -{ - inner(std::string const& s) - : s(s) - {} - - void change(std::string const& new_s) - { - this->s = new_s; - } - - std::string s; -}; - -struct Base -{ - virtual ~Base() {} -}; - -struct A : Base -{ - A(std::string const& s) - : x(s) - { - ++a_instances; - } - - ~A() - { - --a_instances; - } - - std::string content() const - { - return x.s; - } - - inner& get_inner() - { - return x; - } - - inner x; -}; - -struct B -{ - B() : x(0) {} - B(A* x_) : x(x_) {} - - inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } - - std::string a_content() - { - return x ? x->content() : std::string("empty"); - } - - A* x; -}; - - -A* create(std::string const& s) -{ - return new A(s); -} - -A* as_A(Base* b) -{ - return dynamic_cast(b); -} - -BOOST_PYTHON_MODULE(test_pointer_adoption_ext) -{ - def("num_a_instances", num_a_instances); - - // Specify the manage_new_object return policy to take - // ownership of create's result - def("create", create, return_value_policy()); - - def("as_A", as_A, return_internal_reference<>()); - - class_("Base") - ; - - class_ >("A", no_init) - .def("content", &A::content) - .def("get_inner", &A::get_inner, return_internal_reference<>()) - ; - - class_("inner", no_init) - .def("change", &inner::change) - ; - - class_("B") - .def(init()[with_custodian_and_ward_postcall<1,2>()]) - - .def("adopt", &B::adopt - // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") - , return_internal_reference<2 - // Meanwhile, self holds a reference to the 2nd argument. - , with_custodian_and_ward<1,2> >() - ) - - .def("a_content", &B::a_content) - ; -} - -#include "module_tail.cpp" diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py deleted file mode 100644 index d811bce8..00000000 --- a/test/test_pointer_adoption.py +++ /dev/null @@ -1,88 +0,0 @@ -""" ->>> from test_pointer_adoption_ext import * - ->>> num_a_instances() -0 - ->>> a = create('dynamically allocated') ->>> num_a_instances() -1 - ->>> a.content() -'dynamically allocated' - ->>> innards = a.get_inner() ->>> innards.change('with an exposed reference') ->>> a.content() -'with an exposed reference' - -# The a instance should be kept alive... ->>> a = None ->>> num_a_instances() -1 - -# ...until we're done with its innards ->>> innards = None ->>> num_a_instances() -0 - ->>> b = B() ->>> a = create('another') ->>> b.a_content() -'empty' ->>> innards = b.adopt(a); ->>> b.a_content() -'another' ->>> num_a_instances() -1 ->>> del a # innards and b are both holding a reference ->>> num_a_instances() -1 ->>> innards.change('yet another') ->>> b.a_content() -'yet another' - ->>> del innards ->>> num_a_instances() # b still owns a reference to a -1 ->>> del b ->>> num_a_instances() -0 - -Test call policies for constructors here - ->>> a = create('second a') ->>> num_a_instances() -1 ->>> b = B(a) ->>> num_a_instances() -1 ->>> a.content() -'second a' - ->>> del a ->>> num_a_instances() -1 ->>> b.a_content() -'second a' - ->>> del b ->>> num_a_instances() -0 - ->>> assert as_A(create('dynalloc')) is not None ->>> base = Base() ->>> assert as_A(base) is None -""" -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/test/tuple.cpp b/test/tuple.cpp deleted file mode 100644 index fce3da85..00000000 --- a/test/tuple.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include - -using namespace boost::python; - -object convert_to_tuple(object data) -{ - return tuple(data); -} - -void test_operators(tuple t1, tuple t2, object print) -{ - print(t1 + t2); -} - -tuple mktuple0() { return make_tuple(); } -tuple mktuple1(int x) { return make_tuple(x); } -tuple mktuple2(char const* a1, int x) { return make_tuple(a1, x); } - -BOOST_PYTHON_MODULE(tuple_ext) -{ - def("convert_to_tuple",convert_to_tuple); - def("test_operators",test_operators); - def("make_tuple", mktuple0); - def("make_tuple", mktuple1); - def("make_tuple", mktuple2); -} diff --git a/test/tuple.py b/test/tuple.py deleted file mode 100644 index cd899df4..00000000 --- a/test/tuple.py +++ /dev/null @@ -1,32 +0,0 @@ -""" ->>> from tuple_ext import * ->>> def printer(*args): -... for x in args: print x, -... print -... ->>> print convert_to_tuple("this is a test string") -('t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g') ->>> t1 = convert_to_tuple("this is") ->>> t2 = (1,2,3,4) ->>> test_operators(t1,t2,printer) -('t', 'h', 'i', 's', ' ', 'i', 's', 1, 2, 3, 4) ->>> make_tuple() -() ->>> make_tuple(42) -(42,) ->>> make_tuple('hello', 42) -('hello', 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/test/upcast.cpp b/test/upcast.cpp deleted file mode 100755 index b02d2534..00000000 --- a/test/upcast.cpp +++ /dev/null @@ -1,19 +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 - -struct X { long x; }; -struct Y : X, PyObject {}; - -int main() -{ - PyTypeObject o; - Y y; - assert(&boost::python::upcast(&o)->ob_refcnt == &o.ob_refcnt); - assert(&boost::python::upcast(&y)->ob_refcnt == &y.ob_refcnt); - return 0; -} - diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp deleted file mode 100644 index 4fa6c7ee..00000000 --- a/test/virtual_functions.cpp +++ /dev/null @@ -1,113 +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 - -using namespace boost::python; - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; - -struct Y : X -{ - Y(int x) : X(x) {}; -}; - -struct abstract : X -{ - abstract(int x) : X(x) {}; - int call_f(Y const& y) { return f(y); } - virtual int f(Y const& y) = 0; -}; - -struct concrete : X -{ - concrete(int x) : X(x) {}; - int call_f(Y const& y) { return f(y); } - virtual int f(Y const& y) { set(y.value()); return y.value(); } -}; - -struct abstract_callback : abstract -{ - abstract_callback(PyObject* p, int x) - : abstract(x), self(p) - {} - - int f(Y const& y) - { - return call_method(self, "f", boost::ref(y)); - } - - PyObject* self; -}; - -struct concrete_callback : concrete -{ - concrete_callback(PyObject* p, int x) - : concrete(x), self(p) - {} - - concrete_callback(PyObject* p, concrete const& x) - : concrete(x), self(p) - {} - - int f(Y const& y) - { - return call_method(self, "f", boost::ref(y)); - } - - int f_impl(Y const& y) - { - return this->concrete::f(y); - } - - PyObject* self; -}; - -int X::counter; - -BOOST_PYTHON_MODULE(virtual_functions_ext) -{ - class_("concrete", init()) - .def("value", &concrete::value) - .def("set", &concrete::set) - .def("call_f", &concrete::call_f) - .def("f", &concrete_callback::f_impl) - ; - - class_("abstract", init()) - - .def("value", &abstract::value) - .def("call_f", &abstract::call_f) - .def("set", &abstract::set) - ; - - class_("Y", init()) - .def("value", &Y::value) - .def("set", &Y::set) - ; -} - -#include "module_tail.cpp" diff --git a/test/virtual_functions.py b/test/virtual_functions.py deleted file mode 100644 index 9b074b1a..00000000 --- a/test/virtual_functions.py +++ /dev/null @@ -1,102 +0,0 @@ -''' ->>> from virtual_functions_ext import * - ->>> class C1(concrete): -... def f(self, y): -... return concrete.f(self, Y(-y.value())) - ->>> class C2(concrete): -... pass - ->>> class A1(abstract): -... def f(self, y): -... return y.value() * 2 - ->>> class A2(abstract): -... pass - - ->>> y1 = Y(16) ->>> y2 = Y(17) - - - -# -# Test abstract with f overridden -# ->>> a1 = A1(42) ->>> a1.value() -42 - -# Call f indirectly from C++ ->>> a1.call_f(y1) -32 - -# Call f directly from Python ->>> a1.f(y2) -34 - -# -# Test abstract with f not overridden -# ->>> a2 = A2(42) ->>> a2.value() -42 - -# Call f indirectly from C++ ->>> try: a2.call_f(y1) -... except AttributeError: pass -... else: print 'no exception' - -# Call f directly from Python ->>> try: a2.call_f(y2) -... except AttributeError: pass -... else: print 'no exception' - -############# Concrete Tests ############ - -# -# Test concrete with f overridden -# ->>> c1 = C1(42) ->>> c1.value() -42 - -# Call f indirectly from C++ ->>> c1.call_f(y1) --16 - -# Call f directly from Python ->>> c1.f(y2) --17 - -# -# Test concrete with f not overridden -# ->>> c2 = C2(42) ->>> c2.value() -42 - -# Call f indirectly from C++ ->>> c2.call_f(y1) -16 - -# Call f directly from Python ->>> c2.f(y2) -17 - - -''' - -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 e6a0f2d3..00000000 --- a/todo.txt +++ /dev/null @@ -1,24 +0,0 @@ -High Priority: --------------- - -Document builtin correspondences between builtiin Python types and C++ -types - -FILE* conversions: http://aspn.activestate.com/ASPN/Mail/Message/1411366 - -Finish shared_ptr support: http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1456023 - -Medium Priority: ----------------- - -Implement type_info streaming for GCC -(http://mail.python.org/pipermail/c++-sig/2002-June/001277.html) - -Low Priority: ------------- -Write "inside the Python type system", a survey of typeobject.c in -Python source -- may go hand-in-hand with enum wrapping - -Better overload resolution - choose best match - -