diff --git a/stormpy/CMakeLists.txt b/stormpy/CMakeLists.txt deleted file mode 100644 index b7af91a8f..000000000 --- a/stormpy/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -cmake_minimum_required(VERSION 3.0.0) -project(pystorm) - - -find_package(storm REQUIRED) -add_subdirectory(resources/pybind11) - - -file(GLOB_RECURSE STORM_CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/core/*.cpp) - -pybind11_add_module(stormpy.core ${CMAKE_CURRENT_SOURCE_DIR}/src/mod_core.cpp ${STORM_CORE_SOURCES}) -target_include_directories(stormpy.core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${storm_INCLUDE_DIR}) -target_link_libraries(stormpy.core PRIVATE storm) - -file(GLOB_RECURSE STORM_INFO_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/info/*.cpp) - -pybind11_add_module(stormpy.info ${CMAKE_CURRENT_SOURCE_DIR}/src/mod_info.cpp ${STORM_INFO_SOURCES}) -target_include_directories(stormpy.info PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${storm_INCLUDE_DIR}) -target_link_libraries(stormpy.info PRIVATE storm) - - -file(GLOB_RECURSE STORM_EXPRESSIONS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/expressions/*.cpp) - -pybind11_add_module(stormpy.expressions ${CMAKE_CURRENT_SOURCE_DIR}/src/mod_expressions.cpp ${STORM_EXPRESSIONS_SOURCES}) -target_include_directories(stormpy.expressions PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${storm_INCLUDE_DIR}) -target_link_libraries(stormpy.expressions PRIVATE storm) - - -file(GLOB_RECURSE STORM_LOGIC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/logic/*.cpp) - -pybind11_add_module(stormpy.logic ${CMAKE_CURRENT_SOURCE_DIR}/src/mod_logic.cpp ${STORM_LOGIC_SOURCES}) -target_include_directories(stormpy.logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${storm_INCLUDE_DIR}) -target_link_libraries(stormpy.logic PRIVATE storm) - -file(GLOB_RECURSE STORM_STORAGE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/storage/*.cpp) - -pybind11_add_module(stormpy.storage ${CMAKE_CURRENT_SOURCE_DIR}/src/mod_storage.cpp ${STORM_STORAGE_SOURCES}) -target_include_directories(stormpy.storage PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${storm_INCLUDE_DIR}) -target_link_libraries(stormpy.storage PRIVATE storm) - -#set(STORMPY_OUTPUT_DIR "${PROJECT_BINARY_DIR}/stormpy") -#set(STORMPY_SOURCE_DIR "${PROJECT_SOURCE_DIR}/stormpy") -# -#if(STORM_HAVE_CLN) -# set(STORMPY_USE_CLN 1) -#else() -# set(STORMPY_USE_CLN 0) -#endif() -# -## Set configuration file -#get_directory_property(STORMPY_INCLUDE_DIRS_PROP INCLUDE_DIRECTORIES) -#foreach(arg ${STORMPY_INCLUDE_DIRS_PROP}) -# set(STORMPY_INCLUDE_DIRS "${STORMPY_INCLUDE_DIRS}${sep}${arg}") -# set(sep ":") -#endforeach() -#set(STORMPY_COMPILE_ARGS ${CMAKE_CXX_FLAGS}) -#set(STORMPY_LIBRARY_DIRS "${PROJECT_BINARY_DIR}/src/storm") -#set(STORMPY_RPATH "${PROJECT_BINARY_DIR}/src/storm") -#configure_file ( -# "${PROJECT_SOURCE_DIR}/stormpy/setup.cfg.in" -# "${PROJECT_SOURCE_DIR}/stormpy/setup.cfg" -#) -# - diff --git a/stormpy/MANIFEST.in b/stormpy/MANIFEST.in deleted file mode 100644 index 0e6f51f28..000000000 --- a/stormpy/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -recursive-include src *.h diff --git a/stormpy/lib/.gitignore b/stormpy/lib/.gitignore deleted file mode 100644 index c70bcf8ef..000000000 --- a/stormpy/lib/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.so -__pycache__/ -stormpy.egg-info/ diff --git a/stormpy/lib/stormpy/__init__.py b/stormpy/lib/stormpy/__init__.py deleted file mode 100644 index 3dee81dd7..000000000 --- a/stormpy/lib/stormpy/__init__.py +++ /dev/null @@ -1,70 +0,0 @@ -""" -It looks like you want to know about 'stormpy'. - - _.-;:q=._ - .' j=""^k;:\. - ; .F ";`Y - ,;.J_ ;'j - ,-;"^7F : .F _________________ - ,-'-_<. ;gj. _.,---""'' .' - ; _,._`\. : `T"5, ; - : `?8w7 `J ,-'" -^q. ` ; - \;._ _,=' ; n58L Y. .' - F;"; .' k_ `^' j' ; - J;:: ; "y:-=' ; - L;;== |:; jT\ ; - L;:;J J:L 7:;' _ ; - I;|:.L |:k J:.' , ' . ; - |;J:.| ;.I F.: . : - ;J;:L:: |.| |.J , ' ` ; ; - .' J:`J.`. :.J |. L . ; ; - ; L :k:`._ ,',j J; | ` , ; ; - .' I :`=.:."_".' L J `.' - .' |.: `"-=-' |.J ; - _.-' `: : ;:; _ ; - _.-'" J: : /.;' ; ; - ='_ k;.\. _.;:Y' , .' - `"---..__ `Y;."-=';:=' , .' - `""--..__ `"==="' - .' - ``""---...__ itz .-' - ``""---' -""" - -from . import core -from .core import * -from . import storage -from .storage import * - -core.set_up("") - -def build_model(program, formulae): - intermediate = core._build_model(program, formulae) - assert not intermediate.supports_parameters - if intermediate.model_type == ModelType.DTMC: - return intermediate.as_dtmc() - elif intermediate.model_type == ModelType.MDP: - return intermediate.as_mdp() - else: - raise RuntimeError("Not supported non-parametric model constructed") - -def build_parametric_model(program, formulae): - intermediate = core._build_parametric_model(program, formulae) - assert intermediate.supports_parameters - if intermediate.model_type == ModelType.DTMC: - return intermediate.as_pdtmc() - elif intermediate.model_type == ModelType.MDP: - return intermediate.as_pmdp() - else: - raise RuntimeError("Not supported parametric model constructed") - -def perform_bisimulation(model, formula, bisimulation_type): - if model.supports_parameters: - return core._perform_parametric_bisimulation(model, formula, bisimulation_type) - else: - return core._perform_bisimulation(model, formula, bisimulation_type) - -def model_checking(model, formula): - if model.supports_parameters: - return core._parametric_model_checking(model, formula) - else: - return core._model_checking(model, formula) diff --git a/stormpy/lib/stormpy/expressions/__init__.py b/stormpy/lib/stormpy/expressions/__init__.py deleted file mode 100644 index b185f368c..000000000 --- a/stormpy/lib/stormpy/expressions/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import expressions -from .expressions import * diff --git a/stormpy/lib/stormpy/info/__init__.py b/stormpy/lib/stormpy/info/__init__.py deleted file mode 100644 index d8e3cfa68..000000000 --- a/stormpy/lib/stormpy/info/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import info -from .info import * diff --git a/stormpy/lib/stormpy/logic/__init__.py b/stormpy/lib/stormpy/logic/__init__.py deleted file mode 100644 index 9ab762097..000000000 --- a/stormpy/lib/stormpy/logic/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import logic -from .logic import * diff --git a/stormpy/lib/stormpy/storage/__init__.py b/stormpy/lib/stormpy/storage/__init__.py deleted file mode 100644 index c68800f3a..000000000 --- a/stormpy/lib/stormpy/storage/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from . import storage -from .storage import * -from . import state,action diff --git a/stormpy/lib/stormpy/storage/action.py b/stormpy/lib/stormpy/storage/action.py deleted file mode 100644 index 420f5b3ba..000000000 --- a/stormpy/lib/stormpy/storage/action.py +++ /dev/null @@ -1,36 +0,0 @@ -class Action: - """ Represents an action in the model """ - - def __init__(self, row_group_start, row_group_end, row, model): - """ Initialize - :param row_group_start: Start index of the row group in the matrix - :param row_group_end: End index of the row group in the matrix - :param row: Index of the corresponding row in the matrix - :param model: Corresponding model - """ - self.row_group_start = row_group_start - self.row_group_end = row_group_end - self.row = row - 1 - self.model = model - assert row >= -1 and row + row_group_start <= row_group_end - - def __iter__(self): - return self - - def __next__(self): - if self.row + self.row_group_start >= self.row_group_end - 1: - raise StopIteration - else: - self.row += 1 - return self - - def __str__(self): - return "{}".format(self.row) - - def transitions(self): - """ Get transitions associated with the action - :return List of tranistions - """ - row = self.row_group_start + self.row - #return self.model.transition_matrix().get_row(self.row_group_start + self.row) - return self.model.transition_matrix.row_iter(row, row) diff --git a/stormpy/lib/stormpy/storage/state.py b/stormpy/lib/stormpy/storage/state.py deleted file mode 100644 index 6a315e76d..000000000 --- a/stormpy/lib/stormpy/storage/state.py +++ /dev/null @@ -1,34 +0,0 @@ -from . import action - -class State: - """ Represents a state in the model """ - - def __init__(self, id, model): - """ Initialize - :param id: Id of the state - :param model: Corresponding model - """ - self.id = id - 1 - self.model = model - - def __iter__(self): - return self - - def __next__(self): - if self.id >= self.model.nr_states - 1: - raise StopIteration - else: - self.id += 1 - return self - - def __str__(self): - return "{}".format(self.id) - - def actions(self): - """ Get actions associated with the state - :return List of actions - """ - row_group_indices = self.model.transition_matrix._row_group_indices - start = row_group_indices[self.id] - end = row_group_indices[self.id+1] - return action.Action(start, end, 0, self.model) diff --git a/stormpy/resources/pybind11/.appveyor.yml b/stormpy/resources/pybind11/.appveyor.yml deleted file mode 100644 index c65785827..000000000 --- a/stormpy/resources/pybind11/.appveyor.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: 1.0.{build} -os: Visual Studio 2015 -test: off -platform: -- x86 -- x64 -environment: - matrix: - - CONDA: 27 - - CONDA: 35 -install: -- ps: | - if ($env:PLATFORM -eq "x64") { $env:CMAKE_ARCH = "x64" } - if ($env:PYTHON) { - if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" } - $env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH" - pip install --disable-pip-version-check --user --upgrade pip wheel - pip install pytest numpy scipy - } elseif ($env:CONDA) { - if ($env:CONDA -eq "27") { $env:CONDA = "" } - if ($env:PLATFORM -eq "x64") { $env:CONDA = "$env:CONDA-x64" } - $env:PATH = "C:\Miniconda$env:CONDA\;C:\Miniconda$env:CONDA\Scripts\;$env:PATH" - conda install -y -q pytest numpy scipy - } -- ps: | - Start-FileDownload 'http://bitbucket.org/eigen/eigen/get/3.3.0.zip' - 7z x 3.3.0.zip -y > $null - $env:CMAKE_INCLUDE_PATH = "eigen-eigen-26667be4f70b" -build_script: -- cmake -A "%CMAKE_ARCH%" -DPYBIND11_WERROR=ON -- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" -- cmake --build . --config Release --target pytest -- /v:m /logger:%MSBuildLogger% diff --git a/stormpy/resources/pybind11/.gitignore b/stormpy/resources/pybind11/.gitignore deleted file mode 100644 index 4df6229ad..000000000 --- a/stormpy/resources/pybind11/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -CMakeCache.txt -CMakeFiles -Makefile -cmake_install.cmake -.DS_Store -*.so -*.pyd -*.dll -*.sln -*.sdf -*.opensdf -*.vcxproj -*.filters -example.dir -Win32 -x64 -Release -Debug -.vs -CTestTestfile.cmake -Testing -autogen -MANIFEST -/.ninja_* -/*.ninja -/docs/.build -*.py[co] -*.egg-info -*~ -.DS_Store -/dist -/build -/cmake/ -.cache/ -sosize-*.txt diff --git a/stormpy/resources/pybind11/.gitmodules b/stormpy/resources/pybind11/.gitmodules deleted file mode 100644 index 5191885e7..000000000 --- a/stormpy/resources/pybind11/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "tools/clang"] - path = tools/clang - url = https://github.com/wjakob/clang-cindex-python3 diff --git a/stormpy/resources/pybind11/.travis.yml b/stormpy/resources/pybind11/.travis.yml deleted file mode 100644 index ff4662f7a..000000000 --- a/stormpy/resources/pybind11/.travis.yml +++ /dev/null @@ -1,112 +0,0 @@ -language: cpp -sudo: false -matrix: - include: - - os: linux - env: PYTHON=2.7 CPP=11 GCC=4.8 - addons: - apt: - sources: [ubuntu-toolchain-r-test, kubuntu-backports] - packages: [g++-4.8, cmake] - - os: linux - env: PYTHON=3.5 CPP=11 GCC=4.8 - addons: - apt: - sources: [ubuntu-toolchain-r-test, kubuntu-backports, deadsnakes] - packages: [g++-4.8, cmake, python3.5-dev] - - sudo: true - services: docker - env: PYTHON=2.7 CPP=14 GCC=6 - - sudo: true - services: docker - env: PYTHON=3.5 CPP=14 GCC=6 DEBUG=1 - - os: osx - osx_image: xcode7.3 - env: PYTHON=2.7 CPP=14 CLANG - - os: osx - osx_image: xcode7.3 - env: PYTHON=3.5 CPP=14 CLANG - # A barebones build makes sure everything still works without optional deps (numpy/scipy/eigen) - # and also tests the automatic discovery functions in CMake (Python version, C++ standard). - - os: linux - env: BAREBONES - addons: - apt: - sources: [ubuntu-toolchain-r-test, kubuntu-backports] - packages: [g++-4.8, cmake] - install: pip install pytest - # Documentation build: - - os: linux - language: docs - env: DOCS STYLE LINT - install: pip install sphinx sphinx_rtd_theme flake8 pep8-naming - script: - - make -C docs html SPHINX_OPTIONS=-W - - tools/check-style.sh - - flake8 -cache: - directories: - - $HOME/.cache/pip - - $HOME/Library/Caches/pip -before_install: -- | - # Configure build variables - if [ "$TRAVIS_OS_NAME" = "linux" ]; then - if [ -z "$GCC" ]; then export GCC=4.8; fi - export CXX=g++-$GCC CC=gcc-$GCC; - if [ "$GCC" = "6" ]; then export DOCKER=debian:testing CXX=g++ CC=gcc; fi - elif [ "$TRAVIS_OS_NAME" = "osx" ]; then - export CXX=clang++ CC=clang; - fi - if [ -n "$CPP" ]; then export CPP=-std=c++$CPP; fi - if [ "${PYTHON:0:1}" = "3" ]; then export PY=3; fi - if [ -n "$DEBUG" ]; then export CMAKE_EXTRA_ARGS="-DCMAKE_BUILD_TYPE=Debug"; fi -- | - # Initialize enviornment - if [ -n "$DOCKER" ]; then - docker pull $DOCKER - export containerid=$(docker run --detach --tty \ - --volume="$PWD":/pybind11 --workdir=/pybind11 \ - --env="CC=$CC" --env="CXX=$CXX" --env="DEBIAN_FRONTEND=$DEBIAN_FRONTEND" \ - --env=GCC_COLORS=\ \ - $DOCKER) - docker exec --tty "$containerid" sh -c 'for s in 0 15; do sleep $s; apt-get update && apt-get -qy dist-upgrade && break; done' - export SCRIPT_RUN_PREFIX="docker exec --tty $containerid" - else - if [ "$TRAVIS_OS_NAME" = "linux" ]; then - pip install --user --upgrade pip virtualenv - virtualenv -p python$PYTHON venv - elif [ "$TRAVIS_OS_NAME" = "osx" ]; then - if [ "$PY" = "3" ]; then - brew update; brew install python$PY; - else - curl -fsSL -O https://bootstrap.pypa.io/get-pip.py - sudo -H python get-pip.py - fi - pip$PY install --user --upgrade pip virtualenv - python$PY -m virtualenv venv - fi - source venv/bin/activate - fi -install: -- | - # Install dependencies - if [ -n "$DOCKER" ]; then - docker exec --tty "$containerid" sh -c "for s in 0 15; do sleep \$s; apt-get -qy --no-install-recommends install \ - python$PYTHON-dev python$PY-pytest python$PY-scipy \ - libeigen3-dev cmake make g++ && break; done" - else - pip install numpy scipy pytest - - wget -q -O eigen.tar.gz https://bitbucket.org/eigen/eigen/get/3.3.0.tar.gz - tar xzf eigen.tar.gz - export CMAKE_EXTRA_ARGS="${CMAKE_EXTRA_ARGS} -DCMAKE_INCLUDE_PATH=$PWD/eigen-eigen-26667be4f70b" - fi -script: -- $SCRIPT_RUN_PREFIX cmake ${CMAKE_EXTRA_ARGS} - -DPYBIND11_PYTHON_VERSION=$PYTHON - -DPYBIND11_CPP_STANDARD=$CPP - -DPYBIND11_WERROR=ON -- $SCRIPT_RUN_PREFIX make pytest -j 2 -after_script: -- if [ -n "$DOCKER" ]; then docker stop "$containerid"; docker rm "$containerid"; fi diff --git a/stormpy/resources/pybind11/CMakeLists.txt b/stormpy/resources/pybind11/CMakeLists.txt deleted file mode 100644 index 6aa2beaeb..000000000 --- a/stormpy/resources/pybind11/CMakeLists.txt +++ /dev/null @@ -1,184 +0,0 @@ -# CMakeLists.txt -- Build system for the pybind11 modules -# -# Copyright (c) 2015 Wenzel Jakob -# -# All rights reserved. Use of this source code is governed by a -# BSD-style license that can be found in the LICENSE file. - -cmake_minimum_required(VERSION 2.8.12) - -project(pybind11) - -# Check if pybind11 is being used directly or via add_subdirectory -set(PYBIND11_MASTER_PROJECT OFF) -if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - set(PYBIND11_MASTER_PROJECT ON) -endif() - -option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT}) -option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT}) -option(PYBIND11_WERROR "Report all warnings as errors" OFF) - -# Add a CMake parameter for choosing a desired Python version -set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules") - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools") -set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7) -find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED) - -include(CheckCXXCompilerFlag) - -if(NOT MSVC AND NOT PYBIND11_CPP_STANDARD) - check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG) - check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG) - - if (HAS_CPP14_FLAG) - set(PYBIND11_CPP_STANDARD -std=c++14) - elseif (HAS_CPP11_FLAG) - set(PYBIND11_CPP_STANDARD -std=c++11) - else() - message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!") - endif() - - set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING - "C++ standard flag, e.g. -std=c++11 or -std=c++14. Defaults to latest available." FORCE) -endif() - -# Cache variables so pybind11_add_module can be used in parent projects -set(PYBIND11_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include" CACHE INTERNAL "") -set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} CACHE INTERNAL "") -set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} CACHE INTERNAL "") -set(PYTHON_MODULE_PREFIX ${PYTHON_MODULE_PREFIX} CACHE INTERNAL "") -set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "") - -# Build a Python extension module: -# pybind11_add_module( source1 [source2 ...]) -# -function(pybind11_add_module target_name) - add_library(${target_name} MODULE ${ARGN}) - target_include_directories(${target_name} - PRIVATE ${PYBIND11_INCLUDE_DIR} - PRIVATE ${PYTHON_INCLUDE_DIRS}) - - # The prefix and extension are provided by FindPythonLibsNew.cmake - set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") - set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}") - - if(WIN32 OR CYGWIN) - # Link against the Python shared library on Windows - target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES}) - elseif(APPLE) - # It's quite common to have multiple copies of the same Python version - # installed on one's system. E.g.: one copy from the OS and another copy - # that's statically linked into an application like Blender or Maya. - # If we link our plugin library against the OS Python here and import it - # into Blender or Maya later on, this will cause segfaults when multiple - # conflicting Python instances are active at the same time (even when they - # are of the same version). - - # Windows is not affected by this issue since it handles DLL imports - # differently. The solution for Linux and Mac OS is simple: we just don't - # link against the Python library. The resulting shared library will have - # missing symbols, but that's perfectly fine -- they will be resolved at - # import time. - - target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup") - endif() - - if(NOT MSVC) - # Make sure C++11/14 are enabled - target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD}) - - # Enable link time optimization and set the default symbol - # visibility to hidden (very important to obtain small binaries) - string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE) - if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG) - # Check for Link Time Optimization support (GCC/Clang) - check_cxx_compiler_flag("-flto" HAS_LTO_FLAG) - if(HAS_LTO_FLAG AND NOT CYGWIN) - target_compile_options(${target_name} PRIVATE -flto) - endif() - - # Intel equivalent to LTO is called IPO - if(CMAKE_CXX_COMPILER_ID MATCHES "Intel") - check_cxx_compiler_flag("-ipo" HAS_IPO_FLAG) - if(HAS_IPO_FLAG) - target_compile_options(${target_name} PRIVATE -ipo) - endif() - endif() - - # Default symbol visibility - target_compile_options(${target_name} PRIVATE "-fvisibility=hidden") - - # Strip unnecessary sections of the binary on Linux/Mac OS - if(CMAKE_STRIP) - if(APPLE) - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND ${CMAKE_STRIP} -u -r $) - else() - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND ${CMAKE_STRIP} $) - endif() - endif() - endif() - elseif(MSVC) - # /MP enables multithreaded builds (relevant when there are many files), /bigobj is - # needed for bigger binding projects due to the limit to 64k addressable sections - target_compile_options(${target_name} PRIVATE /MP /bigobj) - - # Enforce link time code generation on MSVC, except in debug mode - target_compile_options(${target_name} PRIVATE $<$>:/GL>) - - # Fancy generator expressions don't work with linker flags, for reasons unknown - set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE /LTCG) - set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL /LTCG) - set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO /LTCG) - endif() -endfunction() - -# Compile with compiler warnings turned on -function(pybind11_enable_warnings target_name) - if(MSVC) - target_compile_options(${target_name} PRIVATE /W4) - else() - target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wconversion) - endif() - - if(PYBIND11_WERROR) - if(MSVC) - target_compile_options(${target_name} PRIVATE /WX) - else() - target_compile_options(${target_name} PRIVATE -Werror) - endif() - endif() -endfunction() - -set(PYBIND11_HEADERS - include/pybind11/attr.h - include/pybind11/cast.h - include/pybind11/chrono.h - include/pybind11/common.h - include/pybind11/complex.h - include/pybind11/descr.h - include/pybind11/options.h - include/pybind11/eigen.h - include/pybind11/eval.h - include/pybind11/functional.h - include/pybind11/numpy.h - include/pybind11/operators.h - include/pybind11/pybind11.h - include/pybind11/pytypes.h - include/pybind11/stl.h - include/pybind11/stl_bind.h - include/pybind11/typeid.h -) -string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" - PYBIND11_HEADERS "${PYBIND11_HEADERS}") - -if (PYBIND11_TEST) - add_subdirectory(tests) -endif() - -if (PYBIND11_INSTALL) - install(FILES ${PYBIND11_HEADERS} DESTINATION include/pybind11) -endif() diff --git a/stormpy/resources/pybind11/CONTRIBUTING.md b/stormpy/resources/pybind11/CONTRIBUTING.md deleted file mode 100644 index 2beaf8d4d..000000000 --- a/stormpy/resources/pybind11/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -Thank you for your interest in this project! Please refer to the following -sections on how to contribute code and bug reports. - -### Reporting bugs - -At the moment, this project is run in the spare time of a single person -([Wenzel Jakob](http://rgl.epfl.ch/people/wjakob)) with very limited resources -for issue tracker tickets. Thus, before submitting a question or bug report, -please take a moment of your time and ensure that your issue isn't already -discussed in the project documentation provided at -[http://pybind11.readthedocs.org/en/latest](http://pybind11.readthedocs.org/en/latest). - -Assuming that you have identified a previously unknown problem or an important -question, it's essential that you submit a self-contained and minimal piece of -code that reproduces the problem. In other words: no external dependencies, -isolate the function(s) that cause breakage, submit matched and complete C++ -and Python snippets that can be easily compiled and run on my end. - -## Pull requests -Contributions are submitted, reviewed, and accepted using Github pull requests. -Please refer to [this -article](https://help.github.com/articles/using-pull-requests) for details and -adhere to the following rules to make the process as smooth as possible: - -* Make a new branch for every feature you're working on. -* Make small and clean pull requests that are easy to review but make sure they - do add value by themselves. -* Add tests for any new functionality and run the test suite (``make pytest``) - to ensure that no existing features break. -* This project has a strong focus on providing general solutions using a - minimal amount of code, thus small pull requests are greatly preferred. - -### License - -pybind11 is provided under a BSD-style license that can be found in the -``LICENSE`` file. By using, distributing, or contributing to this project, you -agree to the terms and conditions of this license. diff --git a/stormpy/resources/pybind11/LICENSE b/stormpy/resources/pybind11/LICENSE deleted file mode 100644 index ccf4e9787..000000000 --- a/stormpy/resources/pybind11/LICENSE +++ /dev/null @@ -1,36 +0,0 @@ -Copyright (c) 2016 Wenzel Jakob , All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -You are under no obligation whatsoever to provide any bug fixes, patches, or -upgrades to the features, functionality or performance of the source code -("Enhancements") to anyone; however, if you choose to make your Enhancements -available either publicly, or directly to the author of this software, without -imposing a separate written license agreement for such Enhancements, then you -hereby grant the following license: a non-exclusive, royalty-free perpetual -license to install, use, modify, prepare derivative works, incorporate into -other computer software, distribute, and sublicense such enhancements or -derivative works thereof, in binary and source code form. diff --git a/stormpy/resources/pybind11/MANIFEST.in b/stormpy/resources/pybind11/MANIFEST.in deleted file mode 100644 index aa51d0110..000000000 --- a/stormpy/resources/pybind11/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include include/pybind11/*.h -include LICENSE README.md CONTRIBUTING.md diff --git a/stormpy/resources/pybind11/README.md b/stormpy/resources/pybind11/README.md deleted file mode 100644 index 9d4827a3e..000000000 --- a/stormpy/resources/pybind11/README.md +++ /dev/null @@ -1,123 +0,0 @@ -![pybind11 logo](https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png) - -# pybind11 — Seamless operability between C++11 and Python - -[![Documentation Status](https://readthedocs.org/projects/pybind11/badge/?version=latest)](http://pybind11.readthedocs.org/en/latest/?badge=latest) -[![Build Status](https://travis-ci.org/pybind/pybind11.svg?branch=master)](https://travis-ci.org/pybind/pybind11) -[![Build status](https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true)](https://ci.appveyor.com/project/wjakob/pybind11) - -**pybind11** is a lightweight header-only library that exposes C++ types in Python -and vice versa, mainly to create Python bindings of existing C++ code. Its -goals and syntax are similar to the excellent -[Boost.Python](http://www.boost.org/doc/libs/1_58_0/libs/python/doc/) library -by David Abrahams: to minimize boilerplate code in traditional extension -modules by inferring type information using compile-time introspection. - -The main issue with Boost.Python—and the reason for creating such a similar -project—is Boost. Boost is an enormously large and complex suite of utility -libraries that works with almost every C++ compiler in existence. This -compatibility has its cost: arcane template tricks and workarounds are -necessary to support the oldest and buggiest of compiler specimens. Now that -C++11-compatible compilers are widely available, this heavy machinery has -become an excessively large and unnecessary dependency. - -Think of this library as a tiny self-contained version of Boost.Python with -everything stripped away that isn't relevant for binding generation. Without -comments, the core header files only require ~2.5K lines of code and depend on -Python (2.7 or 3.x) and the C++ standard library. This compact implementation -was possible thanks to some of the new C++11 language features (specifically: -tuples, lambda functions and variadic templates). Since its creation, this -library has grown beyond Boost.Python in many ways, leading to dramatically -simpler binding code in many common situations. - -Tutorial and reference documentation is provided at -[http://pybind11.readthedocs.org/en/latest](http://pybind11.readthedocs.org/en/latest). -A PDF version of the manual is available -[here](https://media.readthedocs.org/pdf/pybind11/latest/pybind11.pdf). - -## Core features -pybind11 can map the following core C++ features to Python - -- Functions accepting and returning custom data structures per value, reference, or pointer -- Instance methods and static methods -- Overloaded functions -- Instance attributes and static attributes -- Arbitrary exception types -- Enumerations -- Callbacks -- Iterators and ranges -- Custom operators -- Single and multiple inheritance -- STL data structures -- Iterators and ranges -- Smart pointers with reference counting like ``std::shared_ptr`` -- Internal references with correct reference counting -- C++ classes with virtual (and pure virtual) methods can be extended in Python - -## Goodies -In addition to the core functionality, pybind11 provides some extra goodies: - -- pybind11 uses C++11 move constructors and move assignment operators whenever - possible to efficiently transfer custom data types. - -- It is possible to bind C++11 lambda functions with captured variables. The - lambda capture data is stored inside the resulting Python function object. - -- It's easy to expose the internal storage of custom data types through - Pythons' buffer protocols. This is handy e.g. for fast conversion between - C++ matrix classes like Eigen and NumPy without expensive copy operations. - -- pybind11 can automatically vectorize functions so that they are transparently - applied to all entries of one or more NumPy array arguments. - -- Python's slice-based access and assignment operations can be supported with - just a few lines of code. - -- Everything is contained in just a few header files; there is no need to link - against any additional libraries. - -- Binaries are generally smaller by a factor of at least 2 compared to - equivalent bindings generated by Boost.Python. A recent pybind11 conversion - of PyRosetta, an enormous Boost.Python binding project, - [reported](http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf) a binary - size reduction of **5.4x** and compile time reduction by **5.8x**. - -- When supported by the compiler, two new C++14 features (relaxed constexpr and - return value deduction) are used to precompute function signatures at compile - time, leading to smaller binaries. - -- With little extra effort, C++ types can be pickled and unpickled similar to - regular Python objects. - -## Supported compilers - -1. Clang/LLVM (any non-ancient version with C++11 support) -2. GCC (any non-ancient version with C++11 support) -3. Microsoft Visual Studio 2015 or newer -4. Intel C++ compiler 16 or newer (15 with a [workaround](https://github.com/pybind/pybind11/issues/276)) -5. Cygwin/GCC (tested on 2.5.1) - -## About - -This project was created by [Wenzel Jakob](https://www.mitsuba-renderer.org/~wenzel/). -Significant features and/or improvements to the code were contributed by -Jonas Adler, -Sylvain Corlay, -Trent Houliston, -Axel Huebl, -@hulucc, -Sergey Lyskov -Johan Mabille, -Tomasz Miąsko, -Dean Moldovan, -Ben Pritchard, -Jason Rhinelander, -Boris Schäling, -Pim Schellart, and -Ivan Smirnov. - -### License - -pybind11 is provided under a BSD-style license that can be found in the -``LICENSE`` file. By using, distributing, or contributing to this project, -you agree to the terms and conditions of this license. diff --git a/stormpy/resources/pybind11/docs/_static/theme_overrides.css b/stormpy/resources/pybind11/docs/_static/theme_overrides.css deleted file mode 100644 index 1071809fa..000000000 --- a/stormpy/resources/pybind11/docs/_static/theme_overrides.css +++ /dev/null @@ -1,11 +0,0 @@ -.wy-table-responsive table td, -.wy-table-responsive table th { - white-space: initial !important; -} -.rst-content table.docutils td { - vertical-align: top !important; -} -div[class^='highlight'] pre { - white-space: pre; - white-space: pre-wrap; -} diff --git a/stormpy/resources/pybind11/docs/advanced.rst b/stormpy/resources/pybind11/docs/advanced.rst deleted file mode 100644 index c257fa2d4..000000000 --- a/stormpy/resources/pybind11/docs/advanced.rst +++ /dev/null @@ -1,1613 +0,0 @@ -.. _advanced: - -Advanced topics -############### - -For brevity, the rest of this chapter assumes that the following two lines are -present: - -.. code-block:: cpp - - #include - - namespace py = pybind11; - -Exporting constants and mutable objects -======================================= - -To expose a C++ constant, use the ``attr`` function to register it in a module -as shown below. The ``int_`` class is one of many small wrapper objects defined -in ``pybind11/pytypes.h``. General objects (including integers) can also be -converted using the function ``cast``. - -.. code-block:: cpp - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - m.attr("MY_CONSTANT") = py::int_(123); - m.attr("MY_CONSTANT_2") = py::cast(new MyObject()); - } - -Operator overloading -==================== - -Suppose that we're given the following ``Vector2`` class with a vector addition -and scalar multiplication operation, all implemented using overloaded operators -in C++. - -.. code-block:: cpp - - class Vector2 { - public: - Vector2(float x, float y) : x(x), y(y) { } - - Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); } - Vector2 operator*(float value) const { return Vector2(x * value, y * value); } - Vector2& operator+=(const Vector2 &v) { x += v.x; y += v.y; return *this; } - Vector2& operator*=(float v) { x *= v; y *= v; return *this; } - - friend Vector2 operator*(float f, const Vector2 &v) { - return Vector2(f * v.x, f * v.y); - } - - std::string toString() const { - return "[" + std::to_string(x) + ", " + std::to_string(y) + "]"; - } - private: - float x, y; - }; - -The following snippet shows how the above operators can be conveniently exposed -to Python. - -.. code-block:: cpp - - #include - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_(m, "Vector2") - .def(py::init()) - .def(py::self + py::self) - .def(py::self += py::self) - .def(py::self *= float()) - .def(float() * py::self) - .def("__repr__", &Vector2::toString); - - return m.ptr(); - } - -Note that a line like - -.. code-block:: cpp - - .def(py::self * float()) - -is really just short hand notation for - -.. code-block:: cpp - - .def("__mul__", [](const Vector2 &a, float b) { - return a * b; - }) - -This can be useful for exposing additional operators that don't exist on the -C++ side, or to perform other types of customization. - -.. note:: - - To use the more convenient ``py::self`` notation, the additional - header file :file:`pybind11/operators.h` must be included. - -.. seealso:: - - The file :file:`example/example3.cpp` contains a complete example that - demonstrates how to work with overloaded operators in more detail. - -Callbacks and passing anonymous functions -========================================= - -The C++11 standard brought lambda functions and the generic polymorphic -function wrapper ``std::function<>`` to the C++ programming language, which -enable powerful new ways of working with functions. Lambda functions come in -two flavors: stateless lambda function resemble classic function pointers that -link to an anonymous piece of code, while stateful lambda functions -additionally depend on captured variables that are stored in an anonymous -*lambda closure object*. - -Here is a simple example of a C++ function that takes an arbitrary function -(stateful or stateless) with signature ``int -> int`` as an argument and runs -it with the value 10. - -.. code-block:: cpp - - int func_arg(const std::function &f) { - return f(10); - } - -The example below is more involved: it takes a function of signature ``int -> int`` -and returns another function of the same kind. The return value is a stateful -lambda function, which stores the value ``f`` in the capture object and adds 1 to -its return value upon execution. - -.. code-block:: cpp - - std::function func_ret(const std::function &f) { - return [f](int i) { - return f(i) + 1; - }; - } - -This example demonstrates using python named parameters in C++ callbacks which -requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining -methods of classes: - -.. code-block:: cpp - - py::cpp_function func_cpp() { - return py::cpp_function([](int i) { return i+1; }, - py::arg("number")); - } - -After including the extra header file :file:`pybind11/functional.h`, it is almost -trivial to generate binding code for all of these functions. - -.. code-block:: cpp - - #include - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - m.def("func_arg", &func_arg); - m.def("func_ret", &func_ret); - m.def("func_cpp", &func_cpp); - - return m.ptr(); - } - -The following interactive session shows how to call them from Python. - -.. code-block:: pycon - - $ python - >>> import example - >>> def square(i): - ... return i * i - ... - >>> example.func_arg(square) - 100L - >>> square_plus_1 = example.func_ret(square) - >>> square_plus_1(4) - 17L - >>> plus_1 = func_cpp() - >>> plus_1(number=43) - 44L - -.. note:: - - This functionality is very useful when generating bindings for callbacks in - C++ libraries (e.g. a graphical user interface library). - - The file :file:`example/example5.cpp` contains a complete example that - demonstrates how to work with callbacks and anonymous functions in more detail. - -.. warning:: - - Keep in mind that passing a function from C++ to Python (or vice versa) - will instantiate a piece of wrapper code that translates function - invocations between the two languages. Copying the same function back and - forth between Python and C++ many times in a row will cause these wrappers - to accumulate, which can decrease performance. - -Overriding virtual functions in Python -====================================== - -Suppose that a C++ class or interface has a virtual function that we'd like to -to override from within Python (we'll focus on the class ``Animal``; ``Dog`` is -given as a specific example of how one would do this with traditional C++ -code). - -.. code-block:: cpp - - class Animal { - public: - virtual ~Animal() { } - virtual std::string go(int n_times) = 0; - }; - - class Dog : public Animal { - public: - std::string go(int n_times) { - std::string result; - for (int i=0; igo(3); - } - -Normally, the binding code for these classes would look as follows: - -.. code-block:: cpp - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_ animal(m, "Animal"); - animal - .def("go", &Animal::go); - - py::class_(m, "Dog", animal) - .def(py::init<>()); - - m.def("call_go", &call_go); - - return m.ptr(); - } - -However, these bindings are impossible to extend: ``Animal`` is not -constructible, and we clearly require some kind of "trampoline" that -redirects virtual calls back to Python. - -Defining a new type of ``Animal`` from within Python is possible but requires a -helper class that is defined as follows: - -.. code-block:: cpp - - class PyAnimal : public Animal { - public: - /* Inherit the constructors */ - using Animal::Animal; - - /* Trampoline (need one for each virtual function) */ - std::string go(int n_times) { - PYBIND11_OVERLOAD_PURE( - std::string, /* Return type */ - Animal, /* Parent class */ - go, /* Name of function */ - n_times /* Argument(s) */ - ); - } - }; - -The macro :func:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual -functions, and :func:`PYBIND11_OVERLOAD` should be used for functions which have -a default implementation. - -There are also two alternate macros :func:`PYBIND11_OVERLOAD_PURE_NAME` and -:func:`PYBIND11_OVERLOAD_NAME` which take a string-valued name argument -after the *Name of the function* slot. This is useful when the C++ and Python -versions of the function have different names, e.g. ``operator()`` vs ``__call__``. - -The binding code also needs a few minor adaptations (highlighted): - -.. code-block:: cpp - :emphasize-lines: 4,6,7 - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_, PyAnimal /* <--- trampoline*/> animal(m, "Animal"); - animal - .def(py::init<>()) - .def("go", &Animal::go); - - py::class_(m, "Dog", animal) - .def(py::init<>()); - - m.def("call_go", &call_go); - - return m.ptr(); - } - -Importantly, pybind11 is made aware of the trampoline trampoline helper class -by specifying it as the *third* template argument to :class:`class_`. The -second argument with the unique pointer is simply the default holder type used -by pybind11. Following this, we are able to define a constructor as usual. - -The Python session below shows how to override ``Animal::go`` and invoke it via -a virtual method call. - -.. code-block:: pycon - - >>> from example import * - >>> d = Dog() - >>> call_go(d) - u'woof! woof! woof! ' - >>> class Cat(Animal): - ... def go(self, n_times): - ... return "meow! " * n_times - ... - >>> c = Cat() - >>> call_go(c) - u'meow! meow! meow! ' - -Please take a look at the :ref:`macro_notes` before using this feature. - -.. seealso:: - - The file :file:`example/example12.cpp` contains a complete example that - demonstrates how to override virtual functions using pybind11 in more - detail. - - -.. _macro_notes: - -General notes regarding convenience macros -========================================== - -pybind11 provides a few convenience macros such as -:func:`PYBIND11_MAKE_OPAQUE` and :func:`PYBIND11_DECLARE_HOLDER_TYPE`, and -``PYBIND11_OVERLOAD_*``. Since these are "just" macros that are evaluated -in the preprocessor (which has no concept of types), they *will* get confused -by commas in a template argument such as ``PYBIND11_OVERLOAD(MyReturnValue, myFunc)``. In this case, the preprocessor assumes that the comma indicates -the beginnning of the next parameter. Use a ``typedef`` to bind the template to -another name and use it in the macro to avoid this problem. - - -Global Interpreter Lock (GIL) -============================= - -The classes :class:`gil_scoped_release` and :class:`gil_scoped_acquire` can be -used to acquire and release the global interpreter lock in the body of a C++ -function call. In this way, long-running C++ code can be parallelized using -multiple Python threads. Taking the previous section as an example, this could -be realized as follows (important changes highlighted): - -.. code-block:: cpp - :emphasize-lines: 8,9,33,34 - - class PyAnimal : public Animal { - public: - /* Inherit the constructors */ - using Animal::Animal; - - /* Trampoline (need one for each virtual function) */ - std::string go(int n_times) { - /* Acquire GIL before calling Python code */ - py::gil_scoped_acquire acquire; - - PYBIND11_OVERLOAD_PURE( - std::string, /* Return type */ - Animal, /* Parent class */ - go, /* Name of function */ - n_times /* Argument(s) */ - ); - } - }; - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_, PyAnimal> animal(m, "Animal"); - animal - .def(py::init<>()) - .def("go", &Animal::go); - - py::class_(m, "Dog", animal) - .def(py::init<>()); - - m.def("call_go", [](Animal *animal) -> std::string { - /* Release GIL before calling into (potentially long-running) C++ code */ - py::gil_scoped_release release; - return call_go(animal); - }); - - return m.ptr(); - } - -Passing STL data structures -=========================== - -When including the additional header file :file:`pybind11/stl.h`, conversions -between ``std::vector<>``, ``std::list<>``, ``std::set<>``, and ``std::map<>`` -and the Python ``list``, ``set`` and ``dict`` data structures are automatically -enabled. The types ``std::pair<>`` and ``std::tuple<>`` are already supported -out of the box with just the core :file:`pybind11/pybind11.h` header. - -.. note:: - - Arbitrary nesting of any of these types is supported. - -.. seealso:: - - The file :file:`example/example2.cpp` contains a complete example that - demonstrates how to pass STL data types in more detail. - -Binding sequence data types, iterators, the slicing protocol, etc. -================================================================== - -Please refer to the supplemental example for details. - -.. seealso:: - - The file :file:`example/example6.cpp` contains a complete example that - shows how to bind a sequence data type, including length queries - (``__len__``), iterators (``__iter__``), the slicing protocol and other - kinds of useful operations. - -Return value policies -===================== - -Python and C++ use wildly different ways of managing the memory and lifetime of -objects managed by them. This can lead to issues when creating bindings for -functions that return a non-trivial type. Just by looking at the type -information, it is not clear whether Python should take charge of the returned -value and eventually free its resources, or if this is handled on the C++ side. -For this reason, pybind11 provides a several `return value policy` annotations -that can be passed to the :func:`module::def` and :func:`class_::def` -functions. The default policy is :enum:`return_value_policy::automatic`. - -.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}| - -+--------------------------------------------------+----------------------------------------------------------------------------+ -| Return value policy | Description | -+==================================================+============================================================================+ -| :enum:`return_value_policy::automatic` | This is the default return value policy, which falls back to the policy | -| | :enum:`return_value_policy::take_ownership` when the return value is a | -| | pointer. Otherwise, it uses :enum:`return_value::move` or | -| | :enum:`return_value::copy` for rvalue and lvalue references, respectively. | -| | See below for a description of what all of these different policies do. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::automatic_reference` | As above, but use policy :enum:`return_value_policy::reference` when the | -| | return value is a pointer. This is the default conversion policy for | -| | function arguments when calling Python functions manually from C++ code | -| | (i.e. via handle::operator()). You probably won't need to use this. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::take_ownership` | Reference an existing object (i.e. do not create a new copy) and take | -| | ownership. Python will call the destructor and delete operator when the | -| | object's reference count reaches zero. Undefined behavior ensues when the | -| | C++ side does the same. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::copy` | Create a new copy of the returned object, which will be owned by Python. | -| | This policy is comparably safe because the lifetimes of the two instances | -| | are decoupled. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::move` | Use ``std::move`` to move the return value contents into a new instance | -| | that will be owned by Python. This policy is comparably safe because the | -| | lifetimes of the two instances (move source and destination) are decoupled.| -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::reference` | Reference an existing object, but do not take ownership. The C++ side is | -| | responsible for managing the object's lifetime and deallocating it when | -| | it is no longer used. Warning: undefined behavior will ensue when the C++ | -| | side deletes an object that is still referenced and used by Python. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::reference_internal` | This policy only applies to methods and properties. It references the | -| | object without taking ownership similar to the above | -| | :enum:`return_value_policy::reference` policy. In contrast to that policy, | -| | the function or property's implicit ``this`` argument (called the *parent*)| -| | is considered to be the the owner of the return value (the *child*). | -| | pybind11 then couples the lifetime of the parent to the child via a | -| | reference relationship that ensures that the parent cannot be garbage | -| | collected while Python is still using the child. More advanced variations | -| | of this scheme are also possible using combinations of | -| | :enum:`return_value_policy::reference` and the :class:`keep_alive` call | -| | policy described next. | -+--------------------------------------------------+----------------------------------------------------------------------------+ - -The following example snippet shows a use case of the -:enum:`return_value_policy::reference_internal` policy. - -.. code-block:: cpp - - class Example { - public: - Internal &get_internal() { return internal; } - private: - Internal internal; - }; - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_(m, "Example") - .def(py::init<>()) - .def("get_internal", &Example::get_internal, "Return the internal data", - py::return_value_policy::reference_internal); - - return m.ptr(); - } - -.. warning:: - - Code with invalid call policies might access unitialized memory or free - data structures multiple times, which can lead to hard-to-debug - non-determinism and segmentation faults, hence it is worth spending the - time to understand all the different options in the table above. - - It is worth highlighting one common issue where a method (e.g. a getter) - returns a reference (or pointer) to the first attribute of a class. In this - case, the class and attribute will be located at the same address in - memory, which pybind11 will recongnize and return the parent instance - instead of creating a new Python object that represents the attribute. - Here, the :enum:`return_value_policy::reference_internal` policy should be - used rather than relying on the automatic one. - -.. note:: - - The next section on :ref:`call_policies` discusses *call policies* that can be - specified *in addition* to a return value policy from the list above. Call - policies indicate reference relationships that can involve both return values - and parameters of functions. - -.. note:: - - As an alternative to elaborate call policies and lifetime management logic, - consider using smart pointers (see the section on :ref:`smart_pointers` for - details). Smart pointers can tell whether an object is still referenced from - C++ or Python, which generally eliminates the kinds of inconsistencies that - can lead to crashes or undefined behavior. For functions returning smart - pointers, it is not necessary to specify a return value policy. - -.. _call_policies: - -Additional call policies -======================== - -In addition to the above return value policies, further `call policies` can be -specified to indicate dependencies between parameters. There is currently just -one policy named ``keep_alive``, which indicates that the -argument with index ``Patient`` should be kept alive at least until the -argument with index ``Nurse`` is freed by the garbage collector; argument -indices start at one, while zero refers to the return value. For methods, index -one refers to the implicit ``this`` pointer, while regular arguments begin at -index two. Arbitrarily many call policies can be specified. - -Consider the following example: the binding code for a list append operation -that ties the lifetime of the newly added element to the underlying container -might be declared as follows: - -.. code-block:: cpp - - py::class_(m, "List") - .def("append", &List::append, py::keep_alive<1, 2>()); - -.. note:: - - ``keep_alive`` is analogous to the ``with_custodian_and_ward`` (if Nurse, - Patient != 0) and ``with_custodian_and_ward_postcall`` (if Nurse/Patient == - 0) policies from Boost.Python. - -.. seealso:: - - The file :file:`example/example13.cpp` contains a complete example that - demonstrates using :class:`keep_alive` in more detail. - -Implicit type conversions -========================= - -Suppose that instances of two types ``A`` and ``B`` are used in a project, and -that an ``A`` can easily be converted into an instance of type ``B`` (examples of this -could be a fixed and an arbitrary precision number type). - -.. code-block:: cpp - - py::class_(m, "A") - /// ... members ... - - py::class_(m, "B") - .def(py::init()) - /// ... members ... - - m.def("func", - [](const B &) { /* .... */ } - ); - -To invoke the function ``func`` using a variable ``a`` containing an ``A`` -instance, we'd have to write ``func(B(a))`` in Python. On the other hand, C++ -will automatically apply an implicit type conversion, which makes it possible -to directly write ``func(a)``. - -In this situation (i.e. where ``B`` has a constructor that converts from -``A``), the following statement enables similar implicit conversions on the -Python side: - -.. code-block:: cpp - - py::implicitly_convertible(); - -.. note:: - - Implicit conversions from ``A`` to ``B`` only work when ``B`` is a custom - data type that is exposed to Python via pybind11. - -.. _static_properties: - -Static properties -================= - -The section on :ref:`properties` discussed the creation of instance properties -that are implemented in terms of C++ getters and setters. - -Static properties can also be created in a similar way to expose getters and -setters of static class attributes. It is important to note that the implicit -``self`` argument also exists in this case and is used to pass the Python -``type`` subclass instance. This parameter will often not be needed by the C++ -side, and the following example illustrates how to instantiate a lambda getter -function that ignores it: - -.. code-block:: cpp - - py::class_(m, "Foo") - .def_property_readonly_static("foo", [](py::object /* self */) { return Foo(); }); - -Unique pointers -=============== - -Given a class ``Example`` with Python bindings, it's possible to return -instances wrapped in C++11 unique pointers, like so - -.. code-block:: cpp - - std::unique_ptr create_example() { return std::unique_ptr(new Example()); } - -.. code-block:: cpp - - m.def("create_example", &create_example); - -In other words, there is nothing special that needs to be done. While returning -unique pointers in this way is allowed, it is *illegal* to use them as function -arguments. For instance, the following function signature cannot be processed -by pybind11. - -.. code-block:: cpp - - void do_something_with_example(std::unique_ptr ex) { ... } - -The above signature would imply that Python needs to give up ownership of an -object that is passed to this function, which is generally not possible (for -instance, the object might be referenced elsewhere). - -.. _smart_pointers: - -Smart pointers -============== - -This section explains how to pass values that are wrapped in "smart" pointer -types with internal reference counting. For the simpler C++11 unique pointers, -refer to the previous section. - -The binding generator for classes, :class:`class_`, takes an optional second -template type, which denotes a special *holder* type that is used to manage -references to the object. When wrapping a type named ``Type``, the default -value of this template parameter is ``std::unique_ptr``, which means that -the object is deallocated when Python's reference count goes to zero. - -It is possible to switch to other types of reference counting wrappers or smart -pointers, which is useful in codebases that rely on them. For instance, the -following snippet causes ``std::shared_ptr`` to be used instead. - -.. code-block:: cpp - - py::class_ /* <- holder type */> obj(m, "Example"); - -Note that any particular class can only be associated with a single holder type. - -To enable transparent conversions for functions that take shared pointers as an -argument or that return them, a macro invocation similar to the following must -be declared at the top level before any binding code: - -.. code-block:: cpp - - PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); - -.. note:: - - The first argument of :func:`PYBIND11_DECLARE_HOLDER_TYPE` should be a - placeholder name that is used as a template parameter of the second - argument. Thus, feel free to use any identifier, but use it consistently on - both sides; also, don't use the name of a type that already exists in your - codebase. - -One potential stumbling block when using holder types is that they need to be -applied consistently. Can you guess what's broken about the following binding -code? - -.. code-block:: cpp - - class Child { }; - - class Parent { - public: - Parent() : child(std::make_shared()) { } - Child *get_child() { return child.get(); } /* Hint: ** DON'T DO THIS ** */ - private: - std::shared_ptr child; - }; - - PYBIND11_PLUGIN(example) { - py::module m("example"); - - py::class_>(m, "Child"); - - py::class_>(m, "Parent") - .def(py::init<>()) - .def("get_child", &Parent::get_child); - - return m.ptr(); - } - -The following Python code will cause undefined behavior (and likely a -segmentation fault). - -.. code-block:: python - - from example import Parent - print(Parent().get_child()) - -The problem is that ``Parent::get_child()`` returns a pointer to an instance of -``Child``, but the fact that this instance is already managed by -``std::shared_ptr<...>`` is lost when passing raw pointers. In this case, -pybind11 will create a second independent ``std::shared_ptr<...>`` that also -claims ownership of the pointer. In the end, the object will be freed **twice** -since these shared pointers have no way of knowing about each other. - -There are two ways to resolve this issue: - -1. For types that are managed by a smart pointer class, never use raw pointers - in function arguments or return values. In other words: always consistently - wrap pointers into their designated holder types (such as - ``std::shared_ptr<...>``). In this case, the signature of ``get_child()`` - should be modified as follows: - -.. code-block:: cpp - - std::shared_ptr get_child() { return child; } - -2. Adjust the definition of ``Child`` by specifying - ``std::enable_shared_from_this`` (see cppreference_ for details) as a - base class. This adds a small bit of information to ``Child`` that allows - pybind11 to realize that there is already an existing - ``std::shared_ptr<...>`` and communicate with it. In this case, the - declaration of ``Child`` should look as follows: - -.. _cppreference: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this - -.. code-block:: cpp - - class Child : public std::enable_shared_from_this { }; - - -Please take a look at the :ref:`macro_notes` before using this feature. - -.. seealso:: - - The file :file:`example/example8.cpp` contains a complete example that - demonstrates how to work with custom reference-counting holder types in - more detail. - -.. _custom_constructors: - -Custom constructors -=================== - -The syntax for binding constructors was previously introduced, but it only -works when a constructor with the given parameters actually exists on the C++ -side. To extend this to more general cases, let's take a look at what actually -happens under the hood: the following statement - -.. code-block:: cpp - - py::class_(m, "Example") - .def(py::init()); - -is short hand notation for - -.. code-block:: cpp - - py::class_(m, "Example") - .def("__init__", - [](Example &instance, int arg) { - new (&instance) Example(arg); - } - ); - -In other words, :func:`init` creates an anonymous function that invokes an -in-place constructor. Memory allocation etc. is already take care of beforehand -within pybind11. - -Catching and throwing exceptions -================================ - -When C++ code invoked from Python throws an ``std::exception``, it is -automatically converted into a Python ``Exception``. pybind11 defines multiple -special exception classes that will map to different types of Python -exceptions: - -.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}| - -+--------------------------------------+------------------------------+ -| C++ exception type | Python exception type | -+======================================+==============================+ -| :class:`std::exception` | ``RuntimeError`` | -+--------------------------------------+------------------------------+ -| :class:`std::bad_alloc` | ``MemoryError`` | -+--------------------------------------+------------------------------+ -| :class:`std::domain_error` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::invalid_argument` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::length_error` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::out_of_range` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::range_error` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`pybind11::stop_iteration` | ``StopIteration`` (used to | -| | implement custom iterators) | -+--------------------------------------+------------------------------+ -| :class:`pybind11::index_error` | ``IndexError`` (used to | -| | indicate out of bounds | -| | accesses in ``__getitem__``, | -| | ``__setitem__``, etc.) | -+--------------------------------------+------------------------------+ -| :class:`pybind11::value_error` | ``ValueError`` (used to | -| | indicate wrong value passed | -| | in ``container.remove(...)`` | -+--------------------------------------+------------------------------+ -| :class:`pybind11::error_already_set` | Indicates that the Python | -| | exception flag has already | -| | been initialized | -+--------------------------------------+------------------------------+ - -When a Python function invoked from C++ throws an exception, it is converted -into a C++ exception of type :class:`error_already_set` whose string payload -contains a textual summary. - -There is also a special exception :class:`cast_error` that is thrown by -:func:`handle::call` when the input arguments cannot be converted to Python -objects. - -.. _opaque: - -Treating STL data structures as opaque objects -============================================== - -pybind11 heavily relies on a template matching mechanism to convert parameters -and return values that are constructed from STL data types such as vectors, -linked lists, hash tables, etc. This even works in a recursive manner, for -instance to deal with lists of hash maps of pairs of elementary and custom -types, etc. - -However, a fundamental limitation of this approach is that internal conversions -between Python and C++ types involve a copy operation that prevents -pass-by-reference semantics. What does this mean? - -Suppose we bind the following function - -.. code-block:: cpp - - void append_1(std::vector &v) { - v.push_back(1); - } - -and call it from Python, the following happens: - -.. code-block:: pycon - - >>> v = [5, 6] - >>> append_1(v) - >>> print(v) - [5, 6] - -As you can see, when passing STL data structures by reference, modifications -are not propagated back the Python side. A similar situation arises when -exposing STL data structures using the ``def_readwrite`` or ``def_readonly`` -functions: - -.. code-block:: cpp - - /* ... definition ... */ - - class MyClass { - std::vector contents; - }; - - /* ... binding code ... */ - - py::class_(m, "MyClass") - .def(py::init<>) - .def_readwrite("contents", &MyClass::contents); - -In this case, properties can be read and written in their entirety. However, an -``append`` operaton involving such a list type has no effect: - -.. code-block:: pycon - - >>> m = MyClass() - >>> m.contents = [5, 6] - >>> print(m.contents) - [5, 6] - >>> m.contents.append(7) - >>> print(m.contents) - [5, 6] - -To deal with both of the above situations, pybind11 provides a macro named -``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based conversion -machinery of types, thus rendering them *opaque*. The contents of opaque -objects are never inspected or extracted, hence they can be passed by -reference. For instance, to turn ``std::vector`` into an opaque type, add -the declaration - -.. code-block:: cpp - - PYBIND11_MAKE_OPAQUE(std::vector); - -before any binding code (e.g. invocations to ``class_::def()``, etc.). This -macro must be specified at the top level, since instantiates a partial template -overload. If your binding code consists of multiple compilation units, it must -be present in every file preceding any usage of ``std::vector``. Opaque -types must also have a corresponding ``class_`` declaration to associate them -with a name in Python, and to define a set of available operations: - -.. code-block:: cpp - - py::class_>(m, "IntVector") - .def(py::init<>()) - .def("clear", &std::vector::clear) - .def("pop_back", &std::vector::pop_back) - .def("__len__", [](const std::vector &v) { return v.size(); }) - .def("__iter__", [](std::vector &v) { - return py::make_iterator(v.begin(), v.end()); - }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */ - // .... - -Please take a look at the :ref:`macro_notes` before using this feature. - -.. seealso:: - - The file :file:`example/example14.cpp` contains a complete example that - demonstrates how to create and expose opaque types using pybind11 in more - detail. - -.. _eigen: - -Transparent conversion of dense and sparse Eigen data types -=========================================================== - -Eigen [#f1]_ is C++ header-based library for dense and sparse linear algebra. Due to -its popularity and widespread adoption, pybind11 provides transparent -conversion support between Eigen and Scientific Python linear algebra data types. - -Specifically, when including the optional header file :file:`pybind11/eigen.h`, -pybind11 will automatically and transparently convert - -1. Static and dynamic Eigen dense vectors and matrices to instances of - ``numpy.ndarray`` (and vice versa). - -1. Eigen sparse vectors and matrices to instances of - ``scipy.sparse.csr_matrix``/``scipy.sparse.csc_matrix`` (and vice versa). - -This makes it possible to bind most kinds of functions that rely on these types. -One major caveat are functions that take Eigen matrices *by reference* and modify -them somehow, in which case the information won't be propagated to the caller. - -.. code-block:: cpp - - /* The Python bindings of this function won't replicate - the intended effect of modifying the function argument */ - void scale_by_2(Eigen::Vector3f &v) { - v *= 2; - } - -To see why this is, refer to the section on :ref:`opaque` (although that -section specifically covers STL data types, the underlying issue is the same). -The next two sections discuss an efficient alternative for exposing the -underlying native Eigen types as opaque objects in a way that still integrates -with NumPy and SciPy. - -.. [#f1] http://eigen.tuxfamily.org - -.. seealso:: - - The file :file:`example/eigen.cpp` contains a complete example that - shows how to pass Eigen sparse and dense data types in more detail. - -Buffer protocol -=============== - -Python supports an extremely general and convenient approach for exchanging -data between plugin libraries. Types can expose a buffer view [#f2]_, which -provides fast direct access to the raw internal data representation. Suppose we -want to bind the following simplistic Matrix class: - -.. code-block:: cpp - - class Matrix { - public: - Matrix(size_t rows, size_t cols) : m_rows(rows), m_cols(cols) { - m_data = new float[rows*cols]; - } - float *data() { return m_data; } - size_t rows() const { return m_rows; } - size_t cols() const { return m_cols; } - private: - size_t m_rows, m_cols; - float *m_data; - }; - -The following binding code exposes the ``Matrix`` contents as a buffer object, -making it possible to cast Matrices into NumPy arrays. It is even possible to -completely avoid copy operations with Python expressions like -``np.array(matrix_instance, copy = False)``. - -.. code-block:: cpp - - py::class_(m, "Matrix") - .def_buffer([](Matrix &m) -> py::buffer_info { - return py::buffer_info( - m.data(), /* Pointer to buffer */ - sizeof(float), /* Size of one scalar */ - py::format_descriptor::value, /* Python struct-style format descriptor */ - 2, /* Number of dimensions */ - { m.rows(), m.cols() }, /* Buffer dimensions */ - { sizeof(float) * m.rows(), /* Strides (in bytes) for each index */ - sizeof(float) } - ); - }); - -The snippet above binds a lambda function, which can create ``py::buffer_info`` -description records on demand describing a given matrix. The contents of -``py::buffer_info`` mirror the Python buffer protocol specification. - -.. code-block:: cpp - - struct buffer_info { - void *ptr; - size_t itemsize; - std::string format; - int ndim; - std::vector shape; - std::vector strides; - }; - -To create a C++ function that can take a Python buffer object as an argument, -simply use the type ``py::buffer`` as one of its arguments. Buffers can exist -in a great variety of configurations, hence some safety checks are usually -necessary in the function body. Below, you can see an basic example on how to -define a custom constructor for the Eigen double precision matrix -(``Eigen::MatrixXd``) type, which supports initialization from compatible -buffer objects (e.g. a NumPy matrix). - -.. code-block:: cpp - - /* Bind MatrixXd (or some other Eigen type) to Python */ - typedef Eigen::MatrixXd Matrix; - - typedef Matrix::Scalar Scalar; - constexpr bool rowMajor = Matrix::Flags & Eigen::RowMajorBit; - - py::class_(m, "Matrix") - .def("__init__", [](Matrix &m, py::buffer b) { - typedef Eigen::Stride Strides; - - /* Request a buffer descriptor from Python */ - py::buffer_info info = b.request(); - - /* Some sanity checks ... */ - if (info.format != py::format_descriptor::value) - throw std::runtime_error("Incompatible format: expected a double array!"); - - if (info.ndim != 2) - throw std::runtime_error("Incompatible buffer dimension!"); - - auto strides = Strides( - info.strides[rowMajor ? 0 : 1] / sizeof(Scalar), - info.strides[rowMajor ? 1 : 0] / sizeof(Scalar)); - - auto map = Eigen::Map( - static_cat(info.ptr), info.shape[0], info.shape[1], strides); - - new (&m) Matrix(map); - }); - -For reference, the ``def_buffer()`` call for this Eigen data type should look -as follows: - -.. code-block:: cpp - - .def_buffer([](Matrix &m) -> py::buffer_info { - return py::buffer_info( - m.data(), /* Pointer to buffer */ - sizeof(Scalar), /* Size of one scalar */ - /* Python struct-style format descriptor */ - py::format_descriptor::value, - /* Number of dimensions */ - 2, - /* Buffer dimensions */ - { (size_t) m.rows(), - (size_t) m.cols() }, - /* Strides (in bytes) for each index */ - { sizeof(Scalar) * (rowMajor ? m.cols() : 1), - sizeof(Scalar) * (rowMajor ? 1 : m.rows()) } - ); - }) - -For a much easier approach of binding Eigen types (although with some -limitations), refer to the section on :ref:`eigen`. - -.. seealso:: - - The file :file:`example/example7.cpp` contains a complete example that - demonstrates using the buffer protocol with pybind11 in more detail. - -.. [#f2] http://docs.python.org/3/c-api/buffer.html - -NumPy support -============= - -By exchanging ``py::buffer`` with ``py::array`` in the above snippet, we can -restrict the function so that it only accepts NumPy arrays (rather than any -type of Python object satisfying the buffer protocol). - -In many situations, we want to define a function which only accepts a NumPy -array of a certain data type. This is possible via the ``py::array_t`` -template. For instance, the following function requires the argument to be a -NumPy array containing double precision values. - -.. code-block:: cpp - - void f(py::array_t array); - -When it is invoked with a different type (e.g. an integer or a list of -integers), the binding code will attempt to cast the input into a NumPy array -of the requested type. Note that this feature requires the -:file:``pybind11/numpy.h`` header to be included. - -Data in NumPy arrays is not guaranteed to packed in a dense manner; -furthermore, entries can be separated by arbitrary column and row strides. -Sometimes, it can be useful to require a function to only accept dense arrays -using either the C (row-major) or Fortran (column-major) ordering. This can be -accomplished via a second template argument with values ``py::array::c_style`` -or ``py::array::f_style``. - -.. code-block:: cpp - - void f(py::array_t array); - -The ``py::array::forcecast`` argument is the default value of the second -template paramenter, and it ensures that non-conforming arguments are converted -into an array satisfying the specified requirements instead of trying the next -function overload. - -Vectorizing functions -===================== - -Suppose we want to bind a function with the following signature to Python so -that it can process arbitrary NumPy array arguments (vectors, matrices, general -N-D arrays) in addition to its normal arguments: - -.. code-block:: cpp - - double my_func(int x, float y, double z); - -After including the ``pybind11/numpy.h`` header, this is extremely simple: - -.. code-block:: cpp - - m.def("vectorized_func", py::vectorize(my_func)); - -Invoking the function like below causes 4 calls to be made to ``my_func`` with -each of the array elements. The significant advantage of this compared to -solutions like ``numpy.vectorize()`` is that the loop over the elements runs -entirely on the C++ side and can be crunched down into a tight, optimized loop -by the compiler. The result is returned as a NumPy array of type -``numpy.dtype.float64``. - -.. code-block:: pycon - - >>> x = np.array([[1, 3],[5, 7]]) - >>> y = np.array([[2, 4],[6, 8]]) - >>> z = 3 - >>> result = vectorized_func(x, y, z) - -The scalar argument ``z`` is transparently replicated 4 times. The input -arrays ``x`` and ``y`` are automatically converted into the right types (they -are of type ``numpy.dtype.int64`` but need to be ``numpy.dtype.int32`` and -``numpy.dtype.float32``, respectively) - -Sometimes we might want to explicitly exclude an argument from the vectorization -because it makes little sense to wrap it in a NumPy array. For instance, -suppose the function signature was - -.. code-block:: cpp - - double my_func(int x, float y, my_custom_type *z); - -This can be done with a stateful Lambda closure: - -.. code-block:: cpp - - // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the vectorization) - m.def("vectorized_func", - [](py::array_t x, py::array_t y, my_custom_type *z) { - auto stateful_closure = [z](int x, float y) { return my_func(x, y, z); }; - return py::vectorize(stateful_closure)(x, y); - } - ); - -In cases where the computation is too complicated to be reduced to -``vectorize``, it will be necessary to create and access the buffer contents -manually. The following snippet contains a complete example that shows how this -works (the code is somewhat contrived, since it could have been done more -simply using ``vectorize``). - -.. code-block:: cpp - - #include - #include - - namespace py = pybind11; - - py::array_t add_arrays(py::array_t input1, py::array_t input2) { - auto buf1 = input1.request(), buf2 = input2.request(); - - if (buf1.ndim != 1 || buf2.ndim != 1) - throw std::runtime_error("Number of dimensions must be one"); - - if (buf1.shape[0] != buf2.shape[0]) - throw std::runtime_error("Input shapes must match"); - - auto result = py::array(py::buffer_info( - nullptr, /* Pointer to data (nullptr -> ask NumPy to allocate!) */ - sizeof(double), /* Size of one item */ - py::format_descriptor::value(), /* Buffer format */ - buf1.ndim, /* How many dimensions? */ - { buf1.shape[0] }, /* Number of elements for each dimension */ - { sizeof(double) } /* Strides for each dimension */ - )); - - auto buf3 = result.request(); - - double *ptr1 = (double *) buf1.ptr, - *ptr2 = (double *) buf2.ptr, - *ptr3 = (double *) buf3.ptr; - - for (size_t idx = 0; idx < buf1.shape[0]; idx++) - ptr3[idx] = ptr1[idx] + ptr2[idx]; - - return result; - } - - PYBIND11_PLUGIN(test) { - py::module m("test"); - m.def("add_arrays", &add_arrays, "Add two NumPy arrays"); - return m.ptr(); - } - -.. seealso:: - - The file :file:`example/example10.cpp` contains a complete example that - demonstrates using :func:`vectorize` in more detail. - -Functions taking Python objects as arguments -============================================ - -pybind11 exposes all major Python types using thin C++ wrapper classes. These -wrapper classes can also be used as parameters of functions in bindings, which -makes it possible to directly work with native Python types on the C++ side. -For instance, the following statement iterates over a Python ``dict``: - -.. code-block:: cpp - - void print_dict(py::dict dict) { - /* Easily interact with Python types */ - for (auto item : dict) - std::cout << "key=" << item.first << ", " - << "value=" << item.second << std::endl; - } - -Available types include :class:`handle`, :class:`object`, :class:`bool_`, -:class:`int_`, :class:`float_`, :class:`str`, :class:`bytes`, :class:`tuple`, -:class:`list`, :class:`dict`, :class:`slice`, :class:`none`, :class:`capsule`, -:class:`iterable`, :class:`iterator`, :class:`function`, :class:`buffer`, -:class:`array`, and :class:`array_t`. - -In this kind of mixed code, it is often necessary to convert arbitrary C++ -types to Python, which can be done using :func:`cast`: - -.. code-block:: cpp - - MyClass *cls = ..; - py::object obj = py::cast(cls); - -The reverse direction uses the following syntax: - -.. code-block:: cpp - - py::object obj = ...; - MyClass *cls = obj.cast(); - -When conversion fails, both directions throw the exception :class:`cast_error`. -It is also possible to call python functions via ``operator()``. - -.. code-block:: cpp - - py::function f = <...>; - py::object result_py = f(1234, "hello", some_instance); - MyClass &result = result_py.cast(); - -The special ``f(*args)`` and ``f(*args, **kwargs)`` syntax is also supported to -supply arbitrary argument and keyword lists, although these cannot be mixed -with other parameters. - -.. code-block:: cpp - - py::function f = <...>; - py::tuple args = py::make_tuple(1234); - py::dict kwargs; - kwargs["y"] = py::cast(5678); - py::object result = f(*args, **kwargs); - -.. seealso:: - - The file :file:`example/example2.cpp` contains a complete example that - demonstrates passing native Python types in more detail. The file - :file:`example/example11.cpp` discusses usage of ``args`` and ``kwargs``. - -Default arguments revisited -=========================== - -The section on :ref:`default_args` previously discussed basic usage of default -arguments using pybind11. One noteworthy aspect of their implementation is that -default arguments are converted to Python objects right at declaration time. -Consider the following example: - -.. code-block:: cpp - - py::class_("MyClass") - .def("myFunction", py::arg("arg") = SomeType(123)); - -In this case, pybind11 must already be set up to deal with values of the type -``SomeType`` (via a prior instantiation of ``py::class_``), or an -exception will be thrown. - -Another aspect worth highlighting is that the "preview" of the default argument -in the function signature is generated using the object's ``__repr__`` method. -If not available, the signature may not be very helpful, e.g.: - -.. code-block:: pycon - - FUNCTIONS - ... - | myFunction(...) - | Signature : (MyClass, arg : SomeType = ) -> NoneType - ... - -The first way of addressing this is by defining ``SomeType.__repr__``. -Alternatively, it is possible to specify the human-readable preview of the -default argument manually using the ``arg_t`` notation: - -.. code-block:: cpp - - py::class_("MyClass") - .def("myFunction", py::arg_t("arg", SomeType(123), "SomeType(123)")); - -Sometimes it may be necessary to pass a null pointer value as a default -argument. In this case, remember to cast it to the underlying type in question, -like so: - -.. code-block:: cpp - - py::class_("MyClass") - .def("myFunction", py::arg("arg") = (SomeType *) nullptr); - -Binding functions that accept arbitrary numbers of arguments and keywords arguments -=================================================================================== - -Python provides a useful mechanism to define functions that accept arbitrary -numbers of arguments and keyword arguments: - -.. code-block:: cpp - - def generic(*args, **kwargs): - # .. do something with args and kwargs - -Such functions can also be created using pybind11: - -.. code-block:: cpp - - void generic(py::args args, py::kwargs kwargs) { - /// .. do something with args - if (kwargs) - /// .. do something with kwargs - } - - /// Binding code - m.def("generic", &generic); - -(See ``example/example11.cpp``). The class ``py::args`` derives from -``py::list`` and ``py::kwargs`` derives from ``py::dict`` Note that the -``kwargs`` argument is invalid if no keyword arguments were actually provided. -Please refer to the other examples for details on how to iterate over these, -and on how to cast their entries into C++ objects. - -Partitioning code over multiple extension modules -================================================= - -It's straightforward to split binding code over multiple extension modules, -while referencing types that are declared elsewhere. Everything "just" works -without any special precautions. One exception to this rule occurs when -extending a type declared in another extension module. Recall the basic example -from Section :ref:`inheritance`. - -.. code-block:: cpp - - py::class_ pet(m, "Pet"); - pet.def(py::init()) - .def_readwrite("name", &Pet::name); - - py::class_(m, "Dog", pet /* <- specify parent */) - .def(py::init()) - .def("bark", &Dog::bark); - -Suppose now that ``Pet`` bindings are defined in a module named ``basic``, -whereas the ``Dog`` bindings are defined somewhere else. The challenge is of -course that the variable ``pet`` is not available anymore though it is needed -to indicate the inheritance relationship to the constructor of ``class_``. -However, it can be acquired as follows: - -.. code-block:: cpp - - py::object pet = (py::object) py::module::import("basic").attr("Pet"); - - py::class_(m, "Dog", pet) - .def(py::init()) - .def("bark", &Dog::bark); - -Alternatively, we can rely on the ``base`` tag, which performs an automated -lookup of the corresponding Python type. However, this also requires invoking -the ``import`` function once to ensure that the pybind11 binding code of the -module ``basic`` has been executed. - -.. code-block:: cpp - - py::module::import("basic"); - - py::class_(m, "Dog", py::base()) - .def(py::init()) - .def("bark", &Dog::bark); - -Naturally, both methods will fail when there are cyclic dependencies. - -Note that compiling code which has its default symbol visibility set to -*hidden* (e.g. via the command line flag ``-fvisibility=hidden`` on GCC/Clang) can interfere with the -ability to access types defined in another extension module. Workarounds -include changing the global symbol visibility (not recommended, because it will -lead unnecessarily large binaries) or manually exporting types that are -accessed by multiple extension modules: - -.. code-block:: cpp - - #ifdef _WIN32 - # define EXPORT_TYPE __declspec(dllexport) - #else - # define EXPORT_TYPE __attribute__ ((visibility("default"))) - #endif - - class EXPORT_TYPE Dog : public Animal { - ... - }; - - -Pickling support -================ - -Python's ``pickle`` module provides a powerful facility to serialize and -de-serialize a Python object graph into a binary data stream. To pickle and -unpickle C++ classes using pybind11, two additional functions must be provided. -Suppose the class in question has the following signature: - -.. code-block:: cpp - - class Pickleable { - public: - Pickleable(const std::string &value) : m_value(value) { } - const std::string &value() const { return m_value; } - - void setExtra(int extra) { m_extra = extra; } - int extra() const { return m_extra; } - private: - std::string m_value; - int m_extra = 0; - }; - -The binding code including the requisite ``__setstate__`` and ``__getstate__`` methods [#f3]_ -looks as follows: - -.. code-block:: cpp - - py::class_(m, "Pickleable") - .def(py::init()) - .def("value", &Pickleable::value) - .def("extra", &Pickleable::extra) - .def("setExtra", &Pickleable::setExtra) - .def("__getstate__", [](const Pickleable &p) { - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(p.value(), p.extra()); - }) - .def("__setstate__", [](Pickleable &p, py::tuple t) { - if (t.size() != 2) - throw std::runtime_error("Invalid state!"); - - /* Invoke the in-place constructor. Note that this is needed even - when the object just has a trivial default constructor */ - new (&p) Pickleable(t[0].cast()); - - /* Assign any additional state */ - p.setExtra(t[1].cast()); - }); - -An instance can now be pickled as follows: - -.. code-block:: python - - try: - import cPickle as pickle # Use cPickle on Python 2.7 - except ImportError: - import pickle - - p = Pickleable("test_value") - p.setExtra(15) - data = pickle.dumps(p, 2) - -Note that only the cPickle module is supported on Python 2.7. The second -argument to ``dumps`` is also crucial: it selects the pickle protocol version -2, since the older version 1 is not supported. Newer versions are also fine—for -instance, specify ``-1`` to always use the latest available version. Beware: -failure to follow these instructions will cause important pybind11 memory -allocation routines to be skipped during unpickling, which will likely lead to -memory corruption and/or segmentation faults. - -.. seealso:: - - The file :file:`example/example15.cpp` contains a complete example that - demonstrates how to pickle and unpickle types using pybind11 in more detail. - -.. [#f3] http://docs.python.org/3/library/pickle.html#pickling-class-instances - -Generating documentation using Sphinx -===================================== - -Sphinx [#f4]_ has the ability to inspect the signatures and documentation -strings in pybind11-based extension modules to automatically generate beautiful -documentation in a variety formats. The python_example repository [#f5]_ contains a -simple example repository which uses this approach. - -There are two potential gotchas when using this approach: first, make sure that -the resulting strings do not contain any :kbd:`TAB` characters, which break the -docstring parsing routines. You may want to use C++11 raw string literals, -which are convenient for multi-line comments. Conveniently, any excess -indentation will be automatically be removed by Sphinx. However, for this to -work, it is important that all lines are indented consistently, i.e.: - -.. code-block:: cpp - - // ok - m.def("foo", &foo, R"mydelimiter( - The foo function - - Parameters - ---------- - )mydelimiter"); - - // *not ok* - m.def("foo", &foo, R"mydelimiter(The foo function - - Parameters - ---------- - )mydelimiter"); - -.. [#f4] http://www.sphinx-doc.org -.. [#f5] http://github.com/pybind/python_example diff --git a/stormpy/resources/pybind11/docs/advanced/cast/chrono.rst b/stormpy/resources/pybind11/docs/advanced/cast/chrono.rst deleted file mode 100755 index 6d4a5ee55..000000000 --- a/stormpy/resources/pybind11/docs/advanced/cast/chrono.rst +++ /dev/null @@ -1,81 +0,0 @@ -Chrono -====== - -When including the additional header file :file:`pybind11/chrono.h` conversions -from C++11 chrono datatypes to python datetime objects are automatically enabled. -This header also enables conversions of python floats (often from sources such -as `time.monotonic()`, `time.perf_counter()` and `time.process_time()`) into -durations. - -An overview of clocks in C++11 ------------------------------- - -A point of confusion when using these conversions is the differences between -clocks provided in C++11. There are three clock types defined by the C++11 -standard and users can define their own if needed. Each of these clocks have -different properties and when converting to and from python will give different -results. - -The first clock defined by the standard is ``std::chrono::system_clock``. This -clock measures the current date and time. However, this clock changes with to -updates to the operating system time. For example, if your time is synchronised -with a time server this clock will change. This makes this clock a poor choice -for timing purposes but good for measuring the wall time. - -The second clock defined in the standard is ``std::chrono::steady_clock``. -This clock ticks at a steady rate and is never adjusted. This makes it excellent -for timing purposes, however the value in this clock does not correspond to the -current date and time. Often this clock will be the amount of time your system -has been on, although it does not have to be. This clock will never be the same -clock as the system clock as the system clock can change but steady clocks -cannot. - -The third clock defined in the standard is ``std::chrono::high_resolution_clock``. -This clock is the clock that has the highest resolution out of the clocks in the -system. It is normally a typedef to either the system clock or the steady clock -but can be its own independent clock. This is important as when using these -conversions as the types you get in python for this clock might be different -depending on the system. -If it is a typedef of the system clock, python will get datetime objects, but if -it is a different clock they will be timedelta objects. - -Provided conversions --------------------- - -.. rubric:: C++ to Python - -- ``std::chrono::system_clock::time_point`` → ``datetime.datetime`` - System clock times are converted to python datetime instances. They are - in the local timezone, but do not have any timezone information attached - to them (they are naive datetime objects). - -- ``std::chrono::duration`` → ``datetime.timedelta`` - Durations are converted to timedeltas, any precision in the duration - greater than microseconds is lost by rounding towards zero. - -- ``std::chrono::[other_clocks]::time_point`` → ``datetime.timedelta`` - Any clock time that is not the system clock is converted to a time delta. - This timedelta measures the time from the clocks epoch to now. - -.. rubric:: Python to C++ - -- ``datetime.datetime`` → ``std::chrono::system_clock::time_point`` - Date/time objects are converted into system clock timepoints. Any - timezone information is ignored and the type is treated as a naive - object. - -- ``datetime.timedelta`` → ``std::chrono::duration`` - Time delta are converted into durations with microsecond precision. - -- ``datetime.timedelta`` → ``std::chrono::[other_clocks]::time_point`` - Time deltas that are converted into clock timepoints are treated as - the amount of time from the start of the clocks epoch. - -- ``float`` → ``std::chrono::duration`` - Floats that are passed to C++ as durations be interpreted as a number of - seconds. These will be converted to the duration using ``duration_cast`` - from the float. - -- ``float`` → ``std::chrono::[other_clocks]::time_point`` - Floats that are passed to C++ as time points will be interpreted as the - number of seconds from the start of the clocks epoch. diff --git a/stormpy/resources/pybind11/docs/advanced/cast/custom.rst b/stormpy/resources/pybind11/docs/advanced/cast/custom.rst deleted file mode 100755 index c854e7fcd..000000000 --- a/stormpy/resources/pybind11/docs/advanced/cast/custom.rst +++ /dev/null @@ -1,85 +0,0 @@ -Custom type casters -=================== - -In very rare cases, applications may require custom type casters that cannot be -expressed using the abstractions provided by pybind11, thus requiring raw -Python C API calls. This is fairly advanced usage and should only be pursued by -experts who are familiar with the intricacies of Python reference counting. - -The following snippets demonstrate how this works for a very simple ``inty`` -type that that should be convertible from Python types that provide a -``__int__(self)`` method. - -.. code-block:: cpp - - struct inty { long long_value; }; - - void print(inty s) { - std::cout << s.long_value << std::endl; - } - -The following Python snippet demonstrates the intended usage from the Python side: - -.. code-block:: python - - class A: - def __int__(self): - return 123 - - from example import print - print(A()) - -To register the necessary conversion routines, it is necessary to add -a partial overload to the ``pybind11::detail::type_caster`` template. -Although this is an implementation detail, adding partial overloads to this -type is explicitly allowed. - -.. code-block:: cpp - - namespace pybind11 { namespace detail { - template <> struct type_caster { - public: - /** - * This macro establishes the name 'inty' in - * function signatures and declares a local variable - * 'value' of type inty - */ - PYBIND11_TYPE_CASTER(inty, _("inty")); - - /** - * Conversion part 1 (Python->C++): convert a PyObject into a inty - * instance or return false upon failure. The second argument - * indicates whether implicit conversions should be applied. - */ - bool load(handle src, bool) { - /* Extract PyObject from handle */ - PyObject *source = src.ptr(); - /* Try converting into a Python integer value */ - PyObject *tmp = PyNumber_Long(source); - if (!tmp) - return false; - /* Now try to convert into a C++ int */ - value.long_value = PyLong_AsLong(tmp); - Py_DECREF(tmp); - /* Ensure return code was OK (to avoid out-of-range errors etc) */ - return !(value.long_value == -1 && !PyErr_Occurred()); - } - - /** - * Conversion part 2 (C++ -> Python): convert an inty instance into - * a Python object. The second and third arguments are used to - * indicate the return value policy and parent object (for - * ``return_value_policy::reference_internal``) and are generally - * ignored by implicit casters. - */ - static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) { - return PyLong_FromLong(src.long_value); - } - }; - }} // namespace pybind11::detail - -.. warning:: - - When using custom type casters, it's important to declare them consistently - in every compilation unit of the Python extension module. Otherwise, - undefined behavior can ensue. diff --git a/stormpy/resources/pybind11/docs/advanced/cast/eigen.rst b/stormpy/resources/pybind11/docs/advanced/cast/eigen.rst deleted file mode 100755 index b83ca9af9..000000000 --- a/stormpy/resources/pybind11/docs/advanced/cast/eigen.rst +++ /dev/null @@ -1,50 +0,0 @@ -Eigen -===== - -`Eigen `_ is C++ header-based library for dense and -sparse linear algebra. Due to its popularity and widespread adoption, pybind11 -provides transparent conversion support between Eigen and Scientific Python linear -algebra data types. - -Specifically, when including the optional header file :file:`pybind11/eigen.h`, -pybind11 will automatically and transparently convert - -1. Static and dynamic Eigen dense vectors and matrices to instances of - ``numpy.ndarray`` (and vice versa). - -2. Returned matrix expressions such as blocks (including columns or rows) and - diagonals will be converted to ``numpy.ndarray`` of the expression - values. - -3. Returned matrix-like objects such as Eigen::DiagonalMatrix or - Eigen::SelfAdjointView will be converted to ``numpy.ndarray`` containing the - expressed value. - -4. Eigen sparse vectors and matrices to instances of - ``scipy.sparse.csr_matrix``/``scipy.sparse.csc_matrix`` (and vice versa). - -This makes it possible to bind most kinds of functions that rely on these types. -One major caveat are functions that take Eigen matrices *by reference* and modify -them somehow, in which case the information won't be propagated to the caller. - -.. code-block:: cpp - - /* The Python bindings of these functions won't replicate - the intended effect of modifying the function arguments */ - void scale_by_2(Eigen::Vector3f &v) { - v *= 2; - } - void scale_by_2(Eigen::Ref &v) { - v *= 2; - } - -To see why this is, refer to the section on :ref:`opaque` (although that -section specifically covers STL data types, the underlying issue is the same). -The :ref:`numpy` sections discuss an efficient alternative for exposing the -underlying native Eigen types as opaque objects in a way that still integrates -with NumPy and SciPy. - -.. seealso:: - - The file :file:`tests/test_eigen.cpp` contains a complete example that - shows how to pass Eigen sparse and dense data types in more detail. diff --git a/stormpy/resources/pybind11/docs/advanced/cast/functional.rst b/stormpy/resources/pybind11/docs/advanced/cast/functional.rst deleted file mode 100755 index 5d0a01d13..000000000 --- a/stormpy/resources/pybind11/docs/advanced/cast/functional.rst +++ /dev/null @@ -1,113 +0,0 @@ -Functional -########## - -The following features must be enabled by including :file:`pybind11/functional.h`. - - -Callbacks and passing anonymous functions -========================================= - -The C++11 standard brought lambda functions and the generic polymorphic -function wrapper ``std::function<>`` to the C++ programming language, which -enable powerful new ways of working with functions. Lambda functions come in -two flavors: stateless lambda function resemble classic function pointers that -link to an anonymous piece of code, while stateful lambda functions -additionally depend on captured variables that are stored in an anonymous -*lambda closure object*. - -Here is a simple example of a C++ function that takes an arbitrary function -(stateful or stateless) with signature ``int -> int`` as an argument and runs -it with the value 10. - -.. code-block:: cpp - - int func_arg(const std::function &f) { - return f(10); - } - -The example below is more involved: it takes a function of signature ``int -> int`` -and returns another function of the same kind. The return value is a stateful -lambda function, which stores the value ``f`` in the capture object and adds 1 to -its return value upon execution. - -.. code-block:: cpp - - std::function func_ret(const std::function &f) { - return [f](int i) { - return f(i) + 1; - }; - } - -This example demonstrates using python named parameters in C++ callbacks which -requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining -methods of classes: - -.. code-block:: cpp - - py::cpp_function func_cpp() { - return py::cpp_function([](int i) { return i+1; }, - py::arg("number")); - } - -After including the extra header file :file:`pybind11/functional.h`, it is almost -trivial to generate binding code for all of these functions. - -.. code-block:: cpp - - #include - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - m.def("func_arg", &func_arg); - m.def("func_ret", &func_ret); - m.def("func_cpp", &func_cpp); - - return m.ptr(); - } - -The following interactive session shows how to call them from Python. - -.. code-block:: pycon - - $ python - >>> import example - >>> def square(i): - ... return i * i - ... - >>> example.func_arg(square) - 100L - >>> square_plus_1 = example.func_ret(square) - >>> square_plus_1(4) - 17L - >>> plus_1 = func_cpp() - >>> plus_1(number=43) - 44L - -.. warning:: - - Keep in mind that passing a function from C++ to Python (or vice versa) - will instantiate a piece of wrapper code that translates function - invocations between the two languages. Naturally, this translation - increases the computational cost of each function call somewhat. A - problematic situation can arise when a function is copied back and forth - between Python and C++ many times in a row, in which case the underlying - wrappers will accumulate correspondingly. The resulting long sequence of - C++ -> Python -> C++ -> ... roundtrips can significantly decrease - performance. - - There is one exception: pybind11 detects case where a stateless function - (i.e. a function pointer or a lambda function without captured variables) - is passed as an argument to another C++ function exposed in Python. In this - case, there is no overhead. Pybind11 will extract the underlying C++ - function pointer from the wrapped function to sidestep a potential C++ -> - Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`. - -.. note:: - - This functionality is very useful when generating bindings for callbacks in - C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.). - - The file :file:`tests/test_callbacks.cpp` contains a complete example - that demonstrates how to work with callbacks and anonymous functions in - more detail. diff --git a/stormpy/resources/pybind11/docs/advanced/cast/index.rst b/stormpy/resources/pybind11/docs/advanced/cast/index.rst deleted file mode 100755 index 36586af5c..000000000 --- a/stormpy/resources/pybind11/docs/advanced/cast/index.rst +++ /dev/null @@ -1,41 +0,0 @@ -Type conversions -################ - -Apart from enabling cross-language function calls, a fundamental problem -that a binding tool like pybind11 must address is to provide access to -native Python types in C++ and vice versa. There are three fundamentally -different ways to do this—which approach is preferable for a particular type -depends on the situation at hand. - -1. Use a native C++ type everywhere. In this case, the type must be wrapped - using pybind11-generated bindings so that Python can interact with it. - -2. Use a native Python type everywhere. It will need to be wrapped so that - C++ functions can interact with it. - -3. Use a native C++ type on the C++ side and a native Python type on the - Python side. pybind11 refers to this as a *type conversion*. - - Type conversions are the most "natural" option in the sense that native - (non-wrapped) types are used everywhere. The main downside is that a copy - of the data must be made on every Python ↔ C++ transition: this is - needed since the C++ and Python versions of the same type generally won't - have the same memory layout. - - pybind11 can perform many kinds of conversions automatically. An overview - is provided in the table ":ref:`conversion_table`". - -The following subsections discuss the differences between these options in more -detail. The main focus in this section is on type conversions, which represent -the last case of the above list. - -.. toctree:: - :maxdepth: 1 - - overview - stl - functional - chrono - eigen - custom - diff --git a/stormpy/resources/pybind11/docs/advanced/cast/overview.rst b/stormpy/resources/pybind11/docs/advanced/cast/overview.rst deleted file mode 100755 index 84085725c..000000000 --- a/stormpy/resources/pybind11/docs/advanced/cast/overview.rst +++ /dev/null @@ -1,144 +0,0 @@ -Overview -######## - -.. rubric:: 1. Native type in C++, wrapper in Python - -Exposing a custom C++ type using :class:`py::class_` was covered in detail -in the :doc:`/classes` section. There, the underlying data structure is -always the original C++ class while the :class:`py::class_` wrapper provides -a Python interface. Internally, when an object like this is sent from C++ to -Python, pybind11 will just add the outer wrapper layer over the native C++ -object. Getting it back from Python is just a matter of peeling off the -wrapper. - -.. rubric:: 2. Wrapper in C++, native type in Python - -This is the exact opposite situation. Now, we have a type which is native to -Python, like a ``tuple`` or a ``list``. One way to get this data into C++ is -with the :class:`py::object` family of wrappers. These are explained in more -detail in the :doc:`/advanced/pycpp/object` section. We'll just give a quick -example here: - -.. code-block:: cpp - - void print_list(py::list my_list) { - for (auto item : my_list) - std::cout << item << " "; - } - -.. code-block:: pycon - - >>> print_list([1, 2, 3]) - 1 2 3 - -The Python ``list`` is not converted in any way -- it's just wrapped in a C++ -:class:`py::list` class. At its core it's still a Python object. Copying a -:class:`py::list` will do the usual reference-counting like in Python. -Returning the object to Python will just remove the thin wrapper. - -.. rubric:: 3. Converting between native C++ and Python types - -In the previous two cases we had a native type in one language and a wrapper in -the other. Now, we have native types on both sides and we convert between them. - -.. code-block:: cpp - - void print_vector(const std::vector &v) { - for (auto item : v) - std::cout << item << "\n"; - } - -.. code-block:: pycon - - >>> print_vector([1, 2, 3]) - 1 2 3 - -In this case, pybind11 will construct a new ``std::vector`` and copy each -element from the Python ``list``. The newly constructed object will be passed -to ``print_vector``. The same thing happens in the other direction: a new -``list`` is made to match the value returned from C++. - -Lots of these conversions are supported out of the box, as shown in the table -below. They are very convenient, but keep in mind that these conversions are -fundamentally based on copying data. This is perfectly fine for small immutable -types but it may become quite expensive for large data structures. This can be -avoided by overriding the automatic conversion with a custom wrapper (i.e. the -above-mentioned approach 1). This requires some manual effort and more details -are available in the :ref:`opaque` section. - -.. _conversion_table: - -List of all builtin conversions -------------------------------- - -The following basic data types are supported out of the box (some may require -an additional extension header to be included). To pass other data structures -as arguments and return values, refer to the section on binding :ref:`classes`. - -+------------------------------------+---------------------------+-------------------------------+ -| Data type | Description | Header file | -+====================================+===========================+===============================+ -| ``int8_t``, ``uint8_t`` | 8-bit integers | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``char`` | Character literal | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::pair`` | Pair of two custom types | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::complex`` | Complex numbers | :file:`pybind11/complex.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::array`` | STL static array | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::vector`` | STL dynamic array | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::list`` | STL linked list | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::map`` | STL ordered map | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::unordered_map`` | STL unordered map | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::set`` | STL ordered set | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::unordered_set`` | STL unordered set | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::optional`` | STL optional type (C++17) | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::experimental::optional`` | STL optional type (exp.) | :file:`pybind11/stl.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` | -+------------------------------------+---------------------------+-------------------------------+ -| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` | -+------------------------------------+---------------------------+-------------------------------+ diff --git a/stormpy/resources/pybind11/docs/advanced/cast/stl.rst b/stormpy/resources/pybind11/docs/advanced/cast/stl.rst deleted file mode 100755 index bbd23732b..000000000 --- a/stormpy/resources/pybind11/docs/advanced/cast/stl.rst +++ /dev/null @@ -1,154 +0,0 @@ -STL containers -############## - -Automatic conversion -==================== - -When including the additional header file :file:`pybind11/stl.h`, conversions -between ``std::vector<>``, ``std::list<>``, ``std::set<>``, and ``std::map<>`` -and the Python ``list``, ``set`` and ``dict`` data structures are automatically -enabled. The types ``std::pair<>`` and ``std::tuple<>`` are already supported -out of the box with just the core :file:`pybind11/pybind11.h` header. - -The major downside of these implicit conversions is that containers must be -converted (i.e. copied) on every Python->C++ and C++->Python transition, which -can have implications on the program semantics and performance. Please read the -next sections for more details and alternative approaches that avoid this. - -.. note:: - - Arbitrary nesting of any of these types is possible. - -.. seealso:: - - The file :file:`tests/test_python_types.cpp` contains a complete - example that demonstrates how to pass STL data types in more detail. - -.. _opaque: - -Making opaque types -=================== - -pybind11 heavily relies on a template matching mechanism to convert parameters -and return values that are constructed from STL data types such as vectors, -linked lists, hash tables, etc. This even works in a recursive manner, for -instance to deal with lists of hash maps of pairs of elementary and custom -types, etc. - -However, a fundamental limitation of this approach is that internal conversions -between Python and C++ types involve a copy operation that prevents -pass-by-reference semantics. What does this mean? - -Suppose we bind the following function - -.. code-block:: cpp - - void append_1(std::vector &v) { - v.push_back(1); - } - -and call it from Python, the following happens: - -.. code-block:: pycon - - >>> v = [5, 6] - >>> append_1(v) - >>> print(v) - [5, 6] - -As you can see, when passing STL data structures by reference, modifications -are not propagated back the Python side. A similar situation arises when -exposing STL data structures using the ``def_readwrite`` or ``def_readonly`` -functions: - -.. code-block:: cpp - - /* ... definition ... */ - - class MyClass { - std::vector contents; - }; - - /* ... binding code ... */ - - py::class_(m, "MyClass") - .def(py::init<>) - .def_readwrite("contents", &MyClass::contents); - -In this case, properties can be read and written in their entirety. However, an -``append`` operation involving such a list type has no effect: - -.. code-block:: pycon - - >>> m = MyClass() - >>> m.contents = [5, 6] - >>> print(m.contents) - [5, 6] - >>> m.contents.append(7) - >>> print(m.contents) - [5, 6] - -Finally, the involved copy operations can be costly when dealing with very -large lists. To deal with all of the above situations, pybind11 provides a -macro named ``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based -conversion machinery of types, thus rendering them *opaque*. The contents of -opaque objects are never inspected or extracted, hence they *can* be passed by -reference. For instance, to turn ``std::vector`` into an opaque type, add -the declaration - -.. code-block:: cpp - - PYBIND11_MAKE_OPAQUE(std::vector); - -before any binding code (e.g. invocations to ``class_::def()``, etc.). This -macro must be specified at the top level (and outside of any namespaces), since -it instantiates a partial template overload. If your binding code consists of -multiple compilation units, it must be present in every file preceding any -usage of ``std::vector``. Opaque types must also have a corresponding -``class_`` declaration to associate them with a name in Python, and to define a -set of available operations, e.g.: - -.. code-block:: cpp - - py::class_>(m, "IntVector") - .def(py::init<>()) - .def("clear", &std::vector::clear) - .def("pop_back", &std::vector::pop_back) - .def("__len__", [](const std::vector &v) { return v.size(); }) - .def("__iter__", [](std::vector &v) { - return py::make_iterator(v.begin(), v.end()); - }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */ - // .... - -The ability to expose STL containers as native Python objects is a fairly -common request, hence pybind11 also provides an optional header file named -:file:`pybind11/stl_bind.h` that does exactly this. The mapped containers try -to match the behavior of their native Python counterparts as much as possible. - -The following example showcases usage of :file:`pybind11/stl_bind.h`: - -.. code-block:: cpp - - // Don't forget this - #include - - PYBIND11_MAKE_OPAQUE(std::vector); - PYBIND11_MAKE_OPAQUE(std::map); - - // ... - - // later in binding code: - py::bind_vector>(m, "VectorInt"); - py::bind_map>(m, "MapStringDouble"); - -Please take a look at the :ref:`macro_notes` before using the -``PYBIND11_MAKE_OPAQUE`` macro. - -.. seealso:: - - The file :file:`tests/test_opaque_types.cpp` contains a complete - example that demonstrates how to create and expose opaque types using - pybind11 in more detail. - - The file :file:`tests/test_stl_binders.cpp` shows how to use the - convenience STL container wrappers. diff --git a/stormpy/resources/pybind11/docs/advanced/classes.rst b/stormpy/resources/pybind11/docs/advanced/classes.rst deleted file mode 100755 index 4a423b578..000000000 --- a/stormpy/resources/pybind11/docs/advanced/classes.rst +++ /dev/null @@ -1,634 +0,0 @@ -Classes -####### - -This section presents advanced binding code for classes and it is assumed -that you are already familiar with the basics from :doc:`/classes`. - -.. _overriding_virtuals: - -Overriding virtual functions in Python -====================================== - -Suppose that a C++ class or interface has a virtual function that we'd like to -to override from within Python (we'll focus on the class ``Animal``; ``Dog`` is -given as a specific example of how one would do this with traditional C++ -code). - -.. code-block:: cpp - - class Animal { - public: - virtual ~Animal() { } - virtual std::string go(int n_times) = 0; - }; - - class Dog : public Animal { - public: - std::string go(int n_times) override { - std::string result; - for (int i=0; igo(3); - } - -Normally, the binding code for these classes would look as follows: - -.. code-block:: cpp - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_ animal(m, "Animal"); - animal - .def("go", &Animal::go); - - py::class_(m, "Dog", animal) - .def(py::init<>()); - - m.def("call_go", &call_go); - - return m.ptr(); - } - -However, these bindings are impossible to extend: ``Animal`` is not -constructible, and we clearly require some kind of "trampoline" that -redirects virtual calls back to Python. - -Defining a new type of ``Animal`` from within Python is possible but requires a -helper class that is defined as follows: - -.. code-block:: cpp - - class PyAnimal : public Animal { - public: - /* Inherit the constructors */ - using Animal::Animal; - - /* Trampoline (need one for each virtual function) */ - std::string go(int n_times) override { - PYBIND11_OVERLOAD_PURE( - std::string, /* Return type */ - Animal, /* Parent class */ - go, /* Name of function */ - n_times /* Argument(s) */ - ); - } - }; - -The macro :func:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual -functions, and :func:`PYBIND11_OVERLOAD` should be used for functions which have -a default implementation. There are also two alternate macros -:func:`PYBIND11_OVERLOAD_PURE_NAME` and :func:`PYBIND11_OVERLOAD_NAME` which -take a string-valued name argument between the *Parent class* and *Name of the -function* slots. This is useful when the C++ and Python versions of the -function have different names, e.g. ``operator()`` vs ``__call__``. - -The binding code also needs a few minor adaptations (highlighted): - -.. code-block:: cpp - :emphasize-lines: 4,6,7 - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_ animal(m, "Animal"); - animal - .def(py::init<>()) - .def("go", &Animal::go); - - py::class_(m, "Dog", animal) - .def(py::init<>()); - - m.def("call_go", &call_go); - - return m.ptr(); - } - -Importantly, pybind11 is made aware of the trampoline helper class by -specifying it as an extra template argument to :class:`class_`. (This can also -be combined with other template arguments such as a custom holder type; the -order of template types does not matter). Following this, we are able to -define a constructor as usual. - -Note, however, that the above is sufficient for allowing python classes to -extend ``Animal``, but not ``Dog``: see ref:`virtual_and_inheritance` for the -necessary steps required to providing proper overload support for inherited -classes. - -The Python session below shows how to override ``Animal::go`` and invoke it via -a virtual method call. - -.. code-block:: pycon - - >>> from example import * - >>> d = Dog() - >>> call_go(d) - u'woof! woof! woof! ' - >>> class Cat(Animal): - ... def go(self, n_times): - ... return "meow! " * n_times - ... - >>> c = Cat() - >>> call_go(c) - u'meow! meow! meow! ' - -Please take a look at the :ref:`macro_notes` before using this feature. - -.. note:: - - When the overridden type returns a reference or pointer to a type that - pybind11 converts from Python (for example, numeric values, std::string, - and other built-in value-converting types), there are some limitations to - be aware of: - - - because in these cases there is no C++ variable to reference (the value - is stored in the referenced Python variable), pybind11 provides one in - the PYBIND11_OVERLOAD macros (when needed) with static storage duration. - Note that this means that invoking the overloaded method on *any* - instance will change the referenced value stored in *all* instances of - that type. - - - Attempts to modify a non-const reference will not have the desired - effect: it will change only the static cache variable, but this change - will not propagate to underlying Python instance, and the change will be - replaced the next time the overload is invoked. - -.. seealso:: - - The file :file:`tests/test_virtual_functions.cpp` contains a complete - example that demonstrates how to override virtual functions using pybind11 - in more detail. - -.. _virtual_and_inheritance: - -Combining virtual functions and inheritance -=========================================== - -When combining virtual methods with inheritance, you need to be sure to provide -an override for each method for which you want to allow overrides from derived -python classes. For example, suppose we extend the above ``Animal``/``Dog`` -example as follows: - -.. code-block:: cpp - - class Animal { - public: - virtual std::string go(int n_times) = 0; - virtual std::string name() { return "unknown"; } - }; - class Dog : public class Animal { - public: - std::string go(int n_times) override { - std::string result; - for (int i=0; i class PyAnimal : public AnimalBase { - using AnimalBase::AnimalBase; // Inherit constructors - std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, AnimalBase, go, n_times); } - std::string name() override { PYBIND11_OVERLOAD(std::string, AnimalBase, name, ); } - }; - template class PyDog : public PyAnimal { - using PyAnimal::PyAnimal; // Inherit constructors - // Override PyAnimal's pure virtual go() with a non-pure one: - std::string go(int n_times) override { PYBIND11_OVERLOAD(std::string, DogBase, go, n_times); } - std::string bark() override { PYBIND11_OVERLOAD(std::string, DogBase, bark, ); } - }; - -This technique has the advantage of requiring just one trampoline method to be -declared per virtual method and pure virtual method override. It does, -however, require the compiler to generate at least as many methods (and -possibly more, if both pure virtual and overridden pure virtual methods are -exposed, as above). - -The classes are then registered with pybind11 using: - -.. code-block:: cpp - - py::class_> animal(m, "Animal"); - py::class_> dog(m, "Dog"); - py::class_> husky(m, "Husky"); - // ... add animal, dog, husky definitions - -Note that ``Husky`` did not require a dedicated trampoline template class at -all, since it neither declares any new virtual methods nor provides any pure -virtual method implementations. - -With either the repeated-virtuals or templated trampoline methods in place, you -can now create a python class that inherits from ``Dog``: - -.. code-block:: python - - class ShihTzu(Dog): - def bark(self): - return "yip!" - -.. seealso:: - - See the file :file:`tests/test_virtual_functions.cpp` for complete examples - using both the duplication and templated trampoline approaches. - -Extended trampoline class functionality -======================================= - -The trampoline classes described in the previous sections are, by default, only -initialized when needed. More specifically, they are initialized when a python -class actually inherits from a registered type (instead of merely creating an -instance of the registered type), or when a registered constructor is only -valid for the trampoline class but not the registered class. This is primarily -for performance reasons: when the trampoline class is not needed for anything -except virtual method dispatching, not initializing the trampoline class -improves performance by avoiding needing to do a run-time check to see if the -inheriting python instance has an overloaded method. - -Sometimes, however, it is useful to always initialize a trampoline class as an -intermediate class that does more than just handle virtual method dispatching. -For example, such a class might perform extra class initialization, extra -destruction operations, and might define new members and methods to enable a -more python-like interface to a class. - -In order to tell pybind11 that it should *always* initialize the trampoline -class when creating new instances of a type, the class constructors should be -declared using ``py::init_alias()`` instead of the usual -``py::init()``. This forces construction via the trampoline class, -ensuring member initialization and (eventual) destruction. - -.. seealso:: - - See the file :file:`tests/test_alias_initialization.cpp` for complete examples - showing both normal and forced trampoline instantiation. - -.. _custom_constructors: - -Custom constructors -=================== - -The syntax for binding constructors was previously introduced, but it only -works when a constructor with the given parameters actually exists on the C++ -side. To extend this to more general cases, let's take a look at what actually -happens under the hood: the following statement - -.. code-block:: cpp - - py::class_(m, "Example") - .def(py::init()); - -is short hand notation for - -.. code-block:: cpp - - py::class_(m, "Example") - .def("__init__", - [](Example &instance, int arg) { - new (&instance) Example(arg); - } - ); - -In other words, :func:`init` creates an anonymous function that invokes an -in-place constructor. Memory allocation etc. is already take care of beforehand -within pybind11. - -.. _classes_with_non_public_destructors: - -Non-public destructors -====================== - -If a class has a private or protected destructor (as might e.g. be the case in -a singleton pattern), a compile error will occur when creating bindings via -pybind11. The underlying issue is that the ``std::unique_ptr`` holder type that -is responsible for managing the lifetime of instances will reference the -destructor even if no deallocations ever take place. In order to expose classes -with private or protected destructors, it is possible to override the holder -type via a holder type argument to ``class_``. Pybind11 provides a helper class -``py::nodelete`` that disables any destructor invocations. In this case, it is -crucial that instances are deallocated on the C++ side to avoid memory leaks. - -.. code-block:: cpp - - /* ... definition ... */ - - class MyClass { - private: - ~MyClass() { } - }; - - /* ... binding code ... */ - - py::class_>(m, "MyClass") - .def(py::init<>) - -Implicit conversions -==================== - -Suppose that instances of two types ``A`` and ``B`` are used in a project, and -that an ``A`` can easily be converted into an instance of type ``B`` (examples of this -could be a fixed and an arbitrary precision number type). - -.. code-block:: cpp - - py::class_(m, "A") - /// ... members ... - - py::class_(m, "B") - .def(py::init()) - /// ... members ... - - m.def("func", - [](const B &) { /* .... */ } - ); - -To invoke the function ``func`` using a variable ``a`` containing an ``A`` -instance, we'd have to write ``func(B(a))`` in Python. On the other hand, C++ -will automatically apply an implicit type conversion, which makes it possible -to directly write ``func(a)``. - -In this situation (i.e. where ``B`` has a constructor that converts from -``A``), the following statement enables similar implicit conversions on the -Python side: - -.. code-block:: cpp - - py::implicitly_convertible(); - -.. note:: - - Implicit conversions from ``A`` to ``B`` only work when ``B`` is a custom - data type that is exposed to Python via pybind11. - -.. _static_properties: - -Static properties -================= - -The section on :ref:`properties` discussed the creation of instance properties -that are implemented in terms of C++ getters and setters. - -Static properties can also be created in a similar way to expose getters and -setters of static class attributes. It is important to note that the implicit -``self`` argument also exists in this case and is used to pass the Python -``type`` subclass instance. This parameter will often not be needed by the C++ -side, and the following example illustrates how to instantiate a lambda getter -function that ignores it: - -.. code-block:: cpp - - py::class_(m, "Foo") - .def_property_readonly_static("foo", [](py::object /* self */) { return Foo(); }); - -Operator overloading -==================== - -Suppose that we're given the following ``Vector2`` class with a vector addition -and scalar multiplication operation, all implemented using overloaded operators -in C++. - -.. code-block:: cpp - - class Vector2 { - public: - Vector2(float x, float y) : x(x), y(y) { } - - Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); } - Vector2 operator*(float value) const { return Vector2(x * value, y * value); } - Vector2& operator+=(const Vector2 &v) { x += v.x; y += v.y; return *this; } - Vector2& operator*=(float v) { x *= v; y *= v; return *this; } - - friend Vector2 operator*(float f, const Vector2 &v) { - return Vector2(f * v.x, f * v.y); - } - - std::string toString() const { - return "[" + std::to_string(x) + ", " + std::to_string(y) + "]"; - } - private: - float x, y; - }; - -The following snippet shows how the above operators can be conveniently exposed -to Python. - -.. code-block:: cpp - - #include - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_(m, "Vector2") - .def(py::init()) - .def(py::self + py::self) - .def(py::self += py::self) - .def(py::self *= float()) - .def(float() * py::self) - .def("__repr__", &Vector2::toString); - - return m.ptr(); - } - -Note that a line like - -.. code-block:: cpp - - .def(py::self * float()) - -is really just short hand notation for - -.. code-block:: cpp - - .def("__mul__", [](const Vector2 &a, float b) { - return a * b; - }, py::is_operator()) - -This can be useful for exposing additional operators that don't exist on the -C++ side, or to perform other types of customization. The ``py::is_operator`` -flag marker is needed to inform pybind11 that this is an operator, which -returns ``NotImplemented`` when invoked with incompatible arguments rather than -throwing a type error. - -.. note:: - - To use the more convenient ``py::self`` notation, the additional - header file :file:`pybind11/operators.h` must be included. - -.. seealso:: - - The file :file:`tests/test_operator_overloading.cpp` contains a - complete example that demonstrates how to work with overloaded operators in - more detail. - -Pickling support -================ - -Python's ``pickle`` module provides a powerful facility to serialize and -de-serialize a Python object graph into a binary data stream. To pickle and -unpickle C++ classes using pybind11, two additional functions must be provided. -Suppose the class in question has the following signature: - -.. code-block:: cpp - - class Pickleable { - public: - Pickleable(const std::string &value) : m_value(value) { } - const std::string &value() const { return m_value; } - - void setExtra(int extra) { m_extra = extra; } - int extra() const { return m_extra; } - private: - std::string m_value; - int m_extra = 0; - }; - -The binding code including the requisite ``__setstate__`` and ``__getstate__`` methods [#f3]_ -looks as follows: - -.. code-block:: cpp - - py::class_(m, "Pickleable") - .def(py::init()) - .def("value", &Pickleable::value) - .def("extra", &Pickleable::extra) - .def("setExtra", &Pickleable::setExtra) - .def("__getstate__", [](const Pickleable &p) { - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(p.value(), p.extra()); - }) - .def("__setstate__", [](Pickleable &p, py::tuple t) { - if (t.size() != 2) - throw std::runtime_error("Invalid state!"); - - /* Invoke the in-place constructor. Note that this is needed even - when the object just has a trivial default constructor */ - new (&p) Pickleable(t[0].cast()); - - /* Assign any additional state */ - p.setExtra(t[1].cast()); - }); - -An instance can now be pickled as follows: - -.. code-block:: python - - try: - import cPickle as pickle # Use cPickle on Python 2.7 - except ImportError: - import pickle - - p = Pickleable("test_value") - p.setExtra(15) - data = pickle.dumps(p, 2) - -Note that only the cPickle module is supported on Python 2.7. The second -argument to ``dumps`` is also crucial: it selects the pickle protocol version -2, since the older version 1 is not supported. Newer versions are also fine—for -instance, specify ``-1`` to always use the latest available version. Beware: -failure to follow these instructions will cause important pybind11 memory -allocation routines to be skipped during unpickling, which will likely lead to -memory corruption and/or segmentation faults. - -.. seealso:: - - The file :file:`tests/test_pickling.cpp` contains a complete example - that demonstrates how to pickle and unpickle types using pybind11 in more - detail. - -.. [#f3] http://docs.python.org/3/library/pickle.html#pickling-class-instances - -Multiple Inheritance -==================== - -pybind11 can create bindings for types that derive from multiple base types -(aka. *multiple inheritance*). To do so, specify all bases in the template -arguments of the ``class_`` declaration: - -.. code-block:: cpp - - py::class_(m, "MyType") - ... - -The base types can be specified in arbitrary order, and they can even be -interspersed with alias types and holder types (discussed earlier in this -document)---pybind11 will automatically find out which is which. The only -requirement is that the first template argument is the type to be declared. - -There are two caveats regarding the implementation of this feature: - -1. When only one base type is specified for a C++ type that actually has - multiple bases, pybind11 will assume that it does not participate in - multiple inheritance, which can lead to undefined behavior. In such cases, - add the tag ``multiple_inheritance``: - - .. code-block:: cpp - - py::class_(m, "MyType", py::multiple_inheritance()); - - The tag is redundant and does not need to be specified when multiple base - types are listed. - -2. As was previously discussed in the section on :ref:`overriding_virtuals`, it - is easy to create Python types that derive from C++ classes. It is even - possible to make use of multiple inheritance to declare a Python class which - has e.g. a C++ and a Python class as bases. However, any attempt to create a - type that has *two or more* C++ classes in its hierarchy of base types will - fail with a fatal error message: ``TypeError: multiple bases have instance - lay-out conflict``. Core Python types that are implemented in C (e.g. - ``dict``, ``list``, ``Exception``, etc.) also fall under this combination - and cannot be combined with C++ types bound using pybind11 via multiple - inheritance. diff --git a/stormpy/resources/pybind11/docs/advanced/exceptions.rst b/stormpy/resources/pybind11/docs/advanced/exceptions.rst deleted file mode 100755 index 348337916..000000000 --- a/stormpy/resources/pybind11/docs/advanced/exceptions.rst +++ /dev/null @@ -1,142 +0,0 @@ -Exceptions -########## - -Built-in exception translation -============================== - -When C++ code invoked from Python throws an ``std::exception``, it is -automatically converted into a Python ``Exception``. pybind11 defines multiple -special exception classes that will map to different types of Python -exceptions: - -.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}| - -+--------------------------------------+------------------------------+ -| C++ exception type | Python exception type | -+======================================+==============================+ -| :class:`std::exception` | ``RuntimeError`` | -+--------------------------------------+------------------------------+ -| :class:`std::bad_alloc` | ``MemoryError`` | -+--------------------------------------+------------------------------+ -| :class:`std::domain_error` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::invalid_argument` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::length_error` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::out_of_range` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`std::range_error` | ``ValueError`` | -+--------------------------------------+------------------------------+ -| :class:`pybind11::stop_iteration` | ``StopIteration`` (used to | -| | implement custom iterators) | -+--------------------------------------+------------------------------+ -| :class:`pybind11::index_error` | ``IndexError`` (used to | -| | indicate out of bounds | -| | accesses in ``__getitem__``, | -| | ``__setitem__``, etc.) | -+--------------------------------------+------------------------------+ -| :class:`pybind11::value_error` | ``ValueError`` (used to | -| | indicate wrong value passed | -| | in ``container.remove(...)`` | -+--------------------------------------+------------------------------+ -| :class:`pybind11::key_error` | ``KeyError`` (used to | -| | indicate out of bounds | -| | accesses in ``__getitem__``, | -| | ``__setitem__`` in dict-like | -| | objects, etc.) | -+--------------------------------------+------------------------------+ -| :class:`pybind11::error_already_set` | Indicates that the Python | -| | exception flag has already | -| | been initialized | -+--------------------------------------+------------------------------+ - -When a Python function invoked from C++ throws an exception, it is converted -into a C++ exception of type :class:`error_already_set` whose string payload -contains a textual summary. - -There is also a special exception :class:`cast_error` that is thrown by -:func:`handle::call` when the input arguments cannot be converted to Python -objects. - -Registering custom translators -============================== - -If the default exception conversion policy described above is insufficient, -pybind11 also provides support for registering custom exception translators. -To register a simple exception conversion that translates a C++ exception into -a new Python exception using the C++ exception's ``what()`` method, a helper -function is available: - -.. code-block:: cpp - - py::register_exception(module, "PyExp"); - -This call creates a Python exception class with the name ``PyExp`` in the given -module and automatically converts any encountered exceptions of type ``CppExp`` -into Python exceptions of type ``PyExp``. - -When more advanced exception translation is needed, the function -``py::register_exception_translator(translator)`` can be used to register -functions that can translate arbitrary exception types (and which may include -additional logic to do so). The function takes a stateless callable (e.g. a -function pointer or a lambda function without captured variables) with the call -signature ``void(std::exception_ptr)``. - -When a C++ exception is thrown, the registered exception translators are tried -in reverse order of registration (i.e. the last registered translator gets the -first shot at handling the exception). - -Inside the translator, ``std::rethrow_exception`` should be used within -a try block to re-throw the exception. One or more catch clauses to catch -the appropriate exceptions should then be used with each clause using -``PyErr_SetString`` to set a Python exception or ``ex(string)`` to set -the python exception to a custom exception type (see below). - -To declare a custom Python exception type, declare a ``py::exception`` variable -and use this in the associated exception translator (note: it is often useful -to make this a static declaration when using it inside a lambda expression -without requiring capturing). - - -The following example demonstrates this for a hypothetical exception classes -``MyCustomException`` and ``OtherException``: the first is translated to a -custom python exception ``MyCustomError``, while the second is translated to a -standard python RuntimeError: - -.. code-block:: cpp - - static py::exception exc(m, "MyCustomError"); - py::register_exception_translator([](std::exception_ptr p) { - try { - if (p) std::rethrow_exception(p); - } catch (const MyCustomException &e) { - exc(e.what()); - } catch (const OtherException &e) { - PyErr_SetString(PyExc_RuntimeError, e.what()); - } - }); - -Multiple exceptions can be handled by a single translator, as shown in the -example above. If the exception is not caught by the current translator, the -previously registered one gets a chance. - -If none of the registered exception translators is able to handle the -exception, it is handled by the default converter as described in the previous -section. - -.. seealso:: - - The file :file:`tests/test_exceptions.cpp` contains examples - of various custom exception translators and custom exception types. - -.. note:: - - You must call either ``PyErr_SetString`` or a custom exception's call - operator (``exc(string)``) for every exception caught in a custom exception - translator. Failure to do so will cause Python to crash with ``SystemError: - error return without exception set``. - - Exceptions that you do not plan to handle should simply not be caught, or - may be explicity (re-)thrown to delegate it to the other, - previously-declared existing exception translators. diff --git a/stormpy/resources/pybind11/docs/advanced/functions.rst b/stormpy/resources/pybind11/docs/advanced/functions.rst deleted file mode 100755 index f291e8222..000000000 --- a/stormpy/resources/pybind11/docs/advanced/functions.rst +++ /dev/null @@ -1,311 +0,0 @@ -Functions -######### - -Before proceeding with this section, make sure that you are already familiar -with the basics of binding functions and classes, as explained in :doc:`/basics` -and :doc:`/classes`. The following guide is applicable to both free and member -functions, i.e. *methods* in Python. - -Return value policies -===================== - -Python and C++ use fundamentally different ways of managing the memory and -lifetime of objects managed by them. This can lead to issues when creating -bindings for functions that return a non-trivial type. Just by looking at the -type information, it is not clear whether Python should take charge of the -returned value and eventually free its resources, or if this is handled on the -C++ side. For this reason, pybind11 provides a several `return value policy` -annotations that can be passed to the :func:`module::def` and -:func:`class_::def` functions. The default policy is -:enum:`return_value_policy::automatic`. - -Return value policies are tricky, and it's very important to get them right. -Just to illustrate what can go wrong, consider the following simple example: - -.. code-block:: cpp - - /* Function declaration */ - Data *get_data() { return _data; /* (pointer to a static data structure) */ } - ... - - /* Binding code */ - m.def("get_data", &get_data); // <-- KABOOM, will cause crash when called from Python - -What's going on here? When ``get_data()`` is called from Python, the return -value (a native C++ type) must be wrapped to turn it into a usable Python type. -In this case, the default return value policy (:enum:`return_value_policy::automatic`) -causes pybind11 to assume ownership of the static ``_data`` instance. - -When Python's garbage collector eventually deletes the Python -wrapper, pybind11 will also attempt to delete the C++ instance (via ``operator -delete()``) due to the implied ownership. At this point, the entire application -will come crashing down, though errors could also be more subtle and involve -silent data corruption. - -In the above example, the policy :enum:`return_value_policy::reference` should have -been specified so that the global data instance is only *referenced* without any -implied transfer of ownership, i.e.: - -.. code-block:: cpp - - m.def("get_data", &get_data, return_value_policy::reference); - -On the other hand, this is not the right policy for many other situations, -where ignoring ownership could lead to resource leaks. -As a developer using pybind11, it's important to be familiar with the different -return value policies, including which situation calls for which one of them. -The following table provides an overview of available policies: - -.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}| - -+--------------------------------------------------+----------------------------------------------------------------------------+ -| Return value policy | Description | -+==================================================+============================================================================+ -| :enum:`return_value_policy::take_ownership` | Reference an existing object (i.e. do not create a new copy) and take | -| | ownership. Python will call the destructor and delete operator when the | -| | object's reference count reaches zero. Undefined behavior ensues when the | -| | C++ side does the same, or when the data was not dynamically allocated. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::copy` | Create a new copy of the returned object, which will be owned by Python. | -| | This policy is comparably safe because the lifetimes of the two instances | -| | are decoupled. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::move` | Use ``std::move`` to move the return value contents into a new instance | -| | that will be owned by Python. This policy is comparably safe because the | -| | lifetimes of the two instances (move source and destination) are decoupled.| -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::reference` | Reference an existing object, but do not take ownership. The C++ side is | -| | responsible for managing the object's lifetime and deallocating it when | -| | it is no longer used. Warning: undefined behavior will ensue when the C++ | -| | side deletes an object that is still referenced and used by Python. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::reference_internal` | Indicates that the lifetime of the return value is tied to the lifetime | -| | of a parent object, namely the implicit ``this``, or ``self`` argument of | -| | the called method or property. Internally, this policy works just like | -| | :enum:`return_value_policy::reference` but additionally applies a | -| | ``keep_alive<0, 1>`` *call policy* (described in the next section) that | -| | prevents the parent object from being garbage collected as long as the | -| | return value is referenced by Python. This is the default policy for | -| | property getters created via ``def_property``, ``def_readwrite``, etc. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::automatic` | This is the default return value policy, which falls back to the policy | -| | :enum:`return_value_policy::take_ownership` when the return value is a | -| | pointer. Otherwise, it uses :enum:`return_value::move` or | -| | :enum:`return_value::copy` for rvalue and lvalue references, respectively. | -| | See above for a description of what all of these different policies do. | -+--------------------------------------------------+----------------------------------------------------------------------------+ -| :enum:`return_value_policy::automatic_reference` | As above, but use policy :enum:`return_value_policy::reference` when the | -| | return value is a pointer. This is the default conversion policy for | -| | function arguments when calling Python functions manually from C++ code | -| | (i.e. via handle::operator()). You probably won't need to use this. | -+--------------------------------------------------+----------------------------------------------------------------------------+ - -Return value policies can also be applied to properties: - -.. code-block:: cpp - - class_(m, "MyClass") - .def_property("data", &MyClass::getData, &MyClass::setData, - py::return_value_policy::copy); - -Technically, the code above applies the policy to both the getter and the -setter function, however, the setter doesn't really care about *return* -value policies which makes this a convenient terse syntax. Alternatively, -targeted arguments can be passed through the :class:`cpp_function` constructor: - -.. code-block:: cpp - - class_(m, "MyClass") - .def_property("data" - py::cpp_function(&MyClass::getData, py::return_value_policy::copy), - py::cpp_function(&MyClass::setData) - ); - -.. warning:: - - Code with invalid return value policies might access unitialized memory or - free data structures multiple times, which can lead to hard-to-debug - non-determinism and segmentation faults, hence it is worth spending the - time to understand all the different options in the table above. - -.. note:: - - One important aspect of the above policies is that they only apply to - instances which pybind11 has *not* seen before, in which case the policy - clarifies essential questions about the return value's lifetime and - ownership. When pybind11 knows the instance already (as identified by its - type and address in memory), it will return the existing Python object - wrapper rather than creating a new copy. - -.. note:: - - The next section on :ref:`call_policies` discusses *call policies* that can be - specified *in addition* to a return value policy from the list above. Call - policies indicate reference relationships that can involve both return values - and parameters of functions. - -.. note:: - - As an alternative to elaborate call policies and lifetime management logic, - consider using smart pointers (see the section on :ref:`smart_pointers` for - details). Smart pointers can tell whether an object is still referenced from - C++ or Python, which generally eliminates the kinds of inconsistencies that - can lead to crashes or undefined behavior. For functions returning smart - pointers, it is not necessary to specify a return value policy. - -.. _call_policies: - -Additional call policies -======================== - -In addition to the above return value policies, further `call policies` can be -specified to indicate dependencies between parameters. There is currently just -one policy named ``keep_alive``, which indicates that the -argument with index ``Patient`` should be kept alive at least until the -argument with index ``Nurse`` is freed by the garbage collector. Argument -indices start at one, while zero refers to the return value. For methods, index -``1`` refers to the implicit ``this`` pointer, while regular arguments begin at -index ``2``. Arbitrarily many call policies can be specified. When a ``Nurse`` -with value ``None`` is detected at runtime, the call policy does nothing. - -This feature internally relies on the ability to create a *weak reference* to -the nurse object, which is permitted by all classes exposed via pybind11. When -the nurse object does not support weak references, an exception will be thrown. - -Consider the following example: here, the binding code for a list append -operation ties the lifetime of the newly added element to the underlying -container: - -.. code-block:: cpp - - py::class_(m, "List") - .def("append", &List::append, py::keep_alive<1, 2>()); - -.. note:: - - ``keep_alive`` is analogous to the ``with_custodian_and_ward`` (if Nurse, - Patient != 0) and ``with_custodian_and_ward_postcall`` (if Nurse/Patient == - 0) policies from Boost.Python. - -.. seealso:: - - The file :file:`tests/test_keep_alive.cpp` contains a complete example - that demonstrates using :class:`keep_alive` in more detail. - -.. _python_objects_as_args: - -Python objects as arguments -=========================== - -pybind11 exposes all major Python types using thin C++ wrapper classes. These -wrapper classes can also be used as parameters of functions in bindings, which -makes it possible to directly work with native Python types on the C++ side. -For instance, the following statement iterates over a Python ``dict``: - -.. code-block:: cpp - - void print_dict(py::dict dict) { - /* Easily interact with Python types */ - for (auto item : dict) - std::cout << "key=" << item.first << ", " - << "value=" << item.second << std::endl; - } - -It can be exported: - -.. code-block:: cpp - - m.def("print_dict", &print_dict); - -And used in Python as usual: - -.. code-block:: pycon - - >>> print_dict({'foo': 123, 'bar': 'hello'}) - key=foo, value=123 - key=bar, value=hello - -For more information on using Python objects in C++, see :doc:`/advanced/pycpp/index`. - -Accepting \*args and \*\*kwargs -=============================== - -Python provides a useful mechanism to define functions that accept arbitrary -numbers of arguments and keyword arguments: - -.. code-block:: python - - def generic(*args, **kwargs): - ... # do something with args and kwargs - -Such functions can also be created using pybind11: - -.. code-block:: cpp - - void generic(py::args args, py::kwargs kwargs) { - /// .. do something with args - if (kwargs) - /// .. do something with kwargs - } - - /// Binding code - m.def("generic", &generic); - -The class ``py::args`` derives from ``py::tuple`` and ``py::kwargs`` derives -from ``py::dict``. Note that the ``kwargs`` argument is invalid if no keyword -arguments were actually provided. Please refer to the other examples for -details on how to iterate over these, and on how to cast their entries into -C++ objects. A demonstration is also available in -``tests/test_kwargs_and_defaults.cpp``. - -.. warning:: - - Unlike Python, pybind11 does not allow combining normal parameters with the - ``args`` / ``kwargs`` special parameters. - -Default arguments revisited -=========================== - -The section on :ref:`default_args` previously discussed basic usage of default -arguments using pybind11. One noteworthy aspect of their implementation is that -default arguments are converted to Python objects right at declaration time. -Consider the following example: - -.. code-block:: cpp - - py::class_("MyClass") - .def("myFunction", py::arg("arg") = SomeType(123)); - -In this case, pybind11 must already be set up to deal with values of the type -``SomeType`` (via a prior instantiation of ``py::class_``), or an -exception will be thrown. - -Another aspect worth highlighting is that the "preview" of the default argument -in the function signature is generated using the object's ``__repr__`` method. -If not available, the signature may not be very helpful, e.g.: - -.. code-block:: pycon - - FUNCTIONS - ... - | myFunction(...) - | Signature : (MyClass, arg : SomeType = ) -> NoneType - ... - -The first way of addressing this is by defining ``SomeType.__repr__``. -Alternatively, it is possible to specify the human-readable preview of the -default argument manually using the ``arg_v`` notation: - -.. code-block:: cpp - - py::class_("MyClass") - .def("myFunction", py::arg_v("arg", SomeType(123), "SomeType(123)")); - -Sometimes it may be necessary to pass a null pointer value as a default -argument. In this case, remember to cast it to the underlying type in question, -like so: - -.. code-block:: cpp - - py::class_("MyClass") - .def("myFunction", py::arg("arg") = (SomeType *) nullptr); diff --git a/stormpy/resources/pybind11/docs/advanced/misc.rst b/stormpy/resources/pybind11/docs/advanced/misc.rst deleted file mode 100755 index c13df7bf8..000000000 --- a/stormpy/resources/pybind11/docs/advanced/misc.rst +++ /dev/null @@ -1,229 +0,0 @@ -Miscellaneous -############# - -.. _macro_notes: - -General notes regarding convenience macros -========================================== - -pybind11 provides a few convenience macros such as -:func:`PYBIND11_MAKE_OPAQUE` and :func:`PYBIND11_DECLARE_HOLDER_TYPE`, and -``PYBIND11_OVERLOAD_*``. Since these are "just" macros that are evaluated -in the preprocessor (which has no concept of types), they *will* get confused -by commas in a template argument such as ``PYBIND11_OVERLOAD(MyReturnValue, myFunc)``. In this case, the preprocessor assumes that the comma indicates -the beginning of the next parameter. Use a ``typedef`` to bind the template to -another name and use it in the macro to avoid this problem. - - -Global Interpreter Lock (GIL) -============================= - -The classes :class:`gil_scoped_release` and :class:`gil_scoped_acquire` can be -used to acquire and release the global interpreter lock in the body of a C++ -function call. In this way, long-running C++ code can be parallelized using -multiple Python threads. Taking :ref:`overriding_virtuals` as an example, this -could be realized as follows (important changes highlighted): - -.. code-block:: cpp - :emphasize-lines: 8,9,33,34 - - class PyAnimal : public Animal { - public: - /* Inherit the constructors */ - using Animal::Animal; - - /* Trampoline (need one for each virtual function) */ - std::string go(int n_times) { - /* Acquire GIL before calling Python code */ - py::gil_scoped_acquire acquire; - - PYBIND11_OVERLOAD_PURE( - std::string, /* Return type */ - Animal, /* Parent class */ - go, /* Name of function */ - n_times /* Argument(s) */ - ); - } - }; - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_ animal(m, "Animal"); - animal - .def(py::init<>()) - .def("go", &Animal::go); - - py::class_(m, "Dog", animal) - .def(py::init<>()); - - m.def("call_go", [](Animal *animal) -> std::string { - /* Release GIL before calling into (potentially long-running) C++ code */ - py::gil_scoped_release release; - return call_go(animal); - }); - - return m.ptr(); - } - - -Binding sequence data types, iterators, the slicing protocol, etc. -================================================================== - -Please refer to the supplemental example for details. - -.. seealso:: - - The file :file:`tests/test_sequences_and_iterators.cpp` contains a - complete example that shows how to bind a sequence data type, including - length queries (``__len__``), iterators (``__iter__``), the slicing - protocol and other kinds of useful operations. - - -Partitioning code over multiple extension modules -================================================= - -It's straightforward to split binding code over multiple extension modules, -while referencing types that are declared elsewhere. Everything "just" works -without any special precautions. One exception to this rule occurs when -extending a type declared in another extension module. Recall the basic example -from Section :ref:`inheritance`. - -.. code-block:: cpp - - py::class_ pet(m, "Pet"); - pet.def(py::init()) - .def_readwrite("name", &Pet::name); - - py::class_(m, "Dog", pet /* <- specify parent */) - .def(py::init()) - .def("bark", &Dog::bark); - -Suppose now that ``Pet`` bindings are defined in a module named ``basic``, -whereas the ``Dog`` bindings are defined somewhere else. The challenge is of -course that the variable ``pet`` is not available anymore though it is needed -to indicate the inheritance relationship to the constructor of ``class_``. -However, it can be acquired as follows: - -.. code-block:: cpp - - py::object pet = (py::object) py::module::import("basic").attr("Pet"); - - py::class_(m, "Dog", pet) - .def(py::init()) - .def("bark", &Dog::bark); - -Alternatively, you can specify the base class as a template parameter option to -``class_``, which performs an automated lookup of the corresponding Python -type. Like the above code, however, this also requires invoking the ``import`` -function once to ensure that the pybind11 binding code of the module ``basic`` -has been executed: - -.. code-block:: cpp - - py::module::import("basic"); - - py::class_(m, "Dog") - .def(py::init()) - .def("bark", &Dog::bark); - -Naturally, both methods will fail when there are cyclic dependencies. - -Note that compiling code which has its default symbol visibility set to -*hidden* (e.g. via the command line flag ``-fvisibility=hidden`` on GCC/Clang) can interfere with the -ability to access types defined in another extension module. Workarounds -include changing the global symbol visibility (not recommended, because it will -lead unnecessarily large binaries) or manually exporting types that are -accessed by multiple extension modules: - -.. code-block:: cpp - - #ifdef _WIN32 - # define EXPORT_TYPE __declspec(dllexport) - #else - # define EXPORT_TYPE __attribute__ ((visibility("default"))) - #endif - - class EXPORT_TYPE Dog : public Animal { - ... - }; - -Note also that it is possible (although would rarely be required) to share arbitrary -C++ objects between extension modules at runtime. Internal library data is shared -between modules using capsule machinery [#f6]_ which can be also utilized for -storing, modifying and accessing user-defined data. Note that an extension module -will "see" other extensions' data if and only if they were built with the same -pybind11 version. Consider the following example: - -.. code-block:: cpp - - auto data = (MyData *) py::get_shared_data("mydata"); - if (!data) - data = (MyData *) py::set_shared_data("mydata", new MyData(42)); - -If the above snippet was used in several separately compiled extension modules, -the first one to be imported would create a ``MyData`` instance and associate -a ``"mydata"`` key with a pointer to it. Extensions that are imported later -would be then able to access the data behind the same pointer. - -.. [#f6] https://docs.python.org/3/extending/extending.html#using-capsules - - -Generating documentation using Sphinx -===================================== - -Sphinx [#f4]_ has the ability to inspect the signatures and documentation -strings in pybind11-based extension modules to automatically generate beautiful -documentation in a variety formats. The python_example repository [#f5]_ contains a -simple example repository which uses this approach. - -There are two potential gotchas when using this approach: first, make sure that -the resulting strings do not contain any :kbd:`TAB` characters, which break the -docstring parsing routines. You may want to use C++11 raw string literals, -which are convenient for multi-line comments. Conveniently, any excess -indentation will be automatically be removed by Sphinx. However, for this to -work, it is important that all lines are indented consistently, i.e.: - -.. code-block:: cpp - - // ok - m.def("foo", &foo, R"mydelimiter( - The foo function - - Parameters - ---------- - )mydelimiter"); - - // *not ok* - m.def("foo", &foo, R"mydelimiter(The foo function - - Parameters - ---------- - )mydelimiter"); - -By default, pybind11 automatically generates and prepends a signature to the docstring of a function -registered with ``module::def()`` and ``class_::def()``. Sometimes this -behavior is not desirable, because you want to provide your own signature or remove -the docstring completely to exclude the function from the Sphinx documentation. -The class ``options`` allows you to selectively suppress auto-generated signatures: - -.. code-block:: cpp - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::options options; - options.disable_function_signatures(); - - m.def("add", [](int a, int b) { return a + b; }, "A function which adds two numbers"); - - return m.ptr(); - } - -Note that changes to the settings affect only function bindings created during the -lifetime of the ``options`` instance. When it goes out of scope at the end of the module's init function, -the default settings are restored to prevent unwanted side effects. - -.. [#f4] http://www.sphinx-doc.org -.. [#f5] http://github.com/pybind/python_example diff --git a/stormpy/resources/pybind11/docs/advanced/pycpp/index.rst b/stormpy/resources/pybind11/docs/advanced/pycpp/index.rst deleted file mode 100755 index 6885bdcff..000000000 --- a/stormpy/resources/pybind11/docs/advanced/pycpp/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -Python C++ interface -#################### - -pybind11 exposes Python types and functions using thin C++ wrappers, which -makes it possible to conveniently call Python code from C++ without resorting -to Python's C API. - -.. toctree:: - :maxdepth: 2 - - object - numpy - utilities diff --git a/stormpy/resources/pybind11/docs/advanced/pycpp/numpy.rst b/stormpy/resources/pybind11/docs/advanced/pycpp/numpy.rst deleted file mode 100755 index 8b46b7c83..000000000 --- a/stormpy/resources/pybind11/docs/advanced/pycpp/numpy.rst +++ /dev/null @@ -1,299 +0,0 @@ -.. _numpy: - -NumPy -##### - -Buffer protocol -=============== - -Python supports an extremely general and convenient approach for exchanging -data between plugin libraries. Types can expose a buffer view [#f2]_, which -provides fast direct access to the raw internal data representation. Suppose we -want to bind the following simplistic Matrix class: - -.. code-block:: cpp - - class Matrix { - public: - Matrix(size_t rows, size_t cols) : m_rows(rows), m_cols(cols) { - m_data = new float[rows*cols]; - } - float *data() { return m_data; } - size_t rows() const { return m_rows; } - size_t cols() const { return m_cols; } - private: - size_t m_rows, m_cols; - float *m_data; - }; - -The following binding code exposes the ``Matrix`` contents as a buffer object, -making it possible to cast Matrices into NumPy arrays. It is even possible to -completely avoid copy operations with Python expressions like -``np.array(matrix_instance, copy = False)``. - -.. code-block:: cpp - - py::class_(m, "Matrix") - .def_buffer([](Matrix &m) -> py::buffer_info { - return py::buffer_info( - m.data(), /* Pointer to buffer */ - sizeof(float), /* Size of one scalar */ - py::format_descriptor::format(), /* Python struct-style format descriptor */ - 2, /* Number of dimensions */ - { m.rows(), m.cols() }, /* Buffer dimensions */ - { sizeof(float) * m.rows(), /* Strides (in bytes) for each index */ - sizeof(float) } - ); - }); - -The snippet above binds a lambda function, which can create ``py::buffer_info`` -description records on demand describing a given matrix. The contents of -``py::buffer_info`` mirror the Python buffer protocol specification. - -.. code-block:: cpp - - struct buffer_info { - void *ptr; - size_t itemsize; - std::string format; - int ndim; - std::vector shape; - std::vector strides; - }; - -To create a C++ function that can take a Python buffer object as an argument, -simply use the type ``py::buffer`` as one of its arguments. Buffers can exist -in a great variety of configurations, hence some safety checks are usually -necessary in the function body. Below, you can see an basic example on how to -define a custom constructor for the Eigen double precision matrix -(``Eigen::MatrixXd``) type, which supports initialization from compatible -buffer objects (e.g. a NumPy matrix). - -.. code-block:: cpp - - /* Bind MatrixXd (or some other Eigen type) to Python */ - typedef Eigen::MatrixXd Matrix; - - typedef Matrix::Scalar Scalar; - constexpr bool rowMajor = Matrix::Flags & Eigen::RowMajorBit; - - py::class_(m, "Matrix") - .def("__init__", [](Matrix &m, py::buffer b) { - typedef Eigen::Stride Strides; - - /* Request a buffer descriptor from Python */ - py::buffer_info info = b.request(); - - /* Some sanity checks ... */ - if (info.format != py::format_descriptor::format()) - throw std::runtime_error("Incompatible format: expected a double array!"); - - if (info.ndim != 2) - throw std::runtime_error("Incompatible buffer dimension!"); - - auto strides = Strides( - info.strides[rowMajor ? 0 : 1] / sizeof(Scalar), - info.strides[rowMajor ? 1 : 0] / sizeof(Scalar)); - - auto map = Eigen::Map( - static_cat(info.ptr), info.shape[0], info.shape[1], strides); - - new (&m) Matrix(map); - }); - -For reference, the ``def_buffer()`` call for this Eigen data type should look -as follows: - -.. code-block:: cpp - - .def_buffer([](Matrix &m) -> py::buffer_info { - return py::buffer_info( - m.data(), /* Pointer to buffer */ - sizeof(Scalar), /* Size of one scalar */ - /* Python struct-style format descriptor */ - py::format_descriptor::format(), - /* Number of dimensions */ - 2, - /* Buffer dimensions */ - { (size_t) m.rows(), - (size_t) m.cols() }, - /* Strides (in bytes) for each index */ - { sizeof(Scalar) * (rowMajor ? m.cols() : 1), - sizeof(Scalar) * (rowMajor ? 1 : m.rows()) } - ); - }) - -For a much easier approach of binding Eigen types (although with some -limitations), refer to the section on :doc:`/advanced/cast/eigen`. - -.. seealso:: - - The file :file:`tests/test_buffers.cpp` contains a complete example - that demonstrates using the buffer protocol with pybind11 in more detail. - -.. [#f2] http://docs.python.org/3/c-api/buffer.html - -Arrays -====== - -By exchanging ``py::buffer`` with ``py::array`` in the above snippet, we can -restrict the function so that it only accepts NumPy arrays (rather than any -type of Python object satisfying the buffer protocol). - -In many situations, we want to define a function which only accepts a NumPy -array of a certain data type. This is possible via the ``py::array_t`` -template. For instance, the following function requires the argument to be a -NumPy array containing double precision values. - -.. code-block:: cpp - - void f(py::array_t array); - -When it is invoked with a different type (e.g. an integer or a list of -integers), the binding code will attempt to cast the input into a NumPy array -of the requested type. Note that this feature requires the -:file:``pybind11/numpy.h`` header to be included. - -Data in NumPy arrays is not guaranteed to packed in a dense manner; -furthermore, entries can be separated by arbitrary column and row strides. -Sometimes, it can be useful to require a function to only accept dense arrays -using either the C (row-major) or Fortran (column-major) ordering. This can be -accomplished via a second template argument with values ``py::array::c_style`` -or ``py::array::f_style``. - -.. code-block:: cpp - - void f(py::array_t array); - -The ``py::array::forcecast`` argument is the default value of the second -template parameter, and it ensures that non-conforming arguments are converted -into an array satisfying the specified requirements instead of trying the next -function overload. - -Structured types -================ - -In order for ``py::array_t`` to work with structured (record) types, we first need -to register the memory layout of the type. This can be done via ``PYBIND11_NUMPY_DTYPE`` -macro which expects the type followed by field names: - -.. code-block:: cpp - - struct A { - int x; - double y; - }; - - struct B { - int z; - A a; - }; - - PYBIND11_NUMPY_DTYPE(A, x, y); - PYBIND11_NUMPY_DTYPE(B, z, a); - - /* now both A and B can be used as template arguments to py::array_t */ - -Vectorizing functions -===================== - -Suppose we want to bind a function with the following signature to Python so -that it can process arbitrary NumPy array arguments (vectors, matrices, general -N-D arrays) in addition to its normal arguments: - -.. code-block:: cpp - - double my_func(int x, float y, double z); - -After including the ``pybind11/numpy.h`` header, this is extremely simple: - -.. code-block:: cpp - - m.def("vectorized_func", py::vectorize(my_func)); - -Invoking the function like below causes 4 calls to be made to ``my_func`` with -each of the array elements. The significant advantage of this compared to -solutions like ``numpy.vectorize()`` is that the loop over the elements runs -entirely on the C++ side and can be crunched down into a tight, optimized loop -by the compiler. The result is returned as a NumPy array of type -``numpy.dtype.float64``. - -.. code-block:: pycon - - >>> x = np.array([[1, 3],[5, 7]]) - >>> y = np.array([[2, 4],[6, 8]]) - >>> z = 3 - >>> result = vectorized_func(x, y, z) - -The scalar argument ``z`` is transparently replicated 4 times. The input -arrays ``x`` and ``y`` are automatically converted into the right types (they -are of type ``numpy.dtype.int64`` but need to be ``numpy.dtype.int32`` and -``numpy.dtype.float32``, respectively) - -Sometimes we might want to explicitly exclude an argument from the vectorization -because it makes little sense to wrap it in a NumPy array. For instance, -suppose the function signature was - -.. code-block:: cpp - - double my_func(int x, float y, my_custom_type *z); - -This can be done with a stateful Lambda closure: - -.. code-block:: cpp - - // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the vectorization) - m.def("vectorized_func", - [](py::array_t x, py::array_t y, my_custom_type *z) { - auto stateful_closure = [z](int x, float y) { return my_func(x, y, z); }; - return py::vectorize(stateful_closure)(x, y); - } - ); - -In cases where the computation is too complicated to be reduced to -``vectorize``, it will be necessary to create and access the buffer contents -manually. The following snippet contains a complete example that shows how this -works (the code is somewhat contrived, since it could have been done more -simply using ``vectorize``). - -.. code-block:: cpp - - #include - #include - - namespace py = pybind11; - - py::array_t add_arrays(py::array_t input1, py::array_t input2) { - auto buf1 = input1.request(), buf2 = input2.request(); - - if (buf1.ndim != 1 || buf2.ndim != 1) - throw std::runtime_error("Number of dimensions must be one"); - - if (buf1.size != buf2.size) - throw std::runtime_error("Input shapes must match"); - - /* No pointer is passed, so NumPy will allocate the buffer */ - auto result = py::array_t(buf1.size); - - auto buf3 = result.request(); - - double *ptr1 = (double *) buf1.ptr, - *ptr2 = (double *) buf2.ptr, - *ptr3 = (double *) buf3.ptr; - - for (size_t idx = 0; idx < buf1.shape[0]; idx++) - ptr3[idx] = ptr1[idx] + ptr2[idx]; - - return result; - } - - PYBIND11_PLUGIN(test) { - py::module m("test"); - m.def("add_arrays", &add_arrays, "Add two NumPy arrays"); - return m.ptr(); - } - -.. seealso:: - - The file :file:`tests/test_numpy_vectorize.cpp` contains a complete - example that demonstrates using :func:`vectorize` in more detail. diff --git a/stormpy/resources/pybind11/docs/advanced/pycpp/object.rst b/stormpy/resources/pybind11/docs/advanced/pycpp/object.rst deleted file mode 100755 index 8fc165d16..000000000 --- a/stormpy/resources/pybind11/docs/advanced/pycpp/object.rst +++ /dev/null @@ -1,96 +0,0 @@ -Python types -############ - -Available wrappers -================== - -All major Python types are available as thin C++ wrapper classes. These -can also be used as function parameters -- see :ref:`python_objects_as_args`. - -Available types include :class:`handle`, :class:`object`, :class:`bool_`, -:class:`int_`, :class:`float_`, :class:`str`, :class:`bytes`, :class:`tuple`, -:class:`list`, :class:`dict`, :class:`slice`, :class:`none`, :class:`capsule`, -:class:`iterable`, :class:`iterator`, :class:`function`, :class:`buffer`, -:class:`array`, and :class:`array_t`. - -Casting back and forth -====================== - -In this kind of mixed code, it is often necessary to convert arbitrary C++ -types to Python, which can be done using :func:`py::cast`: - -.. code-block:: cpp - - MyClass *cls = ..; - py::object obj = py::cast(cls); - -The reverse direction uses the following syntax: - -.. code-block:: cpp - - py::object obj = ...; - MyClass *cls = obj.cast(); - -When conversion fails, both directions throw the exception :class:`cast_error`. - -Calling Python functions -======================== - -It is also possible to call python functions via ``operator()``. - -.. code-block:: cpp - - py::function f = <...>; - py::object result_py = f(1234, "hello", some_instance); - MyClass &result = result_py.cast(); - -Keyword arguments are also supported. In Python, there is the usual call syntax: - -.. code-block:: python - - def f(number, say, to): - ... # function code - - f(1234, say="hello", to=some_instance) # keyword call in Python - -In C++, the same call can be made using: - -.. code-block:: cpp - - using pybind11::literals; // to bring in the `_a` literal - f(1234, "say"_a="hello", "to"_a=some_instance); // keyword call in C++ - -Unpacking of ``*args`` and ``**kwargs`` is also possible and can be mixed with -other arguments: - -.. code-block:: cpp - - // * unpacking - py::tuple args = py::make_tuple(1234, "hello", some_instance); - f(*args); - - // ** unpacking - py::dict kwargs = py::dict("number"_a=1234, "say"_a="hello", "to"_a=some_instance); - f(**kwargs); - - // mixed keywords, * and ** unpacking - py::tuple args = py::make_tuple(1234); - py::dict kwargs = py::dict("to"_a=some_instance); - f(*args, "say"_a="hello", **kwargs); - -Generalized unpacking according to PEP448_ is also supported: - -.. code-block:: cpp - - py::dict kwargs1 = py::dict("number"_a=1234); - py::dict kwargs2 = py::dict("to"_a=some_instance); - f(**kwargs1, "say"_a="hello", **kwargs2); - -.. seealso:: - - The file :file:`tests/test_python_types.cpp` contains a complete - example that demonstrates passing native Python types in more detail. The - file :file:`tests/test_callbacks.cpp` presents a few examples of calling - Python functions from C++, including keywords arguments and unpacking. - -.. _PEP448: https://www.python.org/dev/peps/pep-0448/ diff --git a/stormpy/resources/pybind11/docs/advanced/pycpp/utilities.rst b/stormpy/resources/pybind11/docs/advanced/pycpp/utilities.rst deleted file mode 100755 index ba0dbef88..000000000 --- a/stormpy/resources/pybind11/docs/advanced/pycpp/utilities.rst +++ /dev/null @@ -1,57 +0,0 @@ -Utilities -######### - -Using Python's print function in C++ -==================================== - -The usual way to write output in C++ is using ``std::cout`` while in Python one -would use ``print``. Since these methods use different buffers, mixing them can -lead to output order issues. To resolve this, pybind11 modules can use the -:func:`py::print` function which writes to Python's ``sys.stdout`` for consistency. - -Python's ``print`` function is replicated in the C++ API including optional -keyword arguments ``sep``, ``end``, ``file``, ``flush``. Everything works as -expected in Python: - -.. code-block:: cpp - - py::print(1, 2.0, "three"); // 1 2.0 three - py::print(1, 2.0, "three", "sep"_a="-"); // 1-2.0-three - - auto args = py::make_tuple("unpacked", true); - py::print("->", *args, "end"_a="<-"); // -> unpacked True <- - -Evaluating Python expressions from strings and files -==================================================== - -pybind11 provides the :func:`eval` and :func:`eval_file` functions to evaluate -Python expressions and statements. The following example illustrates how they -can be used. - -Both functions accept a template parameter that describes how the argument -should be interpreted. Possible choices include ``eval_expr`` (isolated -expression), ``eval_single_statement`` (a single statement, return value is -always ``none``), and ``eval_statements`` (sequence of statements, return value -is always ``none``). - -.. code-block:: cpp - - // At beginning of file - #include - - ... - - // Evaluate in scope of main module - py::object scope = py::module::import("__main__").attr("__dict__"); - - // Evaluate an isolated expression - int result = py::eval("my_variable + 10", scope).cast(); - - // Evaluate a sequence of statements - py::eval( - "print('Hello')\n" - "print('world!');", - scope); - - // Evaluate the statements in an separate Python file on disk - py::eval_file("script.py", scope); diff --git a/stormpy/resources/pybind11/docs/advanced/smart_ptrs.rst b/stormpy/resources/pybind11/docs/advanced/smart_ptrs.rst deleted file mode 100755 index 6e8c9de36..000000000 --- a/stormpy/resources/pybind11/docs/advanced/smart_ptrs.rst +++ /dev/null @@ -1,145 +0,0 @@ -Smart pointers -############## - -std::unique_ptr -=============== - -Given a class ``Example`` with Python bindings, it's possible to return -instances wrapped in C++11 unique pointers, like so - -.. code-block:: cpp - - std::unique_ptr create_example() { return std::unique_ptr(new Example()); } - -.. code-block:: cpp - - m.def("create_example", &create_example); - -In other words, there is nothing special that needs to be done. While returning -unique pointers in this way is allowed, it is *illegal* to use them as function -arguments. For instance, the following function signature cannot be processed -by pybind11. - -.. code-block:: cpp - - void do_something_with_example(std::unique_ptr ex) { ... } - -The above signature would imply that Python needs to give up ownership of an -object that is passed to this function, which is generally not possible (for -instance, the object might be referenced elsewhere). - -std::shared_ptr -=============== - -The binding generator for classes, :class:`class_`, can be passed a template -type that denotes a special *holder* type that is used to manage references to -the object. If no such holder type template argument is given, the default for -a type named ``Type`` is ``std::unique_ptr``, which means that the object -is deallocated when Python's reference count goes to zero. - -It is possible to switch to other types of reference counting wrappers or smart -pointers, which is useful in codebases that rely on them. For instance, the -following snippet causes ``std::shared_ptr`` to be used instead. - -.. code-block:: cpp - - py::class_ /* <- holder type */> obj(m, "Example"); - -Note that any particular class can only be associated with a single holder type. - -One potential stumbling block when using holder types is that they need to be -applied consistently. Can you guess what's broken about the following binding -code? - -.. code-block:: cpp - - PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); - - class Child { }; - - class Parent { - public: - Parent() : child(std::make_shared()) { } - Child *get_child() { return child.get(); } /* Hint: ** DON'T DO THIS ** */ - private: - std::shared_ptr child; - }; - - PYBIND11_PLUGIN(example) { - py::module m("example"); - - py::class_>(m, "Child"); - - py::class_>(m, "Parent") - .def(py::init<>()) - .def("get_child", &Parent::get_child); - - return m.ptr(); - } - -The following Python code will cause undefined behavior (and likely a -segmentation fault). - -.. code-block:: python - - from example import Parent - print(Parent().get_child()) - -The problem is that ``Parent::get_child()`` returns a pointer to an instance of -``Child``, but the fact that this instance is already managed by -``std::shared_ptr<...>`` is lost when passing raw pointers. In this case, -pybind11 will create a second independent ``std::shared_ptr<...>`` that also -claims ownership of the pointer. In the end, the object will be freed **twice** -since these shared pointers have no way of knowing about each other. - -There are two ways to resolve this issue: - -1. For types that are managed by a smart pointer class, never use raw pointers - in function arguments or return values. In other words: always consistently - wrap pointers into their designated holder types (such as - ``std::shared_ptr<...>``). In this case, the signature of ``get_child()`` - should be modified as follows: - -.. code-block:: cpp - - std::shared_ptr get_child() { return child; } - -2. Adjust the definition of ``Child`` by specifying - ``std::enable_shared_from_this`` (see cppreference_ for details) as a - base class. This adds a small bit of information to ``Child`` that allows - pybind11 to realize that there is already an existing - ``std::shared_ptr<...>`` and communicate with it. In this case, the - declaration of ``Child`` should look as follows: - -.. _cppreference: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this - -.. code-block:: cpp - - class Child : public std::enable_shared_from_this { }; - -.. _smart_pointers: - -Custom smart pointers -===================== - -pybind11 supports ``std::unique_ptr`` and ``std::shared_ptr`` right out of the -box. For any other custom smart pointer, transparent conversions can be enabled -using a macro invocation similar to the following. It must be declared at the -level before any binding code: - -.. code-block:: cpp - - PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr); - -The first argument of :func:`PYBIND11_DECLARE_HOLDER_TYPE` should be a -placeholder name that is used as a template parameter of the second argument. -Thus, feel free to use any identifier, but use it consistently on both sides; -also, don't use the name of a type that already exists in your codebase. - -Please take a look at the :ref:`macro_notes` before using this feature. - -.. seealso:: - - The file :file:`tests/test_smart_ptr.cpp` contains a complete example - that demonstrates how to work with custom reference-counting holder types - in more detail. diff --git a/stormpy/resources/pybind11/docs/basics.rst b/stormpy/resources/pybind11/docs/basics.rst deleted file mode 100644 index 45272b7ed..000000000 --- a/stormpy/resources/pybind11/docs/basics.rst +++ /dev/null @@ -1,287 +0,0 @@ -.. _basics: - -First steps -########### - -This sections demonstrates the basic features of pybind11. Before getting -started, make sure that development environment is set up to compile the -included set of test cases. - - -Compiling the test cases -======================== - -Linux/MacOS ------------ - -On Linux you'll need to install the **python-dev** or **python3-dev** packages as -well as **cmake**. On Mac OS, the included python version works out of the box, -but **cmake** must still be installed. - -After installing the prerequisites, run - -.. code-block:: bash - - mkdir build - cd build - cmake .. - make pytest -j 4 - -The last line will both compile and run the tests. - -Windows -------- - -On Windows, only **Visual Studio 2015** and newer are supported since pybind11 relies -on various C++11 language features that break older versions of Visual Studio. - -To compile and run the tests: - -.. code-block:: batch - - mkdir build - cd build - cmake .. - cmake --build . --config Release --target pytest - -This will create a Visual Studio project, compile and run the target, all from the -command line. - -.. Note:: - - If all tests fail, make sure that the Python binary and the testcases are compiled - for the same processor type and bitness (i.e. either **i386** or **x86_64**). You - can specify **x86_64** as the target architecture for the generated Visual Studio - project using ``cmake -A x64 ..``. - -.. seealso:: - - Advanced users who are already familiar with Boost.Python may want to skip - the tutorial and look at the test cases in the :file:`tests` directory, - which exercise all features of pybind11. - -Header and namespace conventions -================================ - -For brevity, all code examples assume that the following two lines are present: - -.. code-block:: cpp - - #include - - namespace py = pybind11; - -Some features may require additional headers, but those will be specified as needed. - -Creating bindings for a simple function -======================================= - -Let's start by creating Python bindings for an extremely simple function, which -adds two numbers and returns their result: - -.. code-block:: cpp - - int add(int i, int j) { - return i + j; - } - -For simplicity [#f1]_, we'll put both this function and the binding code into -a file named :file:`example.cpp` with the following contents: - -.. code-block:: cpp - - #include - - int add(int i, int j) { - return i + j; - } - - namespace py = pybind11; - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - m.def("add", &add, "A function which adds two numbers"); - - return m.ptr(); - } - -.. [#f1] In practice, implementation and binding code will generally be located - in separate files. - -The :func:`PYBIND11_PLUGIN` macro creates a function that will be called when an -``import`` statement is issued from within Python. The next line creates a -module named ``example`` (with the supplied docstring). The method -:func:`module::def` generates binding code that exposes the -``add()`` function to Python. The last line returns the internal Python object -associated with ``m`` to the Python interpreter. - -.. note:: - - Notice how little code was needed to expose our function to Python: all - details regarding the function's parameters and return value were - automatically inferred using template metaprogramming. This overall - approach and the used syntax are borrowed from Boost.Python, though the - underlying implementation is very different. - -pybind11 is a header-only-library, hence it is not necessary to link against -any special libraries (other than Python itself). On Windows, use the CMake -build file discussed in section :ref:`cmake`. On Linux and Mac OS, the above -example can be compiled using the following command - -.. code-block:: bash - - $ c++ -O3 -shared -std=c++11 -I /include `python-config --cflags --ldflags` example.cpp -o example.so - -In general, it is advisable to include several additional build parameters -that can considerably reduce the size of the created binary. Refer to section -:ref:`cmake` for a detailed example of a suitable cross-platform CMake-based -build system. - -Assuming that the created file :file:`example.so` (:file:`example.pyd` on Windows) -is located in the current directory, the following interactive Python session -shows how to load and execute the example. - -.. code-block:: pycon - - $ python - Python 2.7.10 (default, Aug 22 2015, 20:33:39) - [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.1)] on darwin - Type "help", "copyright", "credits" or "license" for more information. - >>> import example - >>> example.add(1, 2) - 3L - >>> - -.. _keyword_args: - -Keyword arguments -================= - -With a simple modification code, it is possible to inform Python about the -names of the arguments ("i" and "j" in this case). - -.. code-block:: cpp - - m.def("add", &add, "A function which adds two numbers", - py::arg("i"), py::arg("j")); - -:class:`arg` is one of several special tag classes which can be used to pass -metadata into :func:`module::def`. With this modified binding code, we can now -call the function using keyword arguments, which is a more readable alternative -particularly for functions taking many parameters: - -.. code-block:: pycon - - >>> import example - >>> example.add(i=1, j=2) - 3L - -The keyword names also appear in the function signatures within the documentation. - -.. code-block:: pycon - - >>> help(example) - - .... - - FUNCTIONS - add(...) - Signature : (i: int, j: int) -> int - - A function which adds two numbers - -A shorter notation for named arguments is also available: - -.. code-block:: cpp - - // regular notation - m.def("add1", &add, py::arg("i"), py::arg("j")); - // shorthand - using namespace pybind11::literals; - m.def("add2", &add, "i"_a, "j"_a); - -The :var:`_a` suffix forms a C++11 literal which is equivalent to :class:`arg`. -Note that the literal operator must first be made visible with the directive -``using namespace pybind11::literals``. This does not bring in anything else -from the ``pybind11`` namespace except for literals. - -.. _default_args: - -Default arguments -================= - -Suppose now that the function to be bound has default arguments, e.g.: - -.. code-block:: cpp - - int add(int i = 1, int j = 2) { - return i + j; - } - -Unfortunately, pybind11 cannot automatically extract these parameters, since they -are not part of the function's type information. However, they are simple to specify -using an extension of :class:`arg`: - -.. code-block:: cpp - - m.def("add", &add, "A function which adds two numbers", - py::arg("i") = 1, py::arg("j") = 2); - -The default values also appear within the documentation. - -.. code-block:: pycon - - >>> help(example) - - .... - - FUNCTIONS - add(...) - Signature : (i: int = 1, j: int = 2) -> int - - A function which adds two numbers - -The shorthand notation is also available for default arguments: - -.. code-block:: cpp - - // regular notation - m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2); - // shorthand - m.def("add2", &add, "i"_a=1, "j"_a=2); - -Exporting variables -=================== - -To expose a value from C++, use the ``attr`` function to register it in a module -as shown below. Built-in types and general objects (more on that later) can be -converted using the function ``py::cast``. - -.. code-block:: cpp - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - m.attr("the_answer") = py::cast(42); - m.attr("what") = py::cast("World"); - return m.ptr(); - } - -These are then accessible from Python: - -.. code-block:: pycon - - >>> import example - >>> example.the_answer - 42 - >>> example.what - 'World' - -.. _supported_types: - -Supported data types -==================== - -A large number of data types are supported out of the box and can be used -seamlessly as functions arguments, return values or with ``py::cast`` in general. -For a full overview, see the :doc:`advanced/cast/index` section. diff --git a/stormpy/resources/pybind11/docs/benchmark.py b/stormpy/resources/pybind11/docs/benchmark.py deleted file mode 100644 index 6f02e92ff..000000000 --- a/stormpy/resources/pybind11/docs/benchmark.py +++ /dev/null @@ -1,90 +0,0 @@ -import random -import os -import time -import datetime as dt - -nfns = 4 # Functions per class -nargs = 4 # Arguments per function - - -def generate_dummy_code_pybind11(nclasses=10): - decl = "" - bindings = "" - - for cl in range(nclasses): - decl += "class cl%03i;\n" % cl - decl += '\n' - - for cl in range(nclasses): - decl += "class cl%03i {\n" % cl - decl += "public:\n" - bindings += ' py::class_(m, "cl%03i")\n' % (cl, cl) - for fn in range(nfns): - ret = random.randint(0, nclasses - 1) - params = [random.randint(0, nclasses - 1) for i in range(nargs)] - decl += " cl%03i *fn_%03i(" % (ret, fn) - decl += ", ".join("cl%03i *" % p for p in params) - decl += ");\n" - bindings += ' .def("fn_%03i", &cl%03i::fn_%03i)\n' % \ - (fn, cl, fn) - decl += "};\n\n" - bindings += ' ;\n' - - result = "#include \n\n" - result += "namespace py = pybind11;\n\n" - result += decl + '\n' - result += "PYBIND11_PLUGIN(example) {\n" - result += " py::module m(\"example\");" - result += bindings - result += " return m.ptr();" - result += "}" - return result - - -def generate_dummy_code_boost(nclasses=10): - decl = "" - bindings = "" - - for cl in range(nclasses): - decl += "class cl%03i;\n" % cl - decl += '\n' - - for cl in range(nclasses): - decl += "class cl%03i {\n" % cl - decl += "public:\n" - bindings += ' py::class_("cl%03i")\n' % (cl, cl) - for fn in range(nfns): - ret = random.randint(0, nclasses - 1) - params = [random.randint(0, nclasses - 1) for i in range(nargs)] - decl += " cl%03i *fn_%03i(" % (ret, fn) - decl += ", ".join("cl%03i *" % p for p in params) - decl += ");\n" - bindings += ' .def("fn_%03i", &cl%03i::fn_%03i, py::return_value_policy())\n' % \ - (fn, cl, fn) - decl += "};\n\n" - bindings += ' ;\n' - - result = "#include \n\n" - result += "namespace py = boost::python;\n\n" - result += decl + '\n' - result += "BOOST_PYTHON_MODULE(example) {\n" - result += bindings - result += "}" - return result - - -for codegen in [generate_dummy_code_pybind11, generate_dummy_code_boost]: - print ("{") - for i in range(0, 10): - nclasses = 2 ** i - with open("test.cpp", "w") as f: - f.write(codegen(nclasses)) - n1 = dt.datetime.now() - os.system("g++ -Os -shared -rdynamic -undefined dynamic_lookup " - "-fvisibility=hidden -std=c++14 test.cpp -I include " - "-I /System/Library/Frameworks/Python.framework/Headers -o test.so") - n2 = dt.datetime.now() - elapsed = (n2 - n1).total_seconds() - size = os.stat('test.so').st_size - print(" {%i, %f, %i}," % (nclasses * nfns, elapsed, size)) - print ("}") diff --git a/stormpy/resources/pybind11/docs/benchmark.rst b/stormpy/resources/pybind11/docs/benchmark.rst deleted file mode 100644 index 8babaa319..000000000 --- a/stormpy/resources/pybind11/docs/benchmark.rst +++ /dev/null @@ -1,99 +0,0 @@ -Benchmark -========= - -The following is the result of a synthetic benchmark comparing both compilation -time and module size of pybind11 against Boost.Python. A detailed report about a -Boost.Python to pybind11 conversion of a real project is available here: [#f1]_. - -.. [#f1] http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf - -Setup ------ - -A python script (see the ``docs/benchmark.py`` file) was used to generate a set -of files with dummy classes whose count increases for each successive benchmark -(between 1 and 2048 classes in powers of two). Each class has four methods with -a randomly generated signature with a return value and four arguments. (There -was no particular reason for this setup other than the desire to generate many -unique function signatures whose count could be controlled in a simple way.) - -Here is an example of the binding code for one class: - -.. code-block:: cpp - - ... - class cl034 { - public: - cl279 *fn_000(cl084 *, cl057 *, cl065 *, cl042 *); - cl025 *fn_001(cl098 *, cl262 *, cl414 *, cl121 *); - cl085 *fn_002(cl445 *, cl297 *, cl145 *, cl421 *); - cl470 *fn_003(cl200 *, cl323 *, cl332 *, cl492 *); - }; - ... - - PYBIND11_PLUGIN(example) { - py::module m("example"); - ... - py::class_(m, "cl034") - .def("fn_000", &cl034::fn_000) - .def("fn_001", &cl034::fn_001) - .def("fn_002", &cl034::fn_002) - .def("fn_003", &cl034::fn_003) - ... - return m.ptr(); - } - -The Boost.Python version looks almost identical except that a return value -policy had to be specified as an argument to ``def()``. For both libraries, -compilation was done with - -.. code-block:: bash - - Apple LLVM version 7.0.2 (clang-700.1.81) - -and the following compilation flags - -.. code-block:: bash - - g++ -Os -shared -rdynamic -undefined dynamic_lookup -fvisibility=hidden -std=c++14 - -Compilation time ----------------- - -The following log-log plot shows how the compilation time grows for an -increasing number of class and function declarations. pybind11 includes many -fewer headers, which initially leads to shorter compilation times, but the -performance is ultimately fairly similar (pybind11 is 19.8 seconds faster for -the largest largest file with 2048 classes and a total of 8192 methods -- a -modest **1.2x** speedup relative to Boost.Python, which required 116.35 -seconds). - -.. only:: not latex - - .. image:: pybind11_vs_boost_python1.svg - -.. only:: latex - - .. image:: pybind11_vs_boost_python1.png - -Module size ------------ - -Differences between the two libraries become much more pronounced when -considering the file size of the generated Python plugin: for the largest file, -the binary generated by Boost.Python required 16.8 MiB, which was **2.17 -times** / **9.1 megabytes** larger than the output generated by pybind11. For -very small inputs, Boost.Python has an edge in the plot below -- however, note -that it stores many definitions in an external library, whose size was not -included here, hence the comparison is slightly shifted in Boost.Python's -favor. - -.. only:: not latex - - .. image:: pybind11_vs_boost_python2.svg - -.. only:: latex - - .. image:: pybind11_vs_boost_python2.png - - diff --git a/stormpy/resources/pybind11/docs/changelog.rst b/stormpy/resources/pybind11/docs/changelog.rst deleted file mode 100644 index 15cf8d959..000000000 --- a/stormpy/resources/pybind11/docs/changelog.rst +++ /dev/null @@ -1,222 +0,0 @@ -.. _changelog: - -Changelog -######### - -Starting with version 1.8, pybind11 releases use a -[semantic versioning](http://semver.org) policy. - -Breaking changes queued for v2.0.0 (Not yet released) ------------------------------------------------------ -* Redesigned virtual call mechanism and user-facing syntax (see - https://github.com/pybind/pybind11/commit/86d825f3302701d81414ddd3d38bcd09433076bc) - -* Remove ``handle.call()`` method - -1.9.0 (Not yet released) ------------------------- -* Queued changes: map indexing suite, documentation for indexing suites. -* Mapping a stateless C++ function to Python and back is now "for free" (i.e. no call overheads) -* Support for translation of arbitrary C++ exceptions to Python counterparts -* Added ``eval`` and ``eval_file`` functions for evaluating expressions and - statements from a string or file -* eigen.h type converter fixed for non-contiguous arrays (e.g. slices) -* Print more informative error messages when ``make_tuple()`` or ``cast()`` fail -* ``std::enable_shared_from_this<>`` now also works for ``const`` values -* A return value policy can now be passed to ``handle::operator()`` -* ``make_iterator()`` improvements for better compatibility with various types - (now uses prefix increment operator); it now also accepts iterators with - different begin/end types as long as they are equality comparable. -* ``arg()`` now accepts a wider range of argument types for default values -* Added ``py::repr()`` function which is equivalent to Python's builtin ``repr()``. -* Added support for registering structured dtypes via ``PYBIND11_NUMPY_DTYPE()`` macro. -* Added ``PYBIND11_STR_TYPE`` macro which maps to the ``builtins.str`` type. -* Added a simplified ``buffer_info`` constructor for 1-dimensional buffers. -* Format descriptor strings should now be accessed via ``format_descriptor::format()`` - (for compatibility purposes, the old syntax ``format_descriptor::value`` will still - work for non-structured data types). -* Added a class wrapping NumPy array descriptors: ``dtype``. -* Added buffer/NumPy support for ``char[N]`` and ``std::array`` types. -* ``array`` gained new constructors accepting dtype objects. -* Added constructors for ``array`` and ``array_t`` explicitly accepting shape and - strides; if strides are not provided, they are deduced assuming C-contiguity. - Also added simplified constructors for 1-dimensional case. -* Added constructors for ``str`` from ``bytes`` and for ``bytes`` from ``str``. - This will do the UTF-8 decoding/encoding as required. -* Added constructors for ``str`` and ``bytes`` from zero-terminated char pointers, - and from char pointers and length. -* Added ``memoryview`` wrapper type which is constructible from ``buffer_info``. -* New syntax to call a Python function from C++ using keyword arguments and unpacking, - e.g. ``foo(1, 2, "z"_a=3)`` or ``bar(1, *args, "z"_a=3, **kwargs)``. -* Added ``py::print()`` function which replicates Python's API and writes to Python's - ``sys.stdout`` by default (as opposed to C's ``stdout`` like ``std::cout``). -* Added ``py::dict`` keyword constructor:``auto d = dict("number"_a=42, "name"_a="World");`` -* Added ``py::str::format()`` method and ``_s`` literal: - ``py::str s = "1 + 2 = {}"_s.format(3);`` -* Attribute and item accessors now have a more complete interface which makes it possible - to chain attributes ``obj.attr("a")[key].attr("b").attr("method")(1, 2, 3)```. -* Added built-in support for ``std::shared_ptr`` holder type. There is no more need - to do it manually via ``PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr)``. -* Default return values policy changes: non-static properties now use ``reference_internal`` - and static properties use ``reference`` (previous default was ``automatic``, i.e. ``copy``). -* Support for ``std::experimental::optional`` and ``std::optional`` (C++17). -* Various minor improvements of library internals (no user-visible changes) - -1.8.1 (July 12, 2016) ----------------------- -* Fixed a rare but potentially very severe issue when the garbage collector ran - during pybind11 type creation. - -1.8.0 (June 14, 2016) ----------------------- -* Redesigned CMake build system which exports a convenient - ``pybind11_add_module`` function to parent projects. -* ``std::vector<>`` type bindings analogous to Boost.Python's ``indexing_suite`` -* Transparent conversion of sparse and dense Eigen matrices and vectors (``eigen.h``) -* Added an ``ExtraFlags`` template argument to the NumPy ``array_t<>`` wrapper - to disable an enforced cast that may lose precision, e.g. to create overloads - for different precisions and complex vs real-valued matrices. -* Prevent implicit conversion of floating point values to integral types in - function arguments -* Fixed incorrect default return value policy for functions returning a shared - pointer -* Don't allow registering a type via ``class_`` twice -* Don't allow casting a ``None`` value into a C++ lvalue reference -* Fixed a crash in ``enum_::operator==`` that was triggered by the ``help()`` command -* Improved detection of whether or not custom C++ types can be copy/move-constructed -* Extended ``str`` type to also work with ``bytes`` instances -* Added a ``"name"_a`` user defined string literal that is equivalent to ``py::arg("name")``. -* When specifying function arguments via ``py::arg``, the test that verifies - the number of arguments now runs at compile time. -* Added ``[[noreturn]]`` attribute to ``pybind11_fail()`` to quench some - compiler warnings -* List function arguments in exception text when the dispatch code cannot find - a matching overload -* Added ``PYBIND11_OVERLOAD_NAME`` and ``PYBIND11_OVERLOAD_PURE_NAME`` macros which - can be used to override virtual methods whose name differs in C++ and Python - (e.g. ``__call__`` and ``operator()``) -* Various minor ``iterator`` and ``make_iterator()`` improvements -* Transparently support ``__bool__`` on Python 2.x and Python 3.x -* Fixed issue with destructor of unpickled object not being called -* Minor CMake build system improvements on Windows -* New ``pybind11::args`` and ``pybind11::kwargs`` types to create functions which - take an arbitrary number of arguments and keyword arguments -* New syntax to call a Python function from C++ using ``*args`` and ``*kwargs`` -* The functions ``def_property_*`` now correctly process docstring arguments (these - formerly caused a segmentation fault) -* Many ``mkdoc.py`` improvements (enumerations, template arguments, ``DOC()`` - macro accepts more arguments) -* Cygwin support -* Documentation improvements (pickling support, ``keep_alive``, macro usage) - -1.7 (April 30, 2016) ----------------------- -* Added a new ``move`` return value policy that triggers C++11 move semantics. - The automatic return value policy falls back to this case whenever a rvalue - reference is encountered -* Significantly more general GIL state routines that are used instead of - Python's troublesome ``PyGILState_Ensure`` and ``PyGILState_Release`` API -* Redesign of opaque types that drastically simplifies their usage -* Extended ability to pass values of type ``[const] void *`` -* ``keep_alive`` fix: don't fail when there is no patient -* ``functional.h``: acquire the GIL before calling a Python function -* Added Python RAII type wrappers ``none`` and ``iterable`` -* Added ``*args`` and ``*kwargs`` pass-through parameters to - ``pybind11.get_include()`` function -* Iterator improvements and fixes -* Documentation on return value policies and opaque types improved - -1.6 (April 30, 2016) ----------------------- -* Skipped due to upload to PyPI gone wrong and inability to recover - (https://github.com/pypa/packaging-problems/issues/74) - -1.5 (April 21, 2016) ----------------------- -* For polymorphic types, use RTTI to try to return the closest type registered with pybind11 -* Pickling support for serializing and unserializing C++ instances to a byte stream in Python -* Added a convenience routine ``make_iterator()`` which turns a range indicated - by a pair of C++ iterators into a iterable Python object -* Added ``len()`` and a variadic ``make_tuple()`` function -* Addressed a rare issue that could confuse the current virtual function - dispatcher and another that could lead to crashes in multi-threaded - applications -* Added a ``get_include()`` function to the Python module that returns the path - of the directory containing the installed pybind11 header files -* Documentation improvements: import issues, symbol visibility, pickling, limitations -* Added casting support for ``std::reference_wrapper<>`` - -1.4 (April 7, 2016) --------------------------- -* Transparent type conversion for ``std::wstring`` and ``wchar_t`` -* Allow passing ``nullptr``-valued strings -* Transparent passing of ``void *`` pointers using capsules -* Transparent support for returning values wrapped in ``std::unique_ptr<>`` -* Improved docstring generation for compatibility with Sphinx -* Nicer debug error message when default parameter construction fails -* Support for "opaque" types that bypass the transparent conversion layer for STL containers -* Redesigned type casting interface to avoid ambiguities that could occasionally cause compiler errors -* Redesigned property implementation; fixes crashes due to an unfortunate default return value policy -* Anaconda package generation support - -1.3 (March 8, 2016) --------------------------- - -* Added support for the Intel C++ compiler (v15+) -* Added support for the STL unordered set/map data structures -* Added support for the STL linked list data structure -* NumPy-style broadcasting support in ``pybind11::vectorize`` -* pybind11 now displays more verbose error messages when ``arg::operator=()`` fails -* pybind11 internal data structures now live in a version-dependent namespace to avoid ABI issues -* Many, many bugfixes involving corner cases and advanced usage - -1.2 (February 7, 2016) --------------------------- - -* Optional: efficient generation of function signatures at compile time using C++14 -* Switched to a simpler and more general way of dealing with function default - arguments. Unused keyword arguments in function calls are now detected and - cause errors as expected -* New ``keep_alive`` call policy analogous to Boost.Python's ``with_custodian_and_ward`` -* New ``pybind11::base<>`` attribute to indicate a subclass relationship -* Improved interface for RAII type wrappers in ``pytypes.h`` -* Use RAII type wrappers consistently within pybind11 itself. This - fixes various potential refcount leaks when exceptions occur -* Added new ``bytes`` RAII type wrapper (maps to ``string`` in Python 2.7) -* Made handle and related RAII classes const correct, using them more - consistently everywhere now -* Got rid of the ugly ``__pybind11__`` attributes on the Python side---they are - now stored in a C++ hash table that is not visible in Python -* Fixed refcount leaks involving NumPy arrays and bound functions -* Vastly improved handling of shared/smart pointers -* Removed an unnecessary copy operation in ``pybind11::vectorize`` -* Fixed naming clashes when both pybind11 and NumPy headers are included -* Added conversions for additional exception types -* Documentation improvements (using multiple extension modules, smart pointers, - other minor clarifications) -* unified infrastructure for parsing variadic arguments in ``class_`` and cpp_function -* Fixed license text (was: ZLIB, should have been: 3-clause BSD) -* Python 3.2 compatibility -* Fixed remaining issues when accessing types in another plugin module -* Added enum comparison and casting methods -* Improved SFINAE-based detection of whether types are copy-constructible -* Eliminated many warnings about unused variables and the use of ``offsetof()`` -* Support for ``std::array<>`` conversions - -1.1 (December 7, 2015) --------------------------- - -* Documentation improvements (GIL, wrapping functions, casting, fixed many typos) -* Generalized conversion of integer types -* Improved support for casting function objects -* Improved support for ``std::shared_ptr<>`` conversions -* Initial support for ``std::set<>`` conversions -* Fixed type resolution issue for types defined in a separate plugin module -* Cmake build system improvements -* Factored out generic functionality to non-templated code (smaller code size) -* Added a code size / compile time benchmark vs Boost.Python -* Added an appveyor CI script - -1.0 (October 15, 2015) ------------------------- -* Initial release diff --git a/stormpy/resources/pybind11/docs/classes.rst b/stormpy/resources/pybind11/docs/classes.rst deleted file mode 100644 index 3e8f2ee97..000000000 --- a/stormpy/resources/pybind11/docs/classes.rst +++ /dev/null @@ -1,410 +0,0 @@ -.. _classes: - -Object-oriented code -#################### - -Creating bindings for a custom type -=================================== - -Let's now look at a more complex example where we'll create bindings for a -custom C++ data structure named ``Pet``. Its definition is given below: - -.. code-block:: cpp - - struct Pet { - Pet(const std::string &name) : name(name) { } - void setName(const std::string &name_) { name = name_; } - const std::string &getName() const { return name; } - - std::string name; - }; - -The binding code for ``Pet`` looks as follows: - -.. code-block:: cpp - - #include - - namespace py = pybind11; - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - - py::class_(m, "Pet") - .def(py::init()) - .def("setName", &Pet::setName) - .def("getName", &Pet::getName); - - return m.ptr(); - } - -:class:`class_` creates bindings for a C++ `class` or `struct`-style data -structure. :func:`init` is a convenience function that takes the types of a -constructor's parameters as template arguments and wraps the corresponding -constructor (see the :ref:`custom_constructors` section for details). An -interactive Python session demonstrating this example is shown below: - -.. code-block:: pycon - - % python - >>> import example - >>> p = example.Pet('Molly') - >>> print(p) - - >>> p.getName() - u'Molly' - >>> p.setName('Charly') - >>> p.getName() - u'Charly' - -.. seealso:: - - Static member functions can be bound in the same way using - :func:`class_::def_static`. - -Keyword and default arguments -============================= -It is possible to specify keyword and default arguments using the syntax -discussed in the previous chapter. Refer to the sections :ref:`keyword_args` -and :ref:`default_args` for details. - -Binding lambda functions -======================== - -Note how ``print(p)`` produced a rather useless summary of our data structure in the example above: - -.. code-block:: pycon - - >>> print(p) - - -To address this, we could bind an utility function that returns a human-readable -summary to the special method slot named ``__repr__``. Unfortunately, there is no -suitable functionality in the ``Pet`` data structure, and it would be nice if -we did not have to change it. This can easily be accomplished by binding a -Lambda function instead: - -.. code-block:: cpp - - py::class_(m, "Pet") - .def(py::init()) - .def("setName", &Pet::setName) - .def("getName", &Pet::getName) - .def("__repr__", - [](const Pet &a) { - return ""; - } - ); - -Both stateless [#f1]_ and stateful lambda closures are supported by pybind11. -With the above change, the same Python code now produces the following output: - -.. code-block:: pycon - - >>> print(p) - - -.. _properties: - -Instance and static fields -========================== - -We can also directly expose the ``name`` field using the -:func:`class_::def_readwrite` method. A similar :func:`class_::def_readonly` -method also exists for ``const`` fields. - -.. code-block:: cpp - - py::class_(m, "Pet") - .def(py::init()) - .def_readwrite("name", &Pet::name) - // ... remainder ... - -This makes it possible to write - -.. code-block:: pycon - - >>> p = example.Pet('Molly') - >>> p.name - u'Molly' - >>> p.name = 'Charly' - >>> p.name - u'Charly' - -Now suppose that ``Pet::name`` was a private internal variable -that can only be accessed via setters and getters. - -.. code-block:: cpp - - class Pet { - public: - Pet(const std::string &name) : name(name) { } - void setName(const std::string &name_) { name = name_; } - const std::string &getName() const { return name; } - private: - std::string name; - }; - -In this case, the method :func:`class_::def_property` -(:func:`class_::def_property_readonly` for read-only data) can be used to -provide a field-like interface within Python that will transparently call -the setter and getter functions: - -.. code-block:: cpp - - py::class_(m, "Pet") - .def(py::init()) - .def_property("name", &Pet::getName, &Pet::setName) - // ... remainder ... - -.. seealso:: - - Similar functions :func:`class_::def_readwrite_static`, - :func:`class_::def_readonly_static` :func:`class_::def_property_static`, - and :func:`class_::def_property_readonly_static` are provided for binding - static variables and properties. Please also see the section on - :ref:`static_properties` in the advanced part of the documentation. - -Dynamic attributes -================== - -Native Python classes can pick up new attributes dynamically: - -.. code-block:: pycon - - >>> class Pet: - ... name = 'Molly' - ... - >>> p = Pet() - >>> p.name = 'Charly' # overwrite existing - >>> p.age = 2 # dynamically add a new attribute - -By default, classes exported from C++ do not support this and the only writable -attributes are the ones explicitly defined using :func:`class_::def_readwrite` -or :func:`class_::def_property`. - -.. code-block:: cpp - - py::class_(m, "Pet") - .def(py::init<>()) - .def_readwrite("name", &Pet::name); - -Trying to set any other attribute results in an error: - -.. code-block:: pycon - - >>> p = example.Pet() - >>> p.name = 'Charly' # OK, attribute defined in C++ - >>> p.age = 2 # fail - AttributeError: 'Pet' object has no attribute 'age' - -To enable dynamic attributes for C++ classes, the :class:`py::dynamic_attr` tag -must be added to the :class:`py::class_` constructor: - -.. code-block:: cpp - - py::class_(m, "Pet", py::dynamic_attr()) - .def(py::init<>()) - .def_readwrite("name", &Pet::name); - -Now everything works as expected: - -.. code-block:: pycon - - >>> p = example.Pet() - >>> p.name = 'Charly' # OK, overwrite value in C++ - >>> p.age = 2 # OK, dynamically add a new attribute - >>> p.__dict__ # just like a native Python class - {'age': 2} - -Note that there is a small runtime cost for a class with dynamic attributes. -Not only because of the addition of a ``__dict__``, but also because of more -expensive garbage collection tracking which must be activated to resolve -possible circular references. Native Python classes incur this same cost by -default, so this is not anything to worry about. By default, pybind11 classes -are more efficient than native Python classes. Enabling dynamic attributes -just brings them on par. - -.. _inheritance: - -Inheritance -=========== - -Suppose now that the example consists of two data structures with an -inheritance relationship: - -.. code-block:: cpp - - struct Pet { - Pet(const std::string &name) : name(name) { } - std::string name; - }; - - struct Dog : Pet { - Dog(const std::string &name) : Pet(name) { } - std::string bark() const { return "woof!"; } - }; - -There are two different ways of indicating a hierarchical relationship to -pybind11: the first specifies the C++ base class as an extra template -parameter of the :class:`class_`: - -.. code-block:: cpp - - py::class_(m, "Pet") - .def(py::init()) - .def_readwrite("name", &Pet::name); - - // Method 1: template parameter: - py::class_(m, "Dog") - .def(py::init()) - .def("bark", &Dog::bark); - -Alternatively, we can also assign a name to the previously bound ``Pet`` -:class:`class_` object and reference it when binding the ``Dog`` class: - -.. code-block:: cpp - - py::class_ pet(m, "Pet"); - pet.def(py::init()) - .def_readwrite("name", &Pet::name); - - // Method 2: pass parent class_ object: - py::class_(m, "Dog", pet /* <- specify Python parent type */) - .def(py::init()) - .def("bark", &Dog::bark); - -Functionality-wise, both approaches are equivalent. Afterwards, instances will -expose fields and methods of both types: - -.. code-block:: pycon - - >>> p = example.Dog('Molly') - >>> p.name - u'Molly' - >>> p.bark() - u'woof!' - -Overloaded methods -================== - -Sometimes there are several overloaded C++ methods with the same name taking -different kinds of input arguments: - -.. code-block:: cpp - - struct Pet { - Pet(const std::string &name, int age) : name(name), age(age) { } - - void set(int age) { age = age; } - void set(const std::string &name) { name = name; } - - std::string name; - int age; - }; - -Attempting to bind ``Pet::set`` will cause an error since the compiler does not -know which method the user intended to select. We can disambiguate by casting -them to function pointers. Binding multiple functions to the same Python name -automatically creates a chain of function overloads that will be tried in -sequence. - -.. code-block:: cpp - - py::class_(m, "Pet") - .def(py::init()) - .def("set", (void (Pet::*)(int)) &Pet::set, "Set the pet's age") - .def("set", (void (Pet::*)(const std::string &)) &Pet::set, "Set the pet's name"); - -The overload signatures are also visible in the method's docstring: - -.. code-block:: pycon - - >>> help(example.Pet) - - class Pet(__builtin__.object) - | Methods defined here: - | - | __init__(...) - | Signature : (Pet, str, int) -> NoneType - | - | set(...) - | 1. Signature : (Pet, int) -> NoneType - | - | Set the pet's age - | - | 2. Signature : (Pet, str) -> NoneType - | - | Set the pet's name - -.. note:: - - To define multiple overloaded constructors, simply declare one after the - other using the ``.def(py::init<...>())`` syntax. The existing machinery - for specifying keyword and default arguments also works. - -Enumerations and internal types -=============================== - -Let's now suppose that the example class contains an internal enumeration type, -e.g.: - -.. code-block:: cpp - - struct Pet { - enum Kind { - Dog = 0, - Cat - }; - - Pet(const std::string &name, Kind type) : name(name), type(type) { } - - std::string name; - Kind type; - }; - -The binding code for this example looks as follows: - -.. code-block:: cpp - - py::class_ pet(m, "Pet"); - - pet.def(py::init()) - .def_readwrite("name", &Pet::name) - .def_readwrite("type", &Pet::type); - - py::enum_(pet, "Kind") - .value("Dog", Pet::Kind::Dog) - .value("Cat", Pet::Kind::Cat) - .export_values(); - -To ensure that the ``Kind`` type is created within the scope of ``Pet``, the -``pet`` :class:`class_` instance must be supplied to the :class:`enum_`. -constructor. The :func:`enum_::export_values` function exports the enum entries -into the parent scope, which should be skipped for newer C++11-style strongly -typed enums. - -.. code-block:: pycon - - >>> p = Pet('Lucy', Pet.Cat) - >>> p.type - Kind.Cat - >>> int(p.type) - 1L - - -.. note:: - - When the special tag ``py::arithmetic()`` is specified to the ``enum_`` - constructor, pybind11 creates an enumeration that also supports rudimentary - arithmetic and bit-level operations like comparisons, and, or, xor, negation, - etc. - - .. code-block:: cpp - - py::enum_(pet, "Kind", py::arithmetic()) - ... - - By default, these are omitted to conserve space. - -.. [#f1] Stateless closures are those with an empty pair of brackets ``[]`` as the capture object. diff --git a/stormpy/resources/pybind11/docs/compiling.rst b/stormpy/resources/pybind11/docs/compiling.rst deleted file mode 100644 index 30cd83b79..000000000 --- a/stormpy/resources/pybind11/docs/compiling.rst +++ /dev/null @@ -1,53 +0,0 @@ -Build systems -############# - -Building with setuptools -======================== - -For projects on PyPI, building with setuptools is the way to go. Sylvain Corlay -has kindly provided an example project which shows how to set up everything, -including automatic generation of documentation using Sphinx. Please refer to -the [python_example]_ repository. - -.. [python_example] https://github.com/pybind/python_example - -Building with cppimport -======================== - - cppimport is a small Python import hook that determines whether there is a C++ - source file whose name matches the requested module. If there is, the file is - compiled as a Python extension using pybind11 and placed in the same folder as - the C++ source file. Python is then able to find the module and load it. - -.. [cppimport] https://github.com/tbenthompson/cppimport - -.. _cmake: - -Building with CMake -=================== - -For C++ codebases that have an existing CMake-based build system, a Python -extension module can be created with just a few lines of code: - -.. code-block:: cmake - - cmake_minimum_required(VERSION 2.8.12) - project(example) - - add_subdirectory(pybind11) - pybind11_add_module(example example.cpp) - -This assumes that the pybind11 repository is located in a subdirectory named -:file:`pybind11` and that the code is located in a file named :file:`example.cpp`. -The CMake command ``add_subdirectory`` will import a function with the signature -``pybind11_add_module( source1 [source2 ...])``. It will take care of all -the details needed to build a Python extension module on any platform. - -The target Python version can be selected by setting the ``PYBIND11_PYTHON_VERSION`` -variable before adding the pybind11 subdirectory. Alternatively, an exact Python -installation can be specified by setting ``PYTHON_EXECUTABLE``. - -A working sample project, including a way to invoke CMake from :file:`setup.py` for -PyPI integration, can be found in the [cmake_example]_ repository. - -.. [cmake_example] https://github.com/pybind/cmake_example diff --git a/stormpy/resources/pybind11/docs/conf.py b/stormpy/resources/pybind11/docs/conf.py deleted file mode 100644 index 69f0cb337..000000000 --- a/stormpy/resources/pybind11/docs/conf.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# pybind11 documentation build configuration file, created by -# sphinx-quickstart on Sun Oct 11 19:23:48 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os -import shlex - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['.templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'pybind11' -copyright = '2015, Wenzel Jakob' -author = 'Wenzel Jakob' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.9' -# The full version, including alpha/beta/rc tags. -release = '1.9.dev0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['.build', 'release.rst'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -#pygments_style = 'monokai' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. - -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' - -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - - html_context = { - 'css_files': [ - '_static/theme_overrides.css' - ] - } -else: - html_context = { - 'css_files': [ - '//media.readthedocs.org/css/sphinx_rtd_theme.css', - '//media.readthedocs.org/css/readthedocs-doc-embed.css', - '_static/theme_overrides.css' - ] - } - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'pybind11doc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -'preamble': '\DeclareUnicodeCharacter{00A0}{}', - -# Latex figure (float) alignment -#'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'pybind11.tex', 'pybind11 Documentation', - 'Wenzel Jakob', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = 'pybind11-logo.png' - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'pybind11', 'pybind11 Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'pybind11', 'pybind11 Documentation', - author, 'pybind11', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - -primary_domain = 'cpp' -highlight_language = 'cpp' diff --git a/stormpy/resources/pybind11/docs/faq.rst b/stormpy/resources/pybind11/docs/faq.rst deleted file mode 100644 index 7f9bd35b4..000000000 --- a/stormpy/resources/pybind11/docs/faq.rst +++ /dev/null @@ -1,251 +0,0 @@ -Frequently asked questions -########################## - -"ImportError: dynamic module does not define init function" -=========================================================== - -1. Make sure that the name specified in ``pybind::module`` and - ``PYBIND11_PLUGIN`` is consistent and identical to the filename of the - extension library. The latter should not contain any extra prefixes (e.g. - ``test.so`` instead of ``libtest.so``). - -2. If the above did not fix your issue, then you are likely using an - incompatible version of Python (for instance, the extension library was - compiled against Python 2, while the interpreter is running on top of some - version of Python 3, or vice versa) - -"Symbol not found: ``__Py_ZeroStruct`` / ``_PyInstanceMethod_Type``" -======================================================================== - -See item 2 of the first answer. - -"SystemError: dynamic module not initialized properly" -====================================================== - -See item 2 of the first answer. - -The Python interpreter immediately crashes when importing my module -=================================================================== - -See item 2 of the first answer. - -CMake doesn't detect the right Python version -============================================= - -The CMake-based build system will try to automatically detect the installed -version of Python and link against that. When this fails, or when there are -multiple versions of Python and it finds the wrong one, delete -``CMakeCache.txt`` and then invoke CMake as follows: - -.. code-block:: bash - - cmake -DPYTHON_EXECUTABLE:FILEPATH= . - -Limitations involving reference arguments -========================================= - -In C++, it's fairly common to pass arguments using mutable references or -mutable pointers, which allows both read and write access to the value -supplied by the caller. This is sometimes done for efficiency reasons, or to -realize functions that have multiple return values. Here are two very basic -examples: - -.. code-block:: cpp - - void increment(int &i) { i++; } - void increment_ptr(int *i) { (*i)++; } - -In Python, all arguments are passed by reference, so there is no general -issue in binding such code from Python. - -However, certain basic Python types (like ``str``, ``int``, ``bool``, -``float``, etc.) are **immutable**. This means that the following attempt -to port the function to Python doesn't have the same effect on the value -provided by the caller -- in fact, it does nothing at all. - -.. code-block:: python - - def increment(i): - i += 1 # nope.. - -pybind11 is also affected by such language-level conventions, which means that -binding ``increment`` or ``increment_ptr`` will also create Python functions -that don't modify their arguments. - -Although inconvenient, one workaround is to encapsulate the immutable types in -a custom type that does allow modifications. - -An other alternative involves binding a small wrapper lambda function that -returns a tuple with all output arguments (see the remainder of the -documentation for examples on binding lambda functions). An example: - -.. code-block:: cpp - - int foo(int &i) { i++; return 123; } - -and the binding code - -.. code-block:: cpp - - m.def("foo", [](int i) { int rv = foo(i); return std::make_tuple(rv, i); }); - - -How can I reduce the build time? -================================ - -It's good practice to split binding code over multiple files, as in the -following example: - -:file:`example.cpp`: - -.. code-block:: cpp - - void init_ex1(py::module &); - void init_ex2(py::module &); - /* ... */ - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind example plugin"); - - init_ex1(m); - init_ex2(m); - /* ... */ - - return m.ptr(); - } - -:file:`ex1.cpp`: - -.. code-block:: cpp - - void init_ex1(py::module &m) { - m.def("add", [](int a, int b) { return a + b; }); - } - -:file:`ex2.cpp`: - -.. code-block:: cpp - - void init_ex1(py::module &m) { - m.def("sub", [](int a, int b) { return a - b; }); - } - -:command:`python`: - -.. code-block:: pycon - - >>> import example - >>> example.add(1, 2) - 3 - >>> example.sub(1, 1) - 0 - -As shown above, the various ``init_ex`` functions should be contained in -separate files that can be compiled independently from one another, and then -linked together into the same final shared object. Following this approach -will: - -1. reduce memory requirements per compilation unit. - -2. enable parallel builds (if desired). - -3. allow for faster incremental builds. For instance, when a single class - definition is changed, only a subset of the binding code will generally need - to be recompiled. - -"recursive template instantiation exceeded maximum depth of 256" -================================================================ - -If you receive an error about excessive recursive template evaluation, try -specifying a larger value, e.g. ``-ftemplate-depth=1024`` on GCC/Clang. The -culprit is generally the generation of function signatures at compile time -using C++14 template metaprogramming. - - -How can I create smaller binaries? -================================== - -To do its job, pybind11 extensively relies on a programming technique known as -*template metaprogramming*, which is a way of performing computation at compile -time using type information. Template metaprogamming usually instantiates code -involving significant numbers of deeply nested types that are either completely -removed or reduced to just a few instructions during the compiler's optimization -phase. However, due to the nested nature of these types, the resulting symbol -names in the compiled extension library can be extremely long. For instance, -the included test suite contains the following symbol: - -.. only:: html - - .. code-block:: none - - _​_​Z​N​8​p​y​b​i​n​d​1​1​1​2​c​p​p​_​f​u​n​c​t​i​o​n​C​1​I​v​8​E​x​a​m​p​l​e​2​J​R​N​S​t​3​_​_​1​6​v​e​c​t​o​r​I​N​S​3​_​1​2​b​a​s​i​c​_​s​t​r​i​n​g​I​w​N​S​3​_​1​1​c​h​a​r​_​t​r​a​i​t​s​I​w​E​E​N​S​3​_​9​a​l​l​o​c​a​t​o​r​I​w​E​E​E​E​N​S​8​_​I​S​A​_​E​E​E​E​E​J​N​S​_​4​n​a​m​e​E​N​S​_​7​s​i​b​l​i​n​g​E​N​S​_​9​i​s​_​m​e​t​h​o​d​E​A​2​8​_​c​E​E​E​M​T​0​_​F​T​_​D​p​T​1​_​E​D​p​R​K​T​2​_ - -.. only:: not html - - .. code-block:: cpp - - __ZN8pybind1112cpp_functionC1Iv8Example2JRNSt3__16vectorINS3_12basic_stringIwNS3_11char_traitsIwEENS3_9allocatorIwEEEENS8_ISA_EEEEEJNS_4nameENS_7siblingENS_9is_methodEA28_cEEEMT0_FT_DpT1_EDpRKT2_ - -which is the mangled form of the following function type: - -.. code-block:: cpp - - pybind11::cpp_function::cpp_function, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > >&, pybind11::name, pybind11::sibling, pybind11::is_method, char [28]>(void (Example2::*)(std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > >&), pybind11::name const&, pybind11::sibling const&, pybind11::is_method const&, char const (&) [28]) - -The memory needed to store just the mangled name of this function (196 bytes) -is larger than the actual piece of code (111 bytes) it represents! On the other -hand, it's silly to even give this function a name -- after all, it's just a -tiny cog in a bigger piece of machinery that is not exposed to the outside -world. So we'll generally only want to export symbols for those functions which -are actually called from the outside. - -This can be achieved by specifying the parameter ``-fvisibility=hidden`` to GCC -and Clang, which sets the default symbol visibility to *hidden*. It's best to -do this only for release builds, since the symbol names can be helpful in -debugging sessions. On Visual Studio, symbols are already hidden by default, so -nothing needs to be done there. Needless to say, this has a tremendous impact -on the final binary size of the resulting extension library. - -Another aspect that can require a fair bit of code are function signature -descriptions. pybind11 automatically generates human-readable function -signatures for docstrings, e.g.: - -.. code-block:: none - - | __init__(...) - | __init__(*args, **kwargs) - | Overloaded function. - | - | 1. __init__(example.Example1) -> NoneType - | - | Docstring for overload #1 goes here - | - | 2. __init__(example.Example1, int) -> NoneType - | - | Docstring for overload #2 goes here - | - | 3. __init__(example.Example1, example.Example1) -> NoneType - | - | Docstring for overload #3 goes here - - -In C++11 mode, these are generated at run time using string concatenation, -which can amount to 10-20% of the size of the resulting binary. If you can, -enable C++14 language features (using ``-std=c++14`` for GCC/Clang), in which -case signatures are efficiently pre-generated at compile time. Unfortunately, -Visual Studio's C++14 support (``constexpr``) is not good enough as of April -2016, so it always uses the more expensive run-time approach. - -Working with ancient Visual Studio 2009 builds on Windows -========================================================= - -The official Windows distributions of Python are compiled using truly -ancient versions of Visual Studio that lack good C++11 support. Some users -implicitly assume that it would be impossible to load a plugin built with -Visual Studio 2015 into a Python distribution that was compiled using Visual -Studio 2009. However, no such issue exists: it's perfectly legitimate to -interface DLLs that are built with different compilers and/or C libraries. -Common gotchas to watch out for involve not ``free()``-ing memory region -that that were ``malloc()``-ed in another shared library, using data -structures with incompatible ABIs, and so on. pybind11 is very careful not -to make these types of mistakes. diff --git a/stormpy/resources/pybind11/docs/index.rst b/stormpy/resources/pybind11/docs/index.rst deleted file mode 100644 index cedf65209..000000000 --- a/stormpy/resources/pybind11/docs/index.rst +++ /dev/null @@ -1,45 +0,0 @@ -.. only: not latex - - .. image:: pybind11-logo.png - -pybind11 --- Seamless operability between C++11 and Python -========================================================== - -.. only: not latex - - Contents: - -.. toctree:: - :maxdepth: 1 - - intro - changelog - -.. toctree:: - :caption: The Basics - :maxdepth: 2 - - basics - classes - compiling - -.. toctree:: - :caption: Advanced Topics - :maxdepth: 2 - - advanced/functions - advanced/classes - advanced/exceptions - advanced/smart_ptrs - advanced/cast/index - advanced/pycpp/index - advanced/misc - -.. toctree:: - :caption: Extra Information - :maxdepth: 1 - - faq - benchmark - limitations - reference diff --git a/stormpy/resources/pybind11/docs/intro.rst b/stormpy/resources/pybind11/docs/intro.rst deleted file mode 100644 index 429a01cdd..000000000 --- a/stormpy/resources/pybind11/docs/intro.rst +++ /dev/null @@ -1,93 +0,0 @@ -.. image:: pybind11-logo.png - -About this project -================== -**pybind11** is a lightweight header-only library that exposes C++ types in Python -and vice versa, mainly to create Python bindings of existing C++ code. Its -goals and syntax are similar to the excellent `Boost.Python`_ library by David -Abrahams: to minimize boilerplate code in traditional extension modules by -inferring type information using compile-time introspection. - -.. _Boost.Python: http://www.boost.org/doc/libs/release/libs/python/doc/index.html - -The main issue with Boost.Python—and the reason for creating such a similar -project—is Boost. Boost is an enormously large and complex suite of utility -libraries that works with almost every C++ compiler in existence. This -compatibility has its cost: arcane template tricks and workarounds are -necessary to support the oldest and buggiest of compiler specimens. Now that -C++11-compatible compilers are widely available, this heavy machinery has -become an excessively large and unnecessary dependency. - -Think of this library as a tiny self-contained version of Boost.Python with -everything stripped away that isn't relevant for binding generation. Without -comments, the core header files only require ~2.5K lines of code and depend on -Python (2.7 or 3.x) and the C++ standard library. This compact implementation -was possible thanks to some of the new C++11 language features (specifically: -tuples, lambda functions and variadic templates). Since its creation, this -library has grown beyond Boost.Python in many ways, leading to dramatically -simpler binding code in many common situations. - -Core features -************* -The following core C++ features can be mapped to Python - -- Functions accepting and returning custom data structures per value, reference, or pointer -- Instance methods and static methods -- Overloaded functions -- Instance attributes and static attributes -- Arbitrary exception types -- Enumerations -- Callbacks -- Iterators and ranges -- Custom operators -- Single and multiple inheritance -- STL data structures -- Iterators and ranges -- Smart pointers with reference counting like ``std::shared_ptr`` -- Internal references with correct reference counting -- C++ classes with virtual (and pure virtual) methods can be extended in Python - -Goodies -******* -In addition to the core functionality, pybind11 provides some extra goodies: - -- It is possible to bind C++11 lambda functions with captured variables. The - lambda capture data is stored inside the resulting Python function object. - -- pybind11 uses C++11 move constructors and move assignment operators whenever - possible to efficiently transfer custom data types. - -- It's easy to expose the internal storage of custom data types through - Pythons' buffer protocols. This is handy e.g. for fast conversion between - C++ matrix classes like Eigen and NumPy without expensive copy operations. - -- pybind11 can automatically vectorize functions so that they are transparently - applied to all entries of one or more NumPy array arguments. - -- Python's slice-based access and assignment operations can be supported with - just a few lines of code. - -- Everything is contained in just a few header files; there is no need to link - against any additional libraries. - -- Binaries are generally smaller by a factor of at least 2 compared to - equivalent bindings generated by Boost.Python. A recent pybind11 conversion - of `PyRosetta`_, an enormous Boost.Python binding project, reported a binary - size reduction of **5.4x** and compile time reduction by **5.8x**. - -- When supported by the compiler, two new C++14 features (relaxed constexpr and - return value deduction) are used to precompute function signatures at compile - time, leading to smaller binaries. - -- With little extra effort, C++ types can be pickled and unpickled similar to - regular Python objects. - -.. _PyRosetta: http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf - -Supported compilers -******************* - -1. Clang/LLVM (any non-ancient version with C++11 support) -2. GCC (any non-ancient version with C++11 support) -3. Microsoft Visual Studio 2015 or newer -4. Intel C++ compiler v15 or newer diff --git a/stormpy/resources/pybind11/docs/limitations.rst b/stormpy/resources/pybind11/docs/limitations.rst deleted file mode 100644 index a1a4f1aff..000000000 --- a/stormpy/resources/pybind11/docs/limitations.rst +++ /dev/null @@ -1,20 +0,0 @@ -Limitations -########### - -pybind11 strives to be a general solution to binding generation, but it also has -certain limitations: - -- pybind11 casts away ``const``-ness in function arguments and return values. - This is in line with the Python language, which has no concept of ``const`` - values. This means that some additional care is needed to avoid bugs that - would be caught by the type checker in a traditional C++ program. - -- The NumPy interface ``pybind11::array`` greatly simplifies accessing - numerical data from C++ (and vice versa), but it's not a full-blown array - class like ``Eigen::Array`` or ``boost.multi_array``. - -These features could be implemented but would lead to a significant increase in -complexity. I've decided to draw the line here to keep this project simple and -compact. Users who absolutely require these features are encouraged to fork -pybind11. - diff --git a/stormpy/resources/pybind11/docs/pybind11-logo.png b/stormpy/resources/pybind11/docs/pybind11-logo.png deleted file mode 100644 index 4cbad54f7..000000000 Binary files a/stormpy/resources/pybind11/docs/pybind11-logo.png and /dev/null differ diff --git a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python1.png b/stormpy/resources/pybind11/docs/pybind11_vs_boost_python1.png deleted file mode 100644 index 833231f24..000000000 Binary files a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python1.png and /dev/null differ diff --git a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python1.svg b/stormpy/resources/pybind11/docs/pybind11_vs_boost_python1.svg deleted file mode 100644 index 5bf950e6f..000000000 --- a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python1.svg +++ /dev/null @@ -1,427 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python2.png b/stormpy/resources/pybind11/docs/pybind11_vs_boost_python2.png deleted file mode 100644 index 9f17272c5..000000000 Binary files a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python2.png and /dev/null differ diff --git a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python2.svg b/stormpy/resources/pybind11/docs/pybind11_vs_boost_python2.svg deleted file mode 100644 index 5ed6530ca..000000000 --- a/stormpy/resources/pybind11/docs/pybind11_vs_boost_python2.svg +++ /dev/null @@ -1,427 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stormpy/resources/pybind11/docs/reference.rst b/stormpy/resources/pybind11/docs/reference.rst deleted file mode 100644 index 542259eba..000000000 --- a/stormpy/resources/pybind11/docs/reference.rst +++ /dev/null @@ -1,247 +0,0 @@ -.. _reference: - -.. warning:: - - Please be advised that the reference documentation discussing pybind11 - internals is currently incomplete. Please refer to the previous sections - and the pybind11 header files for the nitty gritty details. - -Reference -######### - -Macros -====== - -.. function:: PYBIND11_PLUGIN(const char *name) - - This macro creates the entry point that will be invoked when the Python - interpreter imports a plugin library. Please create a - :class:`module` in the function body and return the pointer to its - underlying Python object at the end. - - .. code-block:: cpp - - PYBIND11_PLUGIN(example) { - pybind11::module m("example", "pybind11 example plugin"); - /// Set up bindings here - return m.ptr(); - } - -.. _core_types: - -Convenience classes for arbitrary Python types -============================================== - -Without reference counting --------------------------- - -.. class:: handle - - The :class:`handle` class is a thin wrapper around an arbitrary Python - object (i.e. a ``PyObject *`` in Python's C API). It does not perform any - automatic reference counting and merely provides a basic C++ interface to - various Python API functions. - -.. seealso:: - - The :class:`object` class inherits from :class:`handle` and adds automatic - reference counting features. - -.. function:: handle::handle() - - The default constructor creates a handle with a ``nullptr``-valued pointer. - -.. function:: handle::handle(const handle&) - - Copy constructor - -.. function:: handle::handle(PyObject *) - - Creates a :class:`handle` from the given raw Python object pointer. - -.. function:: PyObject * handle::ptr() const - - Return the ``PyObject *`` underlying a :class:`handle`. - -.. function:: const handle& handle::inc_ref() const - - Manually increase the reference count of the Python object. Usually, it is - preferable to use the :class:`object` class which derives from - :class:`handle` and calls this function automatically. Returns a reference - to itself. - -.. function:: const handle& handle::dec_ref() const - - Manually decrease the reference count of the Python object. Usually, it is - preferable to use the :class:`object` class which derives from - :class:`handle` and calls this function automatically. Returns a reference - to itself. - -.. function:: void handle::ref_count() const - - Return the object's current reference count - -.. function:: handle handle::get_type() const - - Return a handle to the Python type object underlying the instance - -.. function detail::accessor handle::operator[](handle key) const - - Return an internal functor to invoke the object's sequence protocol. - Casting the returned ``detail::accessor`` instance to a :class:`handle` or - :class:`object` subclass causes a corresponding call to ``__getitem__``. - Assigning a :class:`handle` or :class:`object` subclass causes a call to - ``__setitem__``. - -.. function detail::accessor handle::operator[](const char *key) const - - See the above function (the only difference is that they key is provided as - a string literal). - -.. function detail::accessor handle::attr(handle key) const - - Return an internal functor to access the object's attributes. - Casting the returned ``detail::accessor`` instance to a :class:`handle` or - :class:`object` subclass causes a corresponding call to ``__getattr``. - Assigning a :class:`handle` or :class:`object` subclass causes a call to - ``__setattr``. - -.. function detail::accessor handle::attr(const char *key) const - - See the above function (the only difference is that they key is provided as - a string literal). - -.. function operator handle::bool() const - - Return ``true`` when the :class:`handle` wraps a valid Python object. - -.. function str handle::str() const - - Return a string representation of the object. This is analogous to - the ``str()`` function in Python. - -.. function:: template T handle::cast() const - - Attempt to cast the Python object into the given C++ type. A - :class:`cast_error` will be throw upon failure. - -.. function:: template object handle::call(Args&&... args) const - - Assuming the Python object is a function or implements the ``__call__`` - protocol, ``call()`` invokes the underlying function, passing an arbitrary - set of parameters. The result is returned as a :class:`object` and may need - to be converted back into a Python object using :func:`handle::cast`. - - When some of the arguments cannot be converted to Python objects, the - function will throw a :class:`cast_error` exception. When the Python - function call fails, a :class:`error_already_set` exception is thrown. - -With reference counting ------------------------ - -.. class:: object : public handle - - Like :class:`handle`, the object class is a thin wrapper around an - arbitrary Python object (i.e. a ``PyObject *`` in Python's C API). In - contrast to :class:`handle`, it optionally increases the object's reference - count upon construction, and it *always* decreases the reference count when - the :class:`object` instance goes out of scope and is destructed. When - using :class:`object` instances consistently, it is much easier to get - reference counting right at the first attempt. - -.. function:: object::object(const object &o) - - Copy constructor; always increases the reference count - -.. function:: object::object(const handle &h, bool borrowed) - - Creates a :class:`object` from the given :class:`handle`. The reference - count is only increased if the ``borrowed`` parameter is set to ``true``. - -.. function:: object::object(PyObject *ptr, bool borrowed) - - Creates a :class:`object` from the given raw Python object pointer. The - reference count is only increased if the ``borrowed`` parameter is set to - ``true``. - -.. function:: object::object(object &&other) - - Move constructor; steals the object from ``other`` and preserves its - reference count. - -.. function:: handle object::release() - - Resets the internal pointer to ``nullptr`` without without decreasing the - object's reference count. The function returns a raw handle to the original - Python object. - -.. function:: object::~object() - - Destructor, which automatically calls :func:`handle::dec_ref()`. - -Convenience classes for specific Python types -============================================= - - -.. class:: module : public object - -.. function:: module::module(const char *name, const char *doc = nullptr) - - Create a new top-level Python module with the given name and docstring - -.. function:: module module::def_submodule(const char *name, const char *doc = nullptr) - - Create and return a new Python submodule with the given name and docstring. - This also works recursively, i.e. - - .. code-block:: cpp - - pybind11::module m("example", "pybind11 example plugin"); - pybind11::module m2 = m.def_submodule("sub", "A submodule of 'example'"); - pybind11::module m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'"); - -.. cpp:function:: template module& module::def(const char *name, Func && f, Extra && ... extra) - - Create Python binding for a new function within the module scope. ``Func`` - can be a plain C++ function, a function pointer, or a lambda function. For - details on the ``Extra&& ... extra`` argument, see section :ref:`extras`. - -.. _extras: - -Passing extra arguments to the def function -=========================================== - -.. class:: arg - -.. function:: arg::arg(const char *name) - -.. function:: template arg_v arg::operator=(T &&value) - -.. class:: arg_v : public arg - - Represents a named argument with a default value - -.. class:: sibling - - Used to specify a handle to an existing sibling function; used internally - to implement function overloading in :func:`module::def` and - :func:`class_::def`. - -.. function:: sibling::sibling(handle handle) - -.. class doc - - This is class is internally used by pybind11. - -.. function:: doc::doc(const char *value) - - Create a new docstring with the specified value - -.. class name - - This is class is internally used by pybind11. - -.. function:: name::name(const char *value) - - Used to specify the function name - diff --git a/stormpy/resources/pybind11/docs/release.rst b/stormpy/resources/pybind11/docs/release.rst deleted file mode 100644 index a15504ea8..000000000 --- a/stormpy/resources/pybind11/docs/release.rst +++ /dev/null @@ -1,22 +0,0 @@ -To release a new version of pybind11: - -- Update the version number and push to pypi - - Update ``pybind11/_version.py`` (set release version, remove 'dev') - - Update version in ``docs/conf.py`` - - Tag release date in ``docs/changelog.rst``. - - ``git add`` and ``git commit``. - - if new minor version: ``git checkout -b vX.Y``, ``git push -u origin vX.Y`` - - ``git tag -a vX.Y.Z -m 'vX.Y.Z release'``. - - ``git push`` - - ``git push --tags``. - - ``python setup.py sdist upload``. - - ``python setup.py bdist_wheel upload``. -- Update conda-forge (https://github.com/conda-forge/pybind11-feedstock) via PR - - change version number in ``recipe/meta.yml`` - - update checksum to match the one computed by pypi -- Get back to work - - Update ``_version.py`` (add 'dev' and increment minor). - - Update version in ``docs/conf.py`` - - Update version macros in ``include/pybind11/common.h`` - - ``git add`` and ``git commit``. - ``git push`` diff --git a/stormpy/resources/pybind11/example/eigen.cpp b/stormpy/resources/pybind11/example/eigen.cpp deleted file mode 100644 index b6fa24a42..000000000 --- a/stormpy/resources/pybind11/example/eigen.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - example/eigen.cpp -- automatic conversion of Eigen types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - -void init_eigen(py::module &m) { - typedef Eigen::Matrix FixedMatrixR; - typedef Eigen::Matrix FixedMatrixC; - typedef Eigen::Matrix DenseMatrixR; - typedef Eigen::Matrix DenseMatrixC; - typedef Eigen::SparseMatrix SparseMatrixR; - typedef Eigen::SparseMatrix SparseMatrixC; - - // Non-symmetric matrix with zero elements - Eigen::MatrixXf mat(5, 6); - mat << 0, 3, 0, 0, 0, 11, 22, 0, 0, 0, 17, 11, 7, 5, 0, 1, 0, 11, 0, - 0, 0, 0, 0, 11, 0, 0, 14, 0, 8, 11; - - m.def("fixed_r", [mat]() -> FixedMatrixR { - return FixedMatrixR(mat); - }); - - m.def("fixed_c", [mat]() -> FixedMatrixC { - return FixedMatrixC(mat); - }); - - m.def("fixed_passthrough_r", [](const FixedMatrixR &m) -> FixedMatrixR { - return m; - }); - - m.def("fixed_passthrough_c", [](const FixedMatrixC &m) -> FixedMatrixC { - return m; - }); - - m.def("dense_r", [mat]() -> DenseMatrixR { - return DenseMatrixR(mat); - }); - - m.def("dense_c", [mat]() -> DenseMatrixC { - return DenseMatrixC(mat); - }); - - m.def("dense_passthrough_r", [](const DenseMatrixR &m) -> DenseMatrixR { - return m; - }); - - m.def("dense_passthrough_c", [](const DenseMatrixC &m) -> DenseMatrixC { - return m; - }); - - m.def("sparse_r", [mat]() -> SparseMatrixR { - return Eigen::SparseView(mat); - }); - - m.def("sparse_c", [mat]() -> SparseMatrixC { - return Eigen::SparseView(mat); - }); - - m.def("sparse_passthrough_r", [](const SparseMatrixR &m) -> SparseMatrixR { - return m; - }); - - m.def("sparse_passthrough_c", [](const SparseMatrixC &m) -> SparseMatrixC { - return m; - }); -} diff --git a/stormpy/resources/pybind11/example/eigen.py b/stormpy/resources/pybind11/example/eigen.py deleted file mode 100644 index accaf236a..000000000 --- a/stormpy/resources/pybind11/example/eigen.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import fixed_r, fixed_c -from example import fixed_passthrough_r, fixed_passthrough_c -from example import dense_r, dense_c -from example import dense_passthrough_r, dense_passthrough_c -from example import sparse_r, sparse_c -from example import sparse_passthrough_r, sparse_passthrough_c -import numpy as np - -ref = np.array( - [[0, 3, 0, 0, 0, 11], - [22, 0, 0, 0, 17, 11], - [7, 5, 0, 1, 0, 11], - [0, 0, 0, 0, 0, 11], - [0, 0, 14, 0, 8, 11]]) - - -def check(mat): - return 'OK' if np.sum(mat - ref) == 0 else 'NOT OK' - -print("fixed_r = %s" % check(fixed_r())) -print("fixed_c = %s" % check(fixed_c())) -print("pt_r(fixed_r) = %s" % check(fixed_passthrough_r(fixed_r()))) -print("pt_c(fixed_c) = %s" % check(fixed_passthrough_c(fixed_c()))) -print("pt_r(fixed_c) = %s" % check(fixed_passthrough_r(fixed_c()))) -print("pt_c(fixed_r) = %s" % check(fixed_passthrough_c(fixed_r()))) - -print("dense_r = %s" % check(dense_r())) -print("dense_c = %s" % check(dense_c())) -print("pt_r(dense_r) = %s" % check(dense_passthrough_r(dense_r()))) -print("pt_c(dense_c) = %s" % check(dense_passthrough_c(dense_c()))) -print("pt_r(dense_c) = %s" % check(dense_passthrough_r(dense_c()))) -print("pt_c(dense_r) = %s" % check(dense_passthrough_c(dense_r()))) - -print("sparse_r = %s" % check(sparse_r())) -print("sparse_c = %s" % check(sparse_c())) -print("pt_r(sparse_r) = %s" % check(sparse_passthrough_r(sparse_r()))) -print("pt_c(sparse_c) = %s" % check(sparse_passthrough_c(sparse_c()))) -print("pt_r(sparse_c) = %s" % check(sparse_passthrough_r(sparse_c()))) -print("pt_c(sparse_r) = %s" % check(sparse_passthrough_c(sparse_r()))) diff --git a/stormpy/resources/pybind11/example/eigen.ref b/stormpy/resources/pybind11/example/eigen.ref deleted file mode 100644 index b87f8ede3..000000000 --- a/stormpy/resources/pybind11/example/eigen.ref +++ /dev/null @@ -1,18 +0,0 @@ -fixed_r = OK -fixed_c = OK -pt_r(fixed_r) = OK -pt_c(fixed_c) = OK -pt_r(fixed_c) = OK -pt_c(fixed_r) = OK -dense_r = OK -dense_c = OK -pt_r(dense_r) = OK -pt_c(dense_c) = OK -pt_r(dense_c) = OK -pt_c(dense_r) = OK -sparse_r = OK -sparse_c = OK -pt_r(sparse_r) = OK -pt_c(sparse_c) = OK -pt_r(sparse_c) = OK -pt_c(sparse_r) = OK diff --git a/stormpy/resources/pybind11/example/example.cpp b/stormpy/resources/pybind11/example/example.cpp deleted file mode 100644 index 470684a3b..000000000 --- a/stormpy/resources/pybind11/example/example.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - example/example.cpp -- pybind example plugin - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -void init_ex1(py::module &); -void init_ex2(py::module &); -void init_ex3(py::module &); -void init_ex4(py::module &); -void init_ex5(py::module &); -void init_ex6(py::module &); -void init_ex7(py::module &); -void init_ex8(py::module &); -void init_ex9(py::module &); -void init_ex10(py::module &); -void init_ex11(py::module &); -void init_ex12(py::module &); -void init_ex13(py::module &); -void init_ex14(py::module &); -void init_ex15(py::module &); -void init_ex16(py::module &); -void init_ex17(py::module &); -void init_issues(py::module &); - -#if defined(PYBIND11_TEST_EIGEN) - void init_eigen(py::module &); -#endif - -PYBIND11_PLUGIN(example) { - py::module m("example", "pybind example plugin"); - - init_ex1(m); - init_ex2(m); - init_ex3(m); - init_ex4(m); - init_ex5(m); - init_ex6(m); - init_ex7(m); - init_ex8(m); - init_ex9(m); - init_ex10(m); - init_ex11(m); - init_ex12(m); - init_ex13(m); - init_ex14(m); - init_ex15(m); - init_ex16(m); - init_ex17(m); - init_issues(m); - - #if defined(PYBIND11_TEST_EIGEN) - init_eigen(m); - #endif - - return m.ptr(); -} diff --git a/stormpy/resources/pybind11/example/example.h b/stormpy/resources/pybind11/example/example.h deleted file mode 100644 index ab8fff796..000000000 --- a/stormpy/resources/pybind11/example/example.h +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -using std::cout; -using std::endl; - -namespace py = pybind11; diff --git a/stormpy/resources/pybind11/example/example1.cpp b/stormpy/resources/pybind11/example/example1.cpp deleted file mode 100644 index dd651fbaf..000000000 --- a/stormpy/resources/pybind11/example/example1.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - example/example1.cpp -- constructors, deconstructors, attribute access, - __str__, argument and return value conventions - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -class Example1 { -public: - Example1() { - cout << "Called Example1 default constructor.." << endl; - } - Example1(int value) : value(value) { - cout << "Called Example1 constructor with value " << value << ".." << endl; - } - Example1(const Example1 &e) : value(e.value) { - cout << "Called Example1 copy constructor with value " << value << ".." << endl; - } - Example1(Example1 &&e) : value(e.value) { - cout << "Called Example1 move constructor with value " << value << ".." << endl; - e.value = 0; - } - ~Example1() { - cout << "Called Example1 destructor (" << value << ")" << endl; - } - std::string toString() { - return "Example1[value=" + std::to_string(value) + "]"; - } - - void operator=(const Example1 &e) { cout << "Assignment operator" << endl; value = e.value; } - void operator=(Example1 &&e) { cout << "Move assignment operator" << endl; value = e.value; e.value = 0;} - - void add1(Example1 other) { value += other.value; } // passing by value - void add2(Example1 &other) { value += other.value; } // passing by reference - void add3(const Example1 &other) { value += other.value; } // passing by const reference - void add4(Example1 *other) { value += other->value; } // passing by pointer - void add5(const Example1 *other) { value += other->value; } // passing by const pointer - - void add6(int other) { value += other; } // passing by value - void add7(int &other) { value += other; } // passing by reference - void add8(const int &other) { value += other; } // passing by const reference - void add9(int *other) { value += *other; } // passing by pointer - void add10(const int *other) { value += *other; } // passing by const pointer - - Example1 self1() { return *this; } // return by value - Example1 &self2() { return *this; } // return by reference - const Example1 &self3() { return *this; } // return by const reference - Example1 *self4() { return this; } // return by pointer - const Example1 *self5() { return this; } // return by const pointer - - int internal1() { return value; } // return by value - int &internal2() { return value; } // return by reference - const int &internal3() { return value; } // return by const reference - int *internal4() { return &value; } // return by pointer - const int *internal5() { return &value; } // return by const pointer - - int value = 0; -}; - -void init_ex1(py::module &m) { - py::class_(m, "Example1") - .def(py::init<>()) - .def(py::init()) - .def(py::init()) - .def("add1", &Example1::add1) - .def("add2", &Example1::add2) - .def("add3", &Example1::add3) - .def("add4", &Example1::add4) - .def("add5", &Example1::add5) - .def("add6", &Example1::add6) - .def("add7", &Example1::add7) - .def("add8", &Example1::add8) - .def("add9", &Example1::add9) - .def("add10", &Example1::add10) - .def("self1", &Example1::self1) - .def("self2", &Example1::self2) - .def("self3", &Example1::self3) - .def("self4", &Example1::self4) - .def("self5", &Example1::self5) - .def("internal1", &Example1::internal1) - .def("internal2", &Example1::internal2) - .def("internal3", &Example1::internal3) - .def("internal4", &Example1::internal4) - .def("internal5", &Example1::internal5) - .def("__str__", &Example1::toString) - .def_readwrite("value", &Example1::value); -} diff --git a/stormpy/resources/pybind11/example/example1.py b/stormpy/resources/pybind11/example/example1.py deleted file mode 100755 index f89b662d8..000000000 --- a/stormpy/resources/pybind11/example/example1.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import Example1 - -instance1 = Example1() -instance2 = Example1(32) -instance1.add1(instance2) -instance1.add2(instance2) -instance1.add3(instance2) -instance1.add4(instance2) -instance1.add5(instance2) -instance1.add6(32) -instance1.add7(32) -instance1.add8(32) -instance1.add9(32) -instance1.add10(32) - -print("Instance 1: " + str(instance1)) -print("Instance 2: " + str(instance2)) - -print(instance1.self1()) -print(instance1.self2()) -print(instance1.self3()) -print(instance1.self4()) -print(instance1.self5()) -print(instance1.internal1()) -print(instance1.internal2()) -print(instance1.internal3()) -print(instance1.internal4()) -print(instance1.internal5()) - -print("Instance 1, direct access = %i" % instance1.value) -instance1.value = 100 -print("Instance 1: " + str(instance1)) diff --git a/stormpy/resources/pybind11/example/example1.ref b/stormpy/resources/pybind11/example/example1.ref deleted file mode 100644 index 2c242f9c4..000000000 --- a/stormpy/resources/pybind11/example/example1.ref +++ /dev/null @@ -1,26 +0,0 @@ -Called Example1 default constructor.. -Called Example1 constructor with value 32.. -Called Example1 copy constructor with value 32.. -Called Example1 copy constructor with value 32.. -Called Example1 destructor (32) -Called Example1 destructor (32) -Instance 1: Example1[value=320] -Instance 2: Example1[value=32] -Called Example1 copy constructor with value 320.. -Called Example1 move constructor with value 320.. -Called Example1 destructor (0) -Example1[value=320] -Called Example1 destructor (320) -Example1[value=320] -Example1[value=320] -Example1[value=320] -Example1[value=320] -320 -320 -320 -320 -320 -Instance 1, direct access = 320 -Instance 1: Example1[value=100] -Called Example1 destructor (32) -Called Example1 destructor (100) diff --git a/stormpy/resources/pybind11/example/example10.cpp b/stormpy/resources/pybind11/example/example10.cpp deleted file mode 100644 index 06528c2f0..000000000 --- a/stormpy/resources/pybind11/example/example10.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - example/example10.cpp -- auto-vectorize functions over NumPy array - arguments - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - -double my_func(int x, float y, double z) { - std::cout << "my_func(x:int=" << x << ", y:float=" << y << ", z:float=" << z << ")" << std::endl; - return (float) x*y*z; -} - -std::complex my_func3(std::complex c) { - return c * std::complex(2.f); -} - -void init_ex10(py::module &m) { - // Vectorize all arguments of a function (though non-vector arguments are also allowed) - m.def("vectorized_func", py::vectorize(my_func)); - - // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the vectorization) - m.def("vectorized_func2", - [](py::array_t x, py::array_t y, float z) { - return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(x, y); - } - ); - - // Vectorize a complex-valued function - m.def("vectorized_func3", py::vectorize(my_func3)); - - /// Numpy function which only accepts specific data types - m.def("selective_func", [](py::array_t) { std::cout << "Int branch taken. "<< std::endl; }); - m.def("selective_func", [](py::array_t) { std::cout << "Float branch taken. "<< std::endl; }); - m.def("selective_func", [](py::array_t, py::array::c_style>) { std::cout << "Complex float branch taken. "<< std::endl; }); -} diff --git a/stormpy/resources/pybind11/example/example10.py b/stormpy/resources/pybind11/example/example10.py deleted file mode 100755 index b18e729a6..000000000 --- a/stormpy/resources/pybind11/example/example10.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -import example -try: - import numpy as np -except ImportError: - print('NumPy missing') - exit(0) - -from example import vectorized_func -from example import vectorized_func2 -from example import vectorized_func3 - -print(vectorized_func3(np.array(3+7j))) - -for f in [vectorized_func, vectorized_func2]: - print(f(1, 2, 3)) - print(f(np.array(1), np.array(2), 3)) - print(f(np.array([1, 3]), np.array([2, 4]), 3)) - print(f(np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3)) - print(np.array([[1, 3, 5], [7, 9, 11]])* np.array([[2, 4, 6], [8, 10, 12]])*3) - print(f(np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2)) - print(np.array([[1, 2, 3], [4, 5, 6]])* np.array([2, 3, 4])* 2) - print(f(np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2)) - print(np.array([[1, 2, 3], [4, 5, 6]])* np.array([[2], [3]])* 2) - -from example import selective_func - -selective_func(np.array([1], dtype=np.int32)) -selective_func(np.array([1.0], dtype=np.float32)) -selective_func(np.array([1.0j], dtype=np.complex64)) diff --git a/stormpy/resources/pybind11/example/example10.ref b/stormpy/resources/pybind11/example/example10.ref deleted file mode 100644 index 4885fc1ca..000000000 --- a/stormpy/resources/pybind11/example/example10.ref +++ /dev/null @@ -1,78 +0,0 @@ -(6+14j) -my_func(x:int=1, y:float=2, z:float=3) -6.0 -my_func(x:int=1, y:float=2, z:float=3) -6.0 -my_func(x:int=1, y:float=2, z:float=3) -my_func(x:int=3, y:float=4, z:float=3) -[ 6. 36.] -my_func(x:int=1, y:float=2, z:float=3) -my_func(x:int=3, y:float=4, z:float=3) -my_func(x:int=5, y:float=6, z:float=3) -my_func(x:int=7, y:float=8, z:float=3) -my_func(x:int=9, y:float=10, z:float=3) -my_func(x:int=11, y:float=12, z:float=3) -[[ 6. 36. 90.] - [ 168. 270. 396.]] -[[ 6 36 90] - [168 270 396]] -my_func(x:int=1, y:float=2, z:float=2) -my_func(x:int=2, y:float=3, z:float=2) -my_func(x:int=3, y:float=4, z:float=2) -my_func(x:int=4, y:float=2, z:float=2) -my_func(x:int=5, y:float=3, z:float=2) -my_func(x:int=6, y:float=4, z:float=2) -[[ 4. 12. 24.] - [ 16. 30. 48.]] -[[ 4 12 24] - [16 30 48]] -my_func(x:int=1, y:float=2, z:float=2) -my_func(x:int=2, y:float=2, z:float=2) -my_func(x:int=3, y:float=2, z:float=2) -my_func(x:int=4, y:float=3, z:float=2) -my_func(x:int=5, y:float=3, z:float=2) -my_func(x:int=6, y:float=3, z:float=2) -[[ 4. 8. 12.] - [ 24. 30. 36.]] -[[ 4 8 12] - [24 30 36]] -my_func(x:int=1, y:float=2, z:float=3) -6.0 -my_func(x:int=1, y:float=2, z:float=3) -6.0 -my_func(x:int=1, y:float=2, z:float=3) -my_func(x:int=3, y:float=4, z:float=3) -[ 6. 36.] -my_func(x:int=1, y:float=2, z:float=3) -my_func(x:int=3, y:float=4, z:float=3) -my_func(x:int=5, y:float=6, z:float=3) -my_func(x:int=7, y:float=8, z:float=3) -my_func(x:int=9, y:float=10, z:float=3) -my_func(x:int=11, y:float=12, z:float=3) -[[ 6. 36. 90.] - [ 168. 270. 396.]] -[[ 6 36 90] - [168 270 396]] -my_func(x:int=1, y:float=2, z:float=2) -my_func(x:int=2, y:float=3, z:float=2) -my_func(x:int=3, y:float=4, z:float=2) -my_func(x:int=4, y:float=2, z:float=2) -my_func(x:int=5, y:float=3, z:float=2) -my_func(x:int=6, y:float=4, z:float=2) -[[ 4. 12. 24.] - [ 16. 30. 48.]] -[[ 4 12 24] - [16 30 48]] -my_func(x:int=1, y:float=2, z:float=2) -my_func(x:int=2, y:float=2, z:float=2) -my_func(x:int=3, y:float=2, z:float=2) -my_func(x:int=4, y:float=3, z:float=2) -my_func(x:int=5, y:float=3, z:float=2) -my_func(x:int=6, y:float=3, z:float=2) -[[ 4. 8. 12.] - [ 24. 30. 36.]] -[[ 4 8 12] - [24 30 36]] -Int branch taken. -Float branch taken. -Complex float branch taken. diff --git a/stormpy/resources/pybind11/example/example11.cpp b/stormpy/resources/pybind11/example/example11.cpp deleted file mode 100644 index 4b3c6d08b..000000000 --- a/stormpy/resources/pybind11/example/example11.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - example/example11.cpp -- keyword arguments and default values - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - -void kw_func(int x, int y) { std::cout << "kw_func(x=" << x << ", y=" << y << ")" << std::endl; } - -void kw_func4(const std::vector &entries) { - std::cout << "kw_func4: "; - for (int i : entries) - std::cout << i << " "; - std::cout << endl; -} - -py::object call_kw_func(py::function f) { - py::tuple args = py::make_tuple(1234); - py::dict kwargs; - kwargs["y"] = py::cast(5678); - return f(*args, **kwargs); -} - -void args_function(py::args args) { - for (size_t it=0; it " << item.second << std::endl; - } -} - -void init_ex11(py::module &m) { - m.def("kw_func", &kw_func, py::arg("x"), py::arg("y")); - m.def("kw_func2", &kw_func, py::arg("x") = 100, py::arg("y") = 200); - m.def("kw_func3", [](const char *) { }, py::arg("data") = std::string("Hello world!")); - - /* A fancier default argument */ - std::vector list; - list.push_back(13); - list.push_back(17); - - m.def("kw_func4", &kw_func4, py::arg("myList") = list); - m.def("call_kw_func", &call_kw_func); - - m.def("args_function", &args_function); - m.def("args_kwargs_function", &args_kwargs_function); - - using namespace py::literals; - m.def("kw_func_udl", &kw_func, "x"_a, "y"_a=300); - m.def("kw_func_udl_z", &kw_func, "x"_a, "y"_a=0); -} diff --git a/stormpy/resources/pybind11/example/example11.py b/stormpy/resources/pybind11/example/example11.py deleted file mode 100755 index 09ba13e6c..000000000 --- a/stormpy/resources/pybind11/example/example11.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -import pydoc - -sys.path.append('.') - -from example import kw_func, kw_func2, kw_func3, kw_func4, call_kw_func -from example import args_function, args_kwargs_function, kw_func_udl, kw_func_udl_z - -print(pydoc.render_doc(kw_func, "Help on %s")) -print(pydoc.render_doc(kw_func2, "Help on %s")) -print(pydoc.render_doc(kw_func3, "Help on %s")) -print(pydoc.render_doc(kw_func4, "Help on %s")) -print(pydoc.render_doc(kw_func_udl, "Help on %s")) -print(pydoc.render_doc(kw_func_udl_z, "Help on %s")) - -kw_func(5, 10) -kw_func(5, y=10) -kw_func(y=10, x=5) - -kw_func2() - -kw_func2(5) -kw_func2(x=5) - -kw_func2(y=10) - -kw_func2(5, 10) -kw_func2(x=5, y=10) - -try: - kw_func2(x=5, y=10, z=12) -except Exception as e: - print("Caught expected exception: " + str(e)) - -kw_func4() -kw_func4(myList=[1, 2, 3]) - -call_kw_func(kw_func2) - -args_function('arg1_value', 'arg2_value', 3) -args_kwargs_function('arg1_value', 'arg2_value', arg3='arg3_value', arg4=4) - -kw_func_udl(x=5, y=10) -kw_func_udl_z(x=5) diff --git a/stormpy/resources/pybind11/example/example11.ref b/stormpy/resources/pybind11/example/example11.ref deleted file mode 100644 index a693b6ceb..000000000 --- a/stormpy/resources/pybind11/example/example11.ref +++ /dev/null @@ -1,55 +0,0 @@ -Help on built-in function kw_func in module example - -kkww__ffuunncc(...) - kw_func(x : int, y : int) -> NoneType - -Help on built-in function kw_func2 in module example - -kkww__ffuunncc22(...) - kw_func2(x : int = 100L, y : int = 200L) -> NoneType - -Help on built-in function kw_func3 in module example - -kkww__ffuunncc33(...) - kw_func3(data : unicode = u'Hello world!') -> NoneType - -Help on built-in function kw_func4 in module example - -kkww__ffuunncc44(...) - kw_func4(myList : list = [13L, 17L]) -> NoneType - -Help on built-in function kw_func_udl in module example - -kkww__ffuunncc__uuddll(...) - kw_func_udl(x : int, y : int = 300L) -> NoneType - -Help on built-in function kw_func_udl_z in module example - -kkww__ffuunncc__uuddll__zz(...) - kw_func_udl_z(x : int, y : int = 0L) -> NoneType - -kw_func(x=5, y=10) -kw_func(x=5, y=10) -kw_func(x=5, y=10) -kw_func(x=100, y=200) -kw_func(x=5, y=200) -kw_func(x=5, y=200) -kw_func(x=100, y=10) -kw_func(x=5, y=10) -kw_func(x=5, y=10) -Caught expected exception: Incompatible function arguments. The following argument types are supported: - 1. (x : int = 100L, y : int = 200L) -> NoneType - Invoked with: -kw_func4: 13 17 -kw_func4: 1 2 3 -kw_func(x=1234, y=5678) -got argument: arg1_value -got argument: arg2_value -got argument: 3 -got argument: arg1_value -got argument: arg2_value -got keyword argument: arg3 -> arg3_value -got keyword argument: arg4 -> 4 - -kw_func(x=5, y=10) -kw_func(x=5, y=0) diff --git a/stormpy/resources/pybind11/example/example12.cpp b/stormpy/resources/pybind11/example/example12.cpp deleted file mode 100644 index e5555f53a..000000000 --- a/stormpy/resources/pybind11/example/example12.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - example/example12.cpp -- overriding virtual functions from Python - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - -/* This is an example class that we'll want to be able to extend from Python */ -class Example12 { -public: - Example12(int state) : state(state) { - cout << "Constructing Example12.." << endl; - } - - ~Example12() { - cout << "Destructing Example12.." << endl; - } - - virtual int run(int value) { - std::cout << "Original implementation of Example12::run(state=" << state - << ", value=" << value << ")" << std::endl; - return state + value; - } - - virtual bool run_bool() = 0; - virtual void pure_virtual() = 0; -private: - int state; -}; - -/* This is a wrapper class that must be generated */ -class PyExample12 : public Example12 { -public: - using Example12::Example12; /* Inherit constructors */ - - virtual int run(int value) { - /* Generate wrapping code that enables native function overloading */ - PYBIND11_OVERLOAD( - int, /* Return type */ - Example12, /* Parent class */ - run, /* Name of function */ - value /* Argument(s) */ - ); - } - - virtual bool run_bool() { - PYBIND11_OVERLOAD_PURE( - bool, /* Return type */ - Example12, /* Parent class */ - run_bool, /* Name of function */ - /* This function has no arguments. The trailing comma - in the previous line is needed for some compilers */ - ); - } - - virtual void pure_virtual() { - PYBIND11_OVERLOAD_PURE( - void, /* Return type */ - Example12, /* Parent class */ - pure_virtual, /* Name of function */ - /* This function has no arguments. The trailing comma - in the previous line is needed for some compilers */ - ); - } -}; - -int runExample12(Example12 *ex, int value) { - return ex->run(value); -} - -bool runExample12Bool(Example12* ex) { - return ex->run_bool(); -} - -void runExample12Virtual(Example12 *ex) { - ex->pure_virtual(); -} - -void init_ex12(py::module &m) { - /* Important: indicate the trampoline class PyExample12 using the third - argument to py::class_. The second argument with the unique pointer - is simply the default holder type used by pybind11. */ - py::class_, PyExample12>(m, "Example12") - .def(py::init()) - /* Reference original class in function definitions */ - .def("run", &Example12::run) - .def("run_bool", &Example12::run_bool) - .def("pure_virtual", &Example12::pure_virtual); - - m.def("runExample12", &runExample12); - m.def("runExample12Bool", &runExample12Bool); - m.def("runExample12Virtual", &runExample12Virtual); -} diff --git a/stormpy/resources/pybind11/example/example12.py b/stormpy/resources/pybind11/example/example12.py deleted file mode 100644 index eb175239f..000000000 --- a/stormpy/resources/pybind11/example/example12.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import Example12, runExample12, runExample12Virtual, runExample12Bool - - -class ExtendedExample12(Example12): - def __init__(self, state): - super(ExtendedExample12, self).__init__(state + 1) - self.data = "Hello world" - - def run(self, value): - print('ExtendedExample12::run(%i), calling parent..' % value) - return super(ExtendedExample12, self).run(value + 1) - - def run_bool(self): - print('ExtendedExample12::run_bool()') - return False - - def pure_virtual(self): - print('ExtendedExample12::pure_virtual(): %s' % self.data) - - -ex12 = Example12(10) -print(runExample12(ex12, 20)) -try: - runExample12Virtual(ex12) -except Exception as e: - print("Caught expected exception: " + str(e)) - -ex12p = ExtendedExample12(10) -print(runExample12(ex12p, 20)) -print(runExample12Bool(ex12p)) -runExample12Virtual(ex12p) diff --git a/stormpy/resources/pybind11/example/example12.ref b/stormpy/resources/pybind11/example/example12.ref deleted file mode 100644 index a25023fae..000000000 --- a/stormpy/resources/pybind11/example/example12.ref +++ /dev/null @@ -1,13 +0,0 @@ -Constructing Example12.. -Original implementation of Example12::run(state=10, value=20) -30 -Caught expected exception: Tried to call pure virtual function "Example12::pure_virtual" -Constructing Example12.. -ExtendedExample12::run(20), calling parent.. -Original implementation of Example12::run(state=11, value=21) -32 -ExtendedExample12::run_bool() -False -ExtendedExample12::pure_virtual(): Hello world -Destructing Example12.. -Destructing Example12.. diff --git a/stormpy/resources/pybind11/example/example13.cpp b/stormpy/resources/pybind11/example/example13.cpp deleted file mode 100644 index 6c1b8765d..000000000 --- a/stormpy/resources/pybind11/example/example13.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - example/example13.cpp -- keep_alive modifier (pybind11's version - of Boost.Python's with_custodian_and_ward / with_custodian_and_ward_postcall) - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -class Child { -public: - Child() { std::cout << "Allocating child." << std::endl; } - ~Child() { std::cout << "Releasing child." << std::endl; } -}; - -class Parent { -public: - Parent() { std::cout << "Allocating parent." << std::endl; } - ~Parent() { std::cout << "Releasing parent." << std::endl; } - void addChild(Child *) { } - Child *returnChild() { return new Child(); } -}; - -void init_ex13(py::module &m) { - py::class_(m, "Parent") - .def(py::init<>()) - .def("addChild", &Parent::addChild) - .def("addChildKeepAlive", &Parent::addChild, py::keep_alive<1, 2>()) - .def("returnChild", &Parent::returnChild) - .def("returnChildKeepAlive", &Parent::returnChild, py::keep_alive<1, 0>()); - - py::class_(m, "Child") - .def(py::init<>()); -} diff --git a/stormpy/resources/pybind11/example/example13.py b/stormpy/resources/pybind11/example/example13.py deleted file mode 100644 index ad0176ed4..000000000 --- a/stormpy/resources/pybind11/example/example13.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import print_function -import sys -import gc -sys.path.append('.') - -from example import Parent, Child - -if True: - p = Parent() - p.addChild(Child()) - gc.collect() - print(p) - p = None - -gc.collect() -print("") - -if True: - p = Parent() - p.returnChild() - gc.collect() - print(p) - p = None - -gc.collect() -print("") - -if True: - p = Parent() - p.addChildKeepAlive(Child()) - gc.collect() - print(p) - p = None -gc.collect() -print("") - -if True: - p = Parent() - p.returnChildKeepAlive() - gc.collect() - print(p) - p = None - -gc.collect() -print("") -print("Terminating..") diff --git a/stormpy/resources/pybind11/example/example13.ref b/stormpy/resources/pybind11/example/example13.ref deleted file mode 100644 index 7eb02c51f..000000000 --- a/stormpy/resources/pybind11/example/example13.ref +++ /dev/null @@ -1,25 +0,0 @@ -Allocating parent. -Allocating child. -Releasing child. - -Releasing parent. - -Allocating parent. -Allocating child. -Releasing child. - -Releasing parent. - -Allocating parent. -Allocating child. - -Releasing parent. -Releasing child. - -Allocating parent. -Allocating child. - -Releasing parent. -Releasing child. - -Terminating.. diff --git a/stormpy/resources/pybind11/example/example14.cpp b/stormpy/resources/pybind11/example/example14.cpp deleted file mode 100644 index ad67fe419..000000000 --- a/stormpy/resources/pybind11/example/example14.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - example/example14.cpp -- opaque types, passing void pointers - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include -#include - -typedef std::vector StringList; - -class ClassWithSTLVecProperty { -public: - StringList stringList; -}; - -/* IMPORTANT: Disable internal pybind11 translation mechanisms for STL data structures */ -PYBIND11_MAKE_OPAQUE(StringList); - -void init_ex14(py::module &m) { - py::class_(m, "StringList") - .def(py::init<>()) - .def("pop_back", &StringList::pop_back) - /* There are multiple versions of push_back(), etc. Select the right ones. */ - .def("push_back", (void (StringList::*)(const std::string &)) &StringList::push_back) - .def("back", (std::string &(StringList::*)()) &StringList::back) - .def("__len__", [](const StringList &v) { return v.size(); }) - .def("__iter__", [](StringList &v) { - return py::make_iterator(v.begin(), v.end()); - }, py::keep_alive<0, 1>()); - - py::class_(m, "ClassWithSTLVecProperty") - .def(py::init<>()) - .def_readwrite("stringList", &ClassWithSTLVecProperty::stringList); - - m.def("print_opaque_list", [](const StringList &l) { - std::cout << "Opaque list: ["; - bool first = true; - for (auto entry : l) { - if (!first) - std::cout << ", "; - std::cout << entry; - first = false; - } - std::cout << "]" << std::endl; - }); - - m.def("return_void_ptr", []() { return (void *) 0x1234; }); - m.def("print_void_ptr", [](void *ptr) { std::cout << "Got void ptr : 0x" << std::hex << (uint64_t) ptr << std::endl; }); - m.def("return_null_str", []() { return (char *) nullptr; }); - m.def("print_null_str", [](char *ptr) { std::cout << "Got null str : 0x" << std::hex << (uint64_t) ptr << std::endl; }); - - m.def("return_unique_ptr", []() -> std::unique_ptr { - StringList *result = new StringList(); - result->push_back("some value"); - return std::unique_ptr(result); - }); -} diff --git a/stormpy/resources/pybind11/example/example14.py b/stormpy/resources/pybind11/example/example14.py deleted file mode 100644 index c653e0cea..000000000 --- a/stormpy/resources/pybind11/example/example14.py +++ /dev/null @@ -1,50 +0,0 @@ -from __future__ import print_function -import sys - -sys.path.append('.') - -from example import StringList, print_opaque_list -from example import ClassWithSTLVecProperty -from example import return_void_ptr, print_void_ptr -from example import return_null_str, print_null_str -from example import return_unique_ptr -from example import Example1 - -##### - -l = StringList() -l.push_back("Element 1") -l.push_back("Element 2") -print_opaque_list(l) -print("Back element is %s" % l.back()) -for i, k in enumerate(l): - print("%i/%i : %s" % (i + 1, len(l), k)) -l.pop_back() -print_opaque_list(l) - -##### -cvp = ClassWithSTLVecProperty() -print_opaque_list(cvp.stringList) - -cvp.stringList = l -cvp.stringList.push_back("Element 3") -print_opaque_list(cvp.stringList) - -##### - -print_void_ptr(return_void_ptr()) -print_void_ptr(Example1()) # Should also work for other C++ types - -try: - print_void_ptr([1, 2, 3]) # This should not work -except Exception as e: - print("Caught expected exception: " + str(e)) - -print(return_null_str()) -print_null_str(return_null_str()) - -##### - -ptr = return_unique_ptr() -print(ptr) -print_opaque_list(ptr) diff --git a/stormpy/resources/pybind11/example/example14.ref b/stormpy/resources/pybind11/example/example14.ref deleted file mode 100644 index 44e682098..000000000 --- a/stormpy/resources/pybind11/example/example14.ref +++ /dev/null @@ -1,18 +0,0 @@ -Opaque list: [Element 1, Element 2] -Back element is Element 2 -1/2 : Element 1 -2/2 : Element 2 -Opaque list: [Element 1] -Opaque list: [] -Opaque list: [Element 1, Element 3] -Got void ptr : 0x1234 -Called Example1 default constructor.. -Got void ptr : 0x7f9ba0f3c430 -Called Example1 destructor (0) -Caught expected exception: Incompatible function arguments. The following argument types are supported: - 1. (capsule) -> NoneType - Invoked with: [1, 2, 3] -None -Got null str : 0x0 - -Opaque list: [some value] diff --git a/stormpy/resources/pybind11/example/example15.cpp b/stormpy/resources/pybind11/example/example15.cpp deleted file mode 100644 index acdd36823..000000000 --- a/stormpy/resources/pybind11/example/example15.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - example/example15.cpp -- pickle support - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -class Pickleable { -public: - Pickleable(const std::string &value) : m_value(value) { } - const std::string &value() const { return m_value; } - - void setExtra1(int extra1) { m_extra1 = extra1; } - void setExtra2(int extra2) { m_extra2 = extra2; } - int extra1() const { return m_extra1; } - int extra2() const { return m_extra2; } -private: - std::string m_value; - int m_extra1 = 0; - int m_extra2 = 0; -}; - -void init_ex15(py::module &m) { - py::class_(m, "Pickleable") - .def(py::init()) - .def("value", &Pickleable::value) - .def("extra1", &Pickleable::extra1) - .def("extra2", &Pickleable::extra2) - .def("setExtra1", &Pickleable::setExtra1) - .def("setExtra2", &Pickleable::setExtra2) - // For details on the methods below, refer to - // http://docs.python.org/3/library/pickle.html#pickling-class-instances - .def("__getstate__", [](const Pickleable &p) { - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(p.value(), p.extra1(), p.extra2()); - }) - .def("__setstate__", [](Pickleable &p, py::tuple t) { - if (t.size() != 3) - throw std::runtime_error("Invalid state!"); - /* Invoke the constructor (need to use in-place version) */ - new (&p) Pickleable(t[0].cast()); - - /* Assign any additional state */ - p.setExtra1(t[1].cast()); - p.setExtra2(t[2].cast()); - }); -} diff --git a/stormpy/resources/pybind11/example/example15.py b/stormpy/resources/pybind11/example/example15.py deleted file mode 100644 index 1810d3e2e..000000000 --- a/stormpy/resources/pybind11/example/example15.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import print_function -import sys - -sys.path.append('.') - -from example import Pickleable - -try: - import cPickle as pickle # Use cPickle on Python 2.7 -except ImportError: - import pickle - -p = Pickleable("test_value") -p.setExtra1(15) -p.setExtra2(48) - -data = pickle.dumps(p, 2) # Must use pickle protocol >= 2 -print("%s %i %i" % (p.value(), p.extra1(), p.extra2())) - -p2 = pickle.loads(data) -print("%s %i %i" % (p2.value(), p2.extra1(), p2.extra2())) diff --git a/stormpy/resources/pybind11/example/example15.ref b/stormpy/resources/pybind11/example/example15.ref deleted file mode 100644 index d804973a1..000000000 --- a/stormpy/resources/pybind11/example/example15.ref +++ /dev/null @@ -1,2 +0,0 @@ -test_value 15 48 -test_value 15 48 diff --git a/stormpy/resources/pybind11/example/example16.cpp b/stormpy/resources/pybind11/example/example16.cpp deleted file mode 100644 index 7b676a9dc..000000000 --- a/stormpy/resources/pybind11/example/example16.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - example/example16.cpp -- automatic upcasting for polymorphic types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -struct BaseClass { virtual ~BaseClass() {} }; -struct DerivedClass1 : BaseClass { }; -struct DerivedClass2 : BaseClass { }; - -void init_ex16(py::module &m) { - py::class_(m, "BaseClass").def(py::init<>()); - py::class_(m, "DerivedClass1").def(py::init<>()); - py::class_(m, "DerivedClass2").def(py::init<>()); - - m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); }); - m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); }); - m.def("return_none", []() -> BaseClass* { return nullptr; }); -} diff --git a/stormpy/resources/pybind11/example/example16.py b/stormpy/resources/pybind11/example/example16.py deleted file mode 100644 index b4bcb655d..000000000 --- a/stormpy/resources/pybind11/example/example16.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import print_function -import sys - -sys.path.append('.') - -from example import return_class_1 -from example import return_class_2 -from example import return_none - -print(type(return_class_1()).__name__) -print(type(return_class_2()).__name__) -print(type(return_none()).__name__) diff --git a/stormpy/resources/pybind11/example/example16.ref b/stormpy/resources/pybind11/example/example16.ref deleted file mode 100644 index 96003367b..000000000 --- a/stormpy/resources/pybind11/example/example16.ref +++ /dev/null @@ -1,3 +0,0 @@ -DerivedClass1 -DerivedClass2 -NoneType diff --git a/stormpy/resources/pybind11/example/example17.cpp b/stormpy/resources/pybind11/example/example17.cpp deleted file mode 100644 index 8fd4ad642..000000000 --- a/stormpy/resources/pybind11/example/example17.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - example/example17.cpp -- Usage of stl_binders functions - - Copyright (c) 2016 Sergey Lyskov - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -#include - -class El { -public: - El() = delete; - El(int v) : a(v) { } - - int a; -}; - -std::ostream & operator<<(std::ostream &s, El const&v) { - s << "El{" << v.a << '}'; - return s; -} - -void init_ex17(py::module &m) { - pybind11::class_(m, "El") - .def(pybind11::init()); - - pybind11::bind_vector(m, "VectorInt"); - pybind11::bind_vector(m, "VectorBool"); - - pybind11::bind_vector(m, "VectorEl"); - - pybind11::bind_vector>(m, "VectorVectorEl"); -} diff --git a/stormpy/resources/pybind11/example/example17.py b/stormpy/resources/pybind11/example/example17.py deleted file mode 100644 index feae30708..000000000 --- a/stormpy/resources/pybind11/example/example17.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function - -from example import VectorInt, El, VectorEl, VectorVectorEl, VectorBool - -v_int = VectorInt([0, 0]) -print(len(v_int)) - -print(bool(v_int)) - -v_int2 = VectorInt([0, 0]) -print(v_int == v_int2) - -v_int2[1] = 1 -print(v_int != v_int2) - -v_int2.append(2) -v_int2.append(3) -v_int2.insert(0, 1) -v_int2.insert(0, 2) -v_int2.insert(0, 3) -print(v_int2) - -v_int.append(99) -v_int2[2:-2] = v_int -print(v_int2) -del v_int2[1:3] -print(v_int2) -del v_int2[0] -print(v_int2) - -v_a = VectorEl() -v_a.append(El(1)) -v_a.append(El(2)) -print(v_a) - -vv_a = VectorVectorEl() -vv_a.append(v_a) -vv_b = vv_a[0] -print(vv_b) - -vv_c = VectorBool() -for i in range(10): - vv_c.append(i % 2 == 0) -for i in range(10): - if vv_c[i] != (i % 2 == 0): - print("Error!") -print(vv_c) diff --git a/stormpy/resources/pybind11/example/example17.ref b/stormpy/resources/pybind11/example/example17.ref deleted file mode 100644 index cc271f3a9..000000000 --- a/stormpy/resources/pybind11/example/example17.ref +++ /dev/null @@ -1,11 +0,0 @@ -2 -True -True -True -VectorInt[3, 2, 1, 0, 1, 2, 3] -VectorInt[3, 2, 0, 0, 99, 2, 3] -VectorInt[3, 0, 99, 2, 3] -VectorInt[0, 99, 2, 3] -VectorEl[El{1}, El{2}] -VectorEl[El{1}, El{2}] -VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0] diff --git a/stormpy/resources/pybind11/example/example2.cpp b/stormpy/resources/pybind11/example/example2.cpp deleted file mode 100644 index 4b15823f2..000000000 --- a/stormpy/resources/pybind11/example/example2.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - example/example2.cpp2 -- singleton design pattern, static functions and - variables, passing and interacting with Python types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - -#ifdef _WIN32 -# include -# include -#endif - -class Example2 { -public: - static Example2 *new_instance() { - return new Example2(); - } - ~Example2() { - std::cout << "Destructing Example2" << std::endl; - } - - /* Create and return a Python dictionary */ - py::dict get_dict() { - py::dict dict; - dict[py::str("key")] = py::str("value"); - return dict; - } - - /* Create and return a Python set */ - py::set get_set() { - py::set set; - set.add(py::str("key1")); - set.add(py::str("key2")); - return set; - } - - /* Create and return a C++ dictionary */ - std::map get_dict_2() { - std::map result; - result["key"] = "value"; - return result; - } - - /* Create and return a C++ set */ - std::set get_set_2() { - std::set result; - result.insert("key1"); - result.insert("key2"); - return result; - } - - /* Create, manipulate, and return a Python list */ - py::list get_list() { - py::list list; - list.append(py::str("value")); - cout << "Entry at positon 0: " << py::object(list[0]) << endl; - list[0] = py::str("overwritten"); - return list; - } - - /* C++ STL data types are automatically casted */ - std::vector get_list_2() { - std::vector list; - list.push_back(L"value"); - return list; - } - - /* C++ STL data types are automatically casted */ - std::array get_array() { - return std::array {{ "array entry 1" , "array entry 2"}}; - } - - /* Easily iterate over a dictionary using a C++11 range-based for loop */ - void print_dict(py::dict dict) { - for (auto item : dict) - std::cout << "key: " << item.first << ", value=" << item.second << std::endl; - } - - /* Easily iterate over a set using a C++11 range-based for loop */ - void print_set(py::set set) { - for (auto item : set) - std::cout << "key: " << item << std::endl; - } - - /* Easily iterate over a list using a C++11 range-based for loop */ - void print_list(py::list list) { - int index = 0; - for (auto item : list) - std::cout << "list item " << index++ << ": " << item << std::endl; - } - - /* STL data types (such as maps) are automatically casted from Python */ - void print_dict_2(const std::map &dict) { - for (auto item : dict) - std::cout << "key: " << item.first << ", value=" << item.second << std::endl; - } - - /* STL data types (such as sets) are automatically casted from Python */ - void print_set_2(const std::set &set) { - for (auto item : set) - std::cout << "key: " << item << std::endl; - } - - /* STL data types (such as vectors) are automatically casted from Python */ - void print_list_2(std::vector &list) { -#ifdef _WIN32 /* Can't easily mix cout and wcout on Windows */ - _setmode(_fileno(stdout), _O_TEXT); -#endif - int index = 0; - for (auto item : list) - std::wcout << L"list item " << index++ << L": " << item << std::endl; - } - - /* pybind automatically translates between C++11 and Python tuples */ - std::pair pair_passthrough(std::pair input) { - return std::make_pair(input.second, input.first); - } - - /* pybind automatically translates between C++11 and Python tuples */ - std::tuple tuple_passthrough(std::tuple input) { - return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input)); - } - - /* STL data types (such as arrays) are automatically casted from Python */ - void print_array(std::array &array) { - int index = 0; - for (auto item : array) - std::cout << "array item " << index++ << ": " << item << std::endl; - } - - void throw_exception() { - throw std::runtime_error("This exception was intentionally thrown."); - } - - static int value; - static const int value2; -}; - -int Example2::value = 0; -const int Example2::value2 = 5; - -void init_ex2(py::module &m) { - /* No constructor is explicitly defined below. An exception is raised when - trying to construct it directly from Python */ - py::class_(m, "Example2", "Example 2 documentation") - .def("get_dict", &Example2::get_dict, "Return a Python dictionary") - .def("get_dict_2", &Example2::get_dict_2, "Return a C++ dictionary") - .def("get_list", &Example2::get_list, "Return a Python list") - .def("get_list_2", &Example2::get_list_2, "Return a C++ list") - .def("get_set", &Example2::get_set, "Return a Python set") - .def("get_set2", &Example2::get_set_2, "Return a C++ set") - .def("get_array", &Example2::get_array, "Return a C++ array") - .def("print_dict", &Example2::print_dict, "Print entries of a Python dictionary") - .def("print_dict_2", &Example2::print_dict_2, "Print entries of a C++ dictionary") - .def("print_set", &Example2::print_set, "Print entries of a Python set") - .def("print_set_2", &Example2::print_set_2, "Print entries of a C++ set") - .def("print_list", &Example2::print_list, "Print entries of a Python list") - .def("print_list_2", &Example2::print_list_2, "Print entries of a C++ list") - .def("print_array", &Example2::print_array, "Print entries of a C++ array") - .def("pair_passthrough", &Example2::pair_passthrough, "Return a pair in reversed order") - .def("tuple_passthrough", &Example2::tuple_passthrough, "Return a triple in reversed order") - .def("throw_exception", &Example2::throw_exception, "Throw an exception") - .def_static("new_instance", &Example2::new_instance, "Return an instance") - .def_readwrite_static("value", &Example2::value, "Static value member") - .def_readonly_static("value2", &Example2::value2, "Static value member (readonly)"); -} diff --git a/stormpy/resources/pybind11/example/example2.py b/stormpy/resources/pybind11/example/example2.py deleted file mode 100755 index d335acc3d..000000000 --- a/stormpy/resources/pybind11/example/example2.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys, pydoc -sys.path.append('.') - -import example -from example import Example2 - -Example2.value = 15 -print(Example2.value) -print(Example2.value2) - -try: - Example2() -except Exception as e: - print(e) - -try: - Example2.value2 = 15 -except Exception as e: - print(e) - -instance = Example2.new_instance() - -dict_result = instance.get_dict() -dict_result['key2'] = 'value2' -instance.print_dict(dict_result) - -dict_result = instance.get_dict_2() -dict_result['key2'] = 'value2' -instance.print_dict_2(dict_result) - -set_result = instance.get_set() -set_result.add('key3') -instance.print_set(set_result) - -set_result = instance.get_set2() -set_result.add('key3') -instance.print_set_2(set_result) - -list_result = instance.get_list() -list_result.append('value2') -instance.print_list(list_result) - -list_result = instance.get_list_2() -list_result.append('value2') -instance.print_list_2(list_result) - -array_result = instance.get_array() -print(array_result) -instance.print_array(array_result) - -try: - instance.throw_exception() -except Exception as e: - print(e) - -print(instance.pair_passthrough((True, "test"))) -print(instance.tuple_passthrough((True, "test", 5))) - -print(pydoc.render_doc(Example2, "Help on %s")) - -print("__name__(example) = %s" % example.__name__) -print("__name__(example.Example2) = %s" % Example2.__name__) -print("__module__(example.Example2) = %s" % Example2.__module__) -print("__name__(example.Example2.get_set) = %s" % Example2.get_set.__name__) -print("__module__(example.Example2.get_set) = %s" % Example2.get_set.__module__) diff --git a/stormpy/resources/pybind11/example/example2.ref b/stormpy/resources/pybind11/example/example2.ref deleted file mode 100644 index fd6c83dda..000000000 --- a/stormpy/resources/pybind11/example/example2.ref +++ /dev/null @@ -1,137 +0,0 @@ -15 -5 -example.Example2: No constructor defined! -can't set attribute -key: key2, value=value2 -key: key, value=value -key: key, value=value -key: key2, value=value2 -key: key3 -key: key2 -key: key1 -key: key1 -key: key2 -key: key3 -Entry at positon 0: value -list item 0: overwritten -list item 1: value2 -list item 0: value -list item 1: value2 -[u'array entry 1', u'array entry 2'] -array item 0: array entry 1 -array item 1: array entry 2 -This exception was intentionally thrown. -(u'test', True) -(5L, u'test', True) -Help on class Example2 in module example - -class EExxaammppllee22(__builtin__.object) - | Example 2 documentation - | - | Methods defined here: - | - | ____iinniitt____(...) - | x.__init__(...) initializes x; see help(type(x)) for signature - | - | ggeett__aarrrraayy(...) - | Signature : (example.Example2) -> list[2] - | - | Return a C++ array - | - | ggeett__ddiicctt(...) - | Signature : (example.Example2) -> dict - | - | Return a Python dictionary - | - | ggeett__ddiicctt__22(...) - | Signature : (example.Example2) -> dict - | - | Return a C++ dictionary - | - | ggeett__lliisstt(...) - | Signature : (example.Example2) -> list - | - | Return a Python list - | - | ggeett__lliisstt__22(...) - | Signature : (example.Example2) -> list - | - | Return a C++ list - | - | ggeett__sseett(...) - | Signature : (example.Example2) -> set - | - | Return a Python set - | - | ggeett__sseett22(...) - | Signature : (example.Example2) -> set - | - | Return a C++ set - | - | ppaaiirr__ppaasssstthhrroouugghh(...) - | Signature : (example.Example2, (bool, unicode)) -> (unicode, bool) - | - | Return a pair in reversed order - | - | pprriinntt__aarrrraayy(...) - | Signature : (example.Example2, list[2]) -> NoneType - | - | Print entries of a C++ array - | - | pprriinntt__ddiicctt(...) - | Signature : (example.Example2, dict) -> NoneType - | - | Print entries of a Python dictionary - | - | pprriinntt__ddiicctt__22(...) - | Signature : (example.Example2, dict) -> NoneType - | - | Print entries of a C++ dictionary - | - | pprriinntt__lliisstt(...) - | Signature : (example.Example2, list) -> NoneType - | - | Print entries of a Python list - | - | pprriinntt__lliisstt__22(...) - | Signature : (example.Example2, list) -> NoneType - | - | Print entries of a C++ list - | - | pprriinntt__sseett(...) - | Signature : (example.Example2, set) -> NoneType - | - | Print entries of a Python set - | - | pprriinntt__sseett__22(...) - | Signature : (example.Example2, set) -> NoneType - | - | Print entries of a C++ set - | - | tthhrrooww__eexxcceeppttiioonn(...) - | Signature : (example.Example2) -> NoneType - | - | Throw an exception - | - | ttuuppllee__ppaasssstthhrroouugghh(...) - | Signature : (example.Example2, (bool, unicode, int)) -> (int, unicode, bool) - | - | Return a triple in reversed order - | - | ---------------------------------------------------------------------- - | Data and other attributes defined here: - | - | ____nneeww____ = - | T.__new__(S, ...) -> a new object with type S, a subtype of T - | - | nneeww__iinnssttaannccee = - | Signature : () -> example.Example2 - | - | Return an instance - -__name__(example) = example -__name__(example.Example2) = Example2 -__module__(example.Example2) = example -__name__(example.Example2.get_set) = get_set -__module__(example.Example2.get_set) = example -Destructing Example2 diff --git a/stormpy/resources/pybind11/example/example3.cpp b/stormpy/resources/pybind11/example/example3.cpp deleted file mode 100644 index af956b13e..000000000 --- a/stormpy/resources/pybind11/example/example3.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - example/example3.cpp -- operator overloading - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - -class Vector2 { -public: - Vector2(float x, float y) : x(x), y(y) { std::cout << "Value constructor" << std::endl; } - Vector2(const Vector2 &v) : x(v.x), y(v.y) { std::cout << "Copy constructor" << std::endl; } - Vector2(Vector2 &&v) : x(v.x), y(v.y) { std::cout << "Move constructor" << std::endl; v.x = v.y = 0; } - ~Vector2() { std::cout << "Destructor." << std::endl; } - - std::string toString() const { - return "[" + std::to_string(x) + ", " + std::to_string(y) + "]"; - } - - void operator=(const Vector2 &v) { - cout << "Assignment operator" << endl; - x = v.x; - y = v.y; - } - - void operator=(Vector2 &&v) { - cout << "Move assignment operator" << endl; - x = v.x; y = v.y; v.x = v.y = 0; - } - - Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); } - Vector2 operator-(const Vector2 &v) const { return Vector2(x - v.x, y - v.y); } - Vector2 operator-(float value) const { return Vector2(x - value, y - value); } - Vector2 operator+(float value) const { return Vector2(x + value, y + value); } - Vector2 operator*(float value) const { return Vector2(x * value, y * value); } - Vector2 operator/(float value) const { return Vector2(x / value, y / value); } - Vector2& operator+=(const Vector2 &v) { x += v.x; y += v.y; return *this; } - Vector2& operator-=(const Vector2 &v) { x -= v.x; y -= v.y; return *this; } - Vector2& operator*=(float v) { x *= v; y *= v; return *this; } - Vector2& operator/=(float v) { x /= v; y /= v; return *this; } - - friend Vector2 operator+(float f, const Vector2 &v) { return Vector2(f + v.x, f + v.y); } - friend Vector2 operator-(float f, const Vector2 &v) { return Vector2(f - v.x, f - v.y); } - friend Vector2 operator*(float f, const Vector2 &v) { return Vector2(f * v.x, f * v.y); } - friend Vector2 operator/(float f, const Vector2 &v) { return Vector2(f / v.x, f / v.y); } -private: - float x, y; -}; - - -void init_ex3(py::module &m) { - py::class_(m, "Vector2") - .def(py::init()) - .def(py::self + py::self) - .def(py::self + float()) - .def(py::self - py::self) - .def(py::self - float()) - .def(py::self * float()) - .def(py::self / float()) - .def(py::self += py::self) - .def(py::self -= py::self) - .def(py::self *= float()) - .def(py::self /= float()) - .def(float() + py::self) - .def(float() - py::self) - .def(float() * py::self) - .def(float() / py::self) - .def("__str__", &Vector2::toString); - - m.attr("Vector") = m.attr("Vector2"); -} diff --git a/stormpy/resources/pybind11/example/example3.py b/stormpy/resources/pybind11/example/example3.py deleted file mode 100755 index 591ae391c..000000000 --- a/stormpy/resources/pybind11/example/example3.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import Vector2, Vector - -v1 = Vector2(1, 2) -v2 = Vector(3, -1) - -print("v1 = " + str(v1)) -print("v2 = " + str(v2)) -print("v1+v2 = " + str(v1+v2)) -print("v1-v2 = " + str(v1-v2)) -print("v1-8 = " + str(v1-8)) -print("v1+8 = " + str(v1+8)) -print("v1*8 = " + str(v1*8)) -print("v1/8 = " + str(v1/8)) -print("8-v1 = " + str(8-v1)) -print("8+v1 = " + str(8+v1)) -print("8*v1 = " + str(8*v1)) -print("8/v1 = " + str(8/v1)) - -v1 += v2 -v1 *= 2 - -print("(v1+v2)*2 = " + str(v1)) diff --git a/stormpy/resources/pybind11/example/example3.ref b/stormpy/resources/pybind11/example/example3.ref deleted file mode 100644 index 8f2c29886..000000000 --- a/stormpy/resources/pybind11/example/example3.ref +++ /dev/null @@ -1,57 +0,0 @@ -Value constructor -Value constructor -v1 = [1.000000, 2.000000] -v2 = [3.000000, -1.000000] -Value constructor -Move constructor -Destructor. -Destructor. -v1+v2 = [4.000000, 1.000000] -Value constructor -Move constructor -Destructor. -Destructor. -v1-v2 = [-2.000000, 3.000000] -Value constructor -Move constructor -Destructor. -Destructor. -v1-8 = [-7.000000, -6.000000] -Value constructor -Move constructor -Destructor. -Destructor. -v1+8 = [9.000000, 10.000000] -Value constructor -Move constructor -Destructor. -Destructor. -v1*8 = [8.000000, 16.000000] -Value constructor -Move constructor -Destructor. -Destructor. -v1/8 = [0.125000, 0.250000] -Value constructor -Move constructor -Destructor. -Destructor. -8-v1 = [7.000000, 6.000000] -Value constructor -Move constructor -Destructor. -Destructor. -8+v1 = [9.000000, 10.000000] -Value constructor -Move constructor -Destructor. -Destructor. -8*v1 = [8.000000, 16.000000] -Value constructor -Move constructor -Destructor. -Destructor. -8/v1 = [8.000000, 4.000000] -(v1+v2)*2 = [8.000000, 2.000000] -Destructor. -Destructor. diff --git a/stormpy/resources/pybind11/example/example4.cpp b/stormpy/resources/pybind11/example/example4.cpp deleted file mode 100644 index 7e17864e0..000000000 --- a/stormpy/resources/pybind11/example/example4.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - example/example4.cpp -- global constants and functions, enumerations, raw byte strings - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -enum EMyEnumeration { - EFirstEntry = 1, - ESecondEntry -}; - -class Example4 { -public: - enum EMode { - EFirstMode = 1, - ESecondMode - }; - - static EMode test_function(EMode mode) { - std::cout << "Example4::test_function(enum=" << mode << ")" << std::endl; - return mode; - } -}; - -bool test_function1() { - std::cout << "test_function()" << std::endl; - return false; -} - -void test_function2(EMyEnumeration k) { - std::cout << "test_function(enum=" << k << ")" << std::endl; -} - -float test_function3(int i) { - std::cout << "test_function(" << i << ")" << std::endl; - return (float) i / 2.f; -} - -py::bytes return_bytes() { - const char *data = "\x01\x00\x02\x00"; - return std::string(data, 4); -} - -void print_bytes(py::bytes bytes) { - std::string value = (std::string) bytes; - for (size_t i = 0; i < value.length(); ++i) - std::cout << "bytes[" << i << "]=" << (int) value[i] << std::endl; -} - -void init_ex4(py::module &m) { - m.def("test_function", &test_function1); - m.def("test_function", &test_function2); - m.def("test_function", &test_function3); - m.attr("some_constant") = py::int_(14); - - py::enum_(m, "EMyEnumeration") - .value("EFirstEntry", EFirstEntry) - .value("ESecondEntry", ESecondEntry) - .export_values(); - - py::class_ ex4_class(m, "Example4"); - ex4_class.def_static("test_function", &Example4::test_function); - py::enum_(ex4_class, "EMode") - .value("EFirstMode", Example4::EFirstMode) - .value("ESecondMode", Example4::ESecondMode) - .export_values(); - - m.def("return_bytes", &return_bytes); - m.def("print_bytes", &print_bytes); -} diff --git a/stormpy/resources/pybind11/example/example4.py b/stormpy/resources/pybind11/example/example4.py deleted file mode 100755 index 37d952f2b..000000000 --- a/stormpy/resources/pybind11/example/example4.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import test_function -from example import some_constant -from example import EMyEnumeration -from example import EFirstEntry -from example import Example4 -from example import return_bytes -from example import print_bytes - -print(EMyEnumeration) -print(EMyEnumeration.EFirstEntry) -print(EMyEnumeration.ESecondEntry) -print(EFirstEntry) - -print(test_function()) -print(test_function(7)) -print(test_function(EMyEnumeration.EFirstEntry)) -print(test_function(EMyEnumeration.ESecondEntry)) -print("enum->integer = %i" % int(EMyEnumeration.ESecondEntry)) -print("integer->enum = %s" % str(EMyEnumeration(2))) - -print("A constant = " + str(some_constant)) - -print(Example4.EMode) -print(Example4.EMode.EFirstMode) -print(Example4.EFirstMode) -Example4.test_function(Example4.EFirstMode) - -print("Equality test 1: " + str( - Example4.test_function(Example4.EFirstMode) == - Example4.test_function(Example4.EFirstMode))) - -print("Inequality test 1: " + str( - Example4.test_function(Example4.EFirstMode) != - Example4.test_function(Example4.EFirstMode))) - -print("Equality test 2: " + str( - Example4.test_function(Example4.EFirstMode) == - Example4.test_function(Example4.ESecondMode))) - -print("Inequality test 2: " + str( - Example4.test_function(Example4.EFirstMode) != - Example4.test_function(Example4.ESecondMode))) - -x = { - Example4.test_function(Example4.EFirstMode): 1, - Example4.test_function(Example4.ESecondMode): 2 -} - -x[Example4.test_function(Example4.EFirstMode)] = 3 -x[Example4.test_function(Example4.ESecondMode)] = 4 -print("Hashing test = " + str(x)) - -print_bytes(return_bytes()) diff --git a/stormpy/resources/pybind11/example/example4.ref b/stormpy/resources/pybind11/example/example4.ref deleted file mode 100644 index a21f62c93..000000000 --- a/stormpy/resources/pybind11/example/example4.ref +++ /dev/null @@ -1,40 +0,0 @@ - -EMyEnumeration.EFirstEntry -EMyEnumeration.ESecondEntry -EMyEnumeration.EFirstEntry -test_function() -False -test_function(7) -3.5 -test_function(enum=1) -None -test_function(enum=2) -None -enum->integer = 2 -integer->enum = EMyEnumeration.ESecondEntry -A constant = 14 - -EMode.EFirstMode -EMode.EFirstMode -Example4::test_function(enum=1) -Example4::test_function(enum=1) -Example4::test_function(enum=1) -Equality test 1: True -Example4::test_function(enum=1) -Example4::test_function(enum=1) -Inequality test 1: False -Example4::test_function(enum=1) -Example4::test_function(enum=2) -Equality test 2: False -Example4::test_function(enum=1) -Example4::test_function(enum=2) -Inequality test 2: True -Example4::test_function(enum=1) -Example4::test_function(enum=2) -Example4::test_function(enum=1) -Example4::test_function(enum=2) -Hashing test = {EMode.EFirstMode: 3, EMode.ESecondMode: 4} -bytes[0]=1 -bytes[1]=0 -bytes[2]=2 -bytes[3]=0 diff --git a/stormpy/resources/pybind11/example/example5.cpp b/stormpy/resources/pybind11/example/example5.cpp deleted file mode 100644 index 0e1d2cd13..000000000 --- a/stormpy/resources/pybind11/example/example5.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - example/example5.cpp -- inheritance, callbacks, acquiring and releasing the - global interpreter lock - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - - -class Pet { -public: - Pet(const std::string &name, const std::string &species) - : m_name(name), m_species(species) {} - std::string name() const { return m_name; } - std::string species() const { return m_species; } -private: - std::string m_name; - std::string m_species; -}; - -class Dog : public Pet { -public: - Dog(const std::string &name) : Pet(name, "dog") {} - void bark() const { std::cout << "Woof!" << std::endl; } -}; - -class Rabbit : public Pet { -public: - Rabbit(const std::string &name) : Pet(name, "parrot") {} -}; - -void pet_print(const Pet &pet) { - std::cout << pet.name() + " is a " + pet.species() << std::endl; -} - -void dog_bark(const Dog &dog) { - dog.bark(); -} - -bool test_callback1(py::object func) { - func(); - return false; -} - -int test_callback2(py::object func) { - py::object result = func("Hello", 'x', true, 5); - return result.cast(); -} - -void test_callback3(const std::function &func) { - cout << "func(43) = " << func(43)<< std::endl; -} - -std::function test_callback4() { - return [](int i) { return i+1; }; -} - -py::cpp_function test_callback5() { - return py::cpp_function([](int i) { return i+1; }, - py::arg("number")); -} - -void init_ex5(py::module &m) { - py::class_ pet_class(m, "Pet"); - pet_class - .def(py::init()) - .def("name", &Pet::name) - .def("species", &Pet::species); - - /* One way of declaring a subclass relationship: reference parent's class_ object */ - py::class_(m, "Dog", pet_class) - .def(py::init()); - - /* Another way of declaring a subclass relationship: reference parent's C++ type */ - py::class_(m, "Rabbit", py::base()) - .def(py::init()); - - m.def("pet_print", pet_print); - m.def("dog_bark", dog_bark); - - m.def("test_callback1", &test_callback1); - m.def("test_callback2", &test_callback2); - m.def("test_callback3", &test_callback3); - m.def("test_callback4", &test_callback4); - m.def("test_callback5", &test_callback5); - - /* Test cleanup of lambda closure */ - - struct Payload { - Payload() { - std::cout << "Payload constructor" << std::endl; - } - ~Payload() { - std::cout << "Payload destructor" << std::endl; - } - Payload(const Payload &) { - std::cout << "Payload copy constructor" << std::endl; - } - Payload(Payload &&) { - std::cout << "Payload move constructor" << std::endl; - } - }; - - m.def("test_cleanup", []() -> std::function { - Payload p; - - return [p]() { - /* p should be cleaned up when the returned function is garbage collected */ - }; - }); -} diff --git a/stormpy/resources/pybind11/example/example5.py b/stormpy/resources/pybind11/example/example5.py deleted file mode 100755 index 1361c7519..000000000 --- a/stormpy/resources/pybind11/example/example5.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -from functools import partial -import sys -sys.path.append('.') - -from example import Pet -from example import Dog -from example import Rabbit -from example import dog_bark -from example import pet_print - -polly = Pet('Polly', 'parrot') -molly = Dog('Molly') -roger = Rabbit('Rabbit') -print(roger.name() + " is a " + roger.species()) -pet_print(roger) -print(polly.name() + " is a " + polly.species()) -pet_print(polly) -print(molly.name() + " is a " + molly.species()) -pet_print(molly) -dog_bark(molly) -try: - dog_bark(polly) -except Exception as e: - print('The following error is expected: ' + str(e)) - -from example import test_callback1 -from example import test_callback2 -from example import test_callback3 -from example import test_callback4 -from example import test_callback5 -from example import test_cleanup - -def func1(): - print('Callback function 1 called!') - -def func2(a, b, c, d): - print('Callback function 2 called : ' + str(a) + ", " + str(b) + ", " + str(c) + ", "+ str(d)) - return d - -def func3(a): - print('Callback function 3 called : ' + str(a)) - -print(test_callback1(func1)) -print(test_callback2(func2)) -print(test_callback1(partial(func2, "Hello", "from", "partial", "object"))) -print(test_callback1(partial(func3, "Partial object with one argument"))) - -test_callback3(lambda i: i + 1) -f = test_callback4() -print("func(43) = %i" % f(43)) -f = test_callback5() -print("func(number=43) = %i" % f(number=43)) - -test_cleanup() diff --git a/stormpy/resources/pybind11/example/example5.ref b/stormpy/resources/pybind11/example/example5.ref deleted file mode 100644 index f32ba3af1..000000000 --- a/stormpy/resources/pybind11/example/example5.ref +++ /dev/null @@ -1,27 +0,0 @@ -Rabbit is a parrot -Polly is a parrot -Molly is a dog -Woof! -func(43) = 44 -Payload constructor -Payload copy constructor -Payload move constructor -Payload destructor -Payload destructor -Payload destructor -Rabbit is a parrot -Polly is a parrot -Molly is a dog -The following error is expected: Incompatible function arguments. The following argument types are supported: - 1. (example.Dog) -> NoneType - Invoked with: -Callback function 1 called! -False -Callback function 2 called : Hello, x, True, 5 -5 -Callback function 2 called : Hello, from, partial, object -False -Callback function 3 called : Partial object with one argument -False -func(43) = 44 -func(number=43) = 44 diff --git a/stormpy/resources/pybind11/example/example6.cpp b/stormpy/resources/pybind11/example/example6.cpp deleted file mode 100644 index e0bfb9e70..000000000 --- a/stormpy/resources/pybind11/example/example6.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - example/example6.cpp -- supporting Pythons' sequence protocol, iterators, - etc. - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include -#include - -class Sequence { -public: - Sequence(size_t size) : m_size(size) { - std::cout << "Value constructor: Creating a sequence with " << m_size << " entries" << std::endl; - m_data = new float[size]; - memset(m_data, 0, sizeof(float) * size); - } - - Sequence(const std::vector &value) : m_size(value.size()) { - std::cout << "Value constructor: Creating a sequence with " << m_size << " entries" << std::endl; - m_data = new float[m_size]; - memcpy(m_data, &value[0], sizeof(float) * m_size); - } - - Sequence(const Sequence &s) : m_size(s.m_size) { - std::cout << "Copy constructor: Creating a sequence with " << m_size << " entries" << std::endl; - m_data = new float[m_size]; - memcpy(m_data, s.m_data, sizeof(float)*m_size); - } - - Sequence(Sequence &&s) : m_size(s.m_size), m_data(s.m_data) { - std::cout << "Move constructor: Creating a sequence with " << m_size << " entries" << std::endl; - s.m_size = 0; - s.m_data = nullptr; - } - - ~Sequence() { - std::cout << "Freeing a sequence with " << m_size << " entries" << std::endl; - delete[] m_data; - } - - Sequence &operator=(const Sequence &s) { - std::cout << "Assignment operator: Creating a sequence with " << s.m_size << " entries" << std::endl; - delete[] m_data; - m_size = s.m_size; - m_data = new float[m_size]; - memcpy(m_data, s.m_data, sizeof(float)*m_size); - return *this; - } - - Sequence &operator=(Sequence &&s) { - std::cout << "Move assignment operator: Creating a sequence with " << s.m_size << " entries" << std::endl; - if (&s != this) { - delete[] m_data; - m_size = s.m_size; - m_data = s.m_data; - s.m_size = 0; - s.m_data = nullptr; - } - return *this; - } - - bool operator==(const Sequence &s) const { - if (m_size != s.size()) - return false; - for (size_t i=0; i seq(m, "Sequence"); - - seq.def(py::init()) - .def(py::init&>()) - /// Bare bones interface - .def("__getitem__", [](const Sequence &s, size_t i) { - if (i >= s.size()) - throw py::index_error(); - return s[i]; - }) - .def("__setitem__", [](Sequence &s, size_t i, float v) { - if (i >= s.size()) - throw py::index_error(); - s[i] = v; - }) - .def("__len__", &Sequence::size) - /// Optional sequence protocol operations - .def("__iter__", [](const Sequence &s) { return py::make_iterator(s.begin(), s.end()); }, - py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def("__contains__", [](const Sequence &s, float v) { return s.contains(v); }) - .def("__reversed__", [](const Sequence &s) -> Sequence { return s.reversed(); }) - /// Slicing protocol (optional) - .def("__getitem__", [](const Sequence &s, py::slice slice) -> Sequence* { - size_t start, stop, step, slicelength; - if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) - throw py::error_already_set(); - Sequence *seq = new Sequence(slicelength); - for (size_t i=0; i(seq, "Iterator") - .def("__iter__", [](PySequenceIterator &it) -> PySequenceIterator& { return it; }) - .def("__next__", &PySequenceIterator::next); - - On the actual Sequence object, the iterator would be constructed as follows: - .def("__iter__", [](py::object s) { return PySequenceIterator(s.cast(), s); }) -#endif -} diff --git a/stormpy/resources/pybind11/example/example6.py b/stormpy/resources/pybind11/example/example6.py deleted file mode 100755 index 5a014dda9..000000000 --- a/stormpy/resources/pybind11/example/example6.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import Sequence - -s = Sequence(5) -print("s = " + str(s)) -print("len(s) = " + str(len(s))) -print("s[0], s[3] = %f %f" % (s[0], s[3])) -print('12.34 in s: ' + str(12.34 in s)) -s[0], s[3] = 12.34, 56.78 -print('12.34 in s: ' + str(12.34 in s)) -print("s[0], s[3] = %f %f" % (s[0], s[3])) -rev = reversed(s) -rev2 = s[::-1] -print("rev[0], rev[1], rev[2], rev[3], rev[4] = %f %f %f %f %f" % (rev[0], rev[1], rev[2], rev[3], rev[4])) - -for i in rev: - print(i, end=' ') -print('') -for i in rev2: - print(i, end=' ') -print('') -print(rev == rev2) -rev[0::2] = Sequence([2.0, 2.0, 2.0]) -for i in rev: - print(i, end=' ') -print('') diff --git a/stormpy/resources/pybind11/example/example6.ref b/stormpy/resources/pybind11/example/example6.ref deleted file mode 100644 index c02dc76af..000000000 --- a/stormpy/resources/pybind11/example/example6.ref +++ /dev/null @@ -1,21 +0,0 @@ -Value constructor: Creating a sequence with 5 entries -s = -len(s) = 5 -s[0], s[3] = 0.000000 0.000000 -12.34 in s: False -12.34 in s: True -s[0], s[3] = 12.340000 56.779999 -Value constructor: Creating a sequence with 5 entries -Move constructor: Creating a sequence with 5 entries -Freeing a sequence with 0 entries -Value constructor: Creating a sequence with 5 entries -rev[0], rev[1], rev[2], rev[3], rev[4] = 0.000000 56.779999 0.000000 0.000000 12.340000 -0.0 56.7799987793 0.0 0.0 12.3400001526 -0.0 56.7799987793 0.0 0.0 12.3400001526 -True -Value constructor: Creating a sequence with 3 entries -Freeing a sequence with 3 entries -2.0 56.7799987793 2.0 0.0 2.0 -Freeing a sequence with 5 entries -Freeing a sequence with 5 entries -Freeing a sequence with 5 entries diff --git a/stormpy/resources/pybind11/example/example7.cpp b/stormpy/resources/pybind11/example/example7.cpp deleted file mode 100644 index 6aabf1c1c..000000000 --- a/stormpy/resources/pybind11/example/example7.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - example/example7.cpp -- supporting Pythons' buffer protocol - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -class Matrix { -public: - Matrix(size_t rows, size_t cols) : m_rows(rows), m_cols(cols) { - std::cout << "Value constructor: Creating a " << rows << "x" << cols << " matrix " << std::endl; - m_data = new float[rows*cols]; - memset(m_data, 0, sizeof(float) * rows * cols); - } - - Matrix(const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) { - std::cout << "Copy constructor: Creating a " << m_rows << "x" << m_cols << " matrix " << std::endl; - m_data = new float[m_rows * m_cols]; - memcpy(m_data, s.m_data, sizeof(float) * m_rows * m_cols); - } - - Matrix(Matrix &&s) : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) { - std::cout << "Move constructor: Creating a " << m_rows << "x" << m_cols << " matrix " << std::endl; - s.m_rows = 0; - s.m_cols = 0; - s.m_data = nullptr; - } - - ~Matrix() { - std::cout << "Freeing a " << m_rows << "x" << m_cols << " matrix " << std::endl; - delete[] m_data; - } - - Matrix &operator=(const Matrix &s) { - std::cout << "Assignment operator : Creating a " << s.m_rows << "x" << s.m_cols << " matrix " << std::endl; - delete[] m_data; - m_rows = s.m_rows; - m_cols = s.m_cols; - m_data = new float[m_rows * m_cols]; - memcpy(m_data, s.m_data, sizeof(float) * m_rows * m_cols); - return *this; - } - - Matrix &operator=(Matrix &&s) { - std::cout << "Move assignment operator : Creating a " << s.m_rows << "x" << s.m_cols << " matrix " << std::endl; - if (&s != this) { - delete[] m_data; - m_rows = s.m_rows; m_cols = s.m_cols; m_data = s.m_data; - s.m_rows = 0; s.m_cols = 0; s.m_data = nullptr; - } - return *this; - } - - float operator()(size_t i, size_t j) const { - return m_data[i*m_cols + j]; - } - - float &operator()(size_t i, size_t j) { - return m_data[i*m_cols + j]; - } - - float *data() { return m_data; } - - size_t rows() const { return m_rows; } - size_t cols() const { return m_cols; } -private: - size_t m_rows; - size_t m_cols; - float *m_data; -}; - -void init_ex7(py::module &m) { - py::class_ mtx(m, "Matrix"); - - mtx.def(py::init()) - /// Construct from a buffer - .def("__init__", [](Matrix &v, py::buffer b) { - py::buffer_info info = b.request(); - if (info.format != py::format_descriptor::value || info.ndim != 2) - throw std::runtime_error("Incompatible buffer format!"); - new (&v) Matrix(info.shape[0], info.shape[1]); - memcpy(v.data(), info.ptr, sizeof(float) * v.rows() * v.cols()); - }) - - .def("rows", &Matrix::rows) - .def("cols", &Matrix::cols) - - /// Bare bones interface - .def("__getitem__", [](const Matrix &m, std::pair i) { - if (i.first >= m.rows() || i.second >= m.cols()) - throw py::index_error(); - return m(i.first, i.second); - }) - .def("__setitem__", [](Matrix &m, std::pair i, float v) { - if (i.first >= m.rows() || i.second >= m.cols()) - throw py::index_error(); - m(i.first, i.second) = v; - }) - /// Provide buffer access - .def_buffer([](Matrix &m) -> py::buffer_info { - return py::buffer_info( - m.data(), /* Pointer to buffer */ - sizeof(float), /* Size of one scalar */ - py::format_descriptor::value, /* Python struct-style format descriptor */ - 2, /* Number of dimensions */ - { m.rows(), m.cols() }, /* Buffer dimensions */ - { sizeof(float) * m.rows(), /* Strides (in bytes) for each index */ - sizeof(float) } - ); - }); -} diff --git a/stormpy/resources/pybind11/example/example7.py b/stormpy/resources/pybind11/example/example7.py deleted file mode 100755 index 62d330174..000000000 --- a/stormpy/resources/pybind11/example/example7.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import Matrix - -try: - import numpy as np -except ImportError: - print('NumPy missing') - exit(0) - -m = Matrix(5, 5) - -print(m[2, 3]) -m[2, 3] = 4 -print(m[2, 3]) - -m2 = np.array(m, copy=False) -print(m2) -print(m2[2, 3]) -m2[2, 3] = 5 -print(m[2, 3]) - -m3 = np.array([[1,2,3],[4,5,6]]).astype(np.float32) -print(m3) -m4 = Matrix(m3) -for i in range(m4.rows()): - for j in range(m4.cols()): - print(m4[i, j], end = ' ') - print() diff --git a/stormpy/resources/pybind11/example/example7.ref b/stormpy/resources/pybind11/example/example7.ref deleted file mode 100644 index 75db9633b..000000000 --- a/stormpy/resources/pybind11/example/example7.ref +++ /dev/null @@ -1,17 +0,0 @@ -Value constructor: Creating a 5x5 matrix -0.0 -4.0 -[[ 0. 0. 0. 0. 0.] - [ 0. 0. 0. 0. 0.] - [ 0. 0. 0. 4. 0.] - [ 0. 0. 0. 0. 0.] - [ 0. 0. 0. 0. 0.]] -4.0 -5.0 -[[ 1. 2. 3.] - [ 4. 5. 6.]] -Value constructor: Creating a 2x3 matrix -1.0 2.0 3.0 -4.0 5.0 6.0 -Freeing a 2x3 matrix -Freeing a 5x5 matrix diff --git a/stormpy/resources/pybind11/example/example8.cpp b/stormpy/resources/pybind11/example/example8.cpp deleted file mode 100644 index dbdd4218d..000000000 --- a/stormpy/resources/pybind11/example/example8.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - example/example8.cpp -- binding classes with custom reference counting, - implicit conversions between types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include "object.h" - -/// Custom object with builtin reference counting (see 'object.h' for the implementation) -class MyObject1 : public Object { -public: - MyObject1(int value) : value(value) { - std::cout << toString() << " constructor" << std::endl; - } - - std::string toString() const { - return "MyObject1[" + std::to_string(value) + "]"; - } - -protected: - virtual ~MyObject1() { - std::cout << toString() << " destructor" << std::endl; - } - -private: - int value; -}; - -/// Object managed by a std::shared_ptr<> -class MyObject2 { -public: - MyObject2(int value) : value(value) { - std::cout << toString() << " constructor" << std::endl; - } - - std::string toString() const { - return "MyObject2[" + std::to_string(value) + "]"; - } - - virtual ~MyObject2() { - std::cout << toString() << " destructor" << std::endl; - } - -private: - int value; -}; - -/// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<> -class MyObject3 : public std::enable_shared_from_this { -public: - MyObject3(int value) : value(value) { - std::cout << toString() << " constructor" << std::endl; - } - - std::string toString() const { - return "MyObject3[" + std::to_string(value) + "]"; - } - - virtual ~MyObject3() { - std::cout << toString() << " destructor" << std::endl; - } - -private: - int value; -}; - -/// Make pybind aware of the ref-counted wrapper type (s) -PYBIND11_DECLARE_HOLDER_TYPE(T, ref); -PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); - -Object *make_object_1() { return new MyObject1(1); } -ref make_object_2() { return new MyObject1(2); } - -MyObject1 *make_myobject1_1() { return new MyObject1(4); } -ref make_myobject1_2() { return new MyObject1(5); } - -MyObject2 *make_myobject2_1() { return new MyObject2(6); } -std::shared_ptr make_myobject2_2() { return std::make_shared(7); } - -MyObject3 *make_myobject3_1() { return new MyObject3(8); } -std::shared_ptr make_myobject3_2() { return std::make_shared(9); } - -void print_object_1(const Object *obj) { std::cout << obj->toString() << std::endl; } -void print_object_2(ref obj) { std::cout << obj->toString() << std::endl; } -void print_object_3(const ref &obj) { std::cout << obj->toString() << std::endl; } -void print_object_4(const ref *obj) { std::cout << (*obj)->toString() << std::endl; } - -void print_myobject1_1(const MyObject1 *obj) { std::cout << obj->toString() << std::endl; } -void print_myobject1_2(ref obj) { std::cout << obj->toString() << std::endl; } -void print_myobject1_3(const ref &obj) { std::cout << obj->toString() << std::endl; } -void print_myobject1_4(const ref *obj) { std::cout << (*obj)->toString() << std::endl; } - -void print_myobject2_1(const MyObject2 *obj) { std::cout << obj->toString() << std::endl; } -void print_myobject2_2(std::shared_ptr obj) { std::cout << obj->toString() << std::endl; } -void print_myobject2_3(const std::shared_ptr &obj) { std::cout << obj->toString() << std::endl; } -void print_myobject2_4(const std::shared_ptr *obj) { std::cout << (*obj)->toString() << std::endl; } - -void print_myobject3_1(const MyObject3 *obj) { std::cout << obj->toString() << std::endl; } -void print_myobject3_2(std::shared_ptr obj) { std::cout << obj->toString() << std::endl; } -void print_myobject3_3(const std::shared_ptr &obj) { std::cout << obj->toString() << std::endl; } -void print_myobject3_4(const std::shared_ptr *obj) { std::cout << (*obj)->toString() << std::endl; } - -void init_ex8(py::module &m) { - py::class_> obj(m, "Object"); - obj.def("getRefCount", &Object::getRefCount); - - py::class_>(m, "MyObject1", obj) - .def(py::init()); - - m.def("make_object_1", &make_object_1); - m.def("make_object_2", &make_object_2); - m.def("make_myobject1_1", &make_myobject1_1); - m.def("make_myobject1_2", &make_myobject1_2); - m.def("print_object_1", &print_object_1); - m.def("print_object_2", &print_object_2); - m.def("print_object_3", &print_object_3); - m.def("print_object_4", &print_object_4); - m.def("print_myobject1_1", &print_myobject1_1); - m.def("print_myobject1_2", &print_myobject1_2); - m.def("print_myobject1_3", &print_myobject1_3); - m.def("print_myobject1_4", &print_myobject1_4); - - py::class_>(m, "MyObject2") - .def(py::init()); - m.def("make_myobject2_1", &make_myobject2_1); - m.def("make_myobject2_2", &make_myobject2_2); - m.def("print_myobject2_1", &print_myobject2_1); - m.def("print_myobject2_2", &print_myobject2_2); - m.def("print_myobject2_3", &print_myobject2_3); - m.def("print_myobject2_4", &print_myobject2_4); - - py::class_>(m, "MyObject3") - .def(py::init()); - m.def("make_myobject3_1", &make_myobject3_1); - m.def("make_myobject3_2", &make_myobject3_2); - m.def("print_myobject3_1", &print_myobject3_1); - m.def("print_myobject3_2", &print_myobject3_2); - m.def("print_myobject3_3", &print_myobject3_3); - m.def("print_myobject3_4", &print_myobject3_4); - - py::implicitly_convertible(); -} diff --git a/stormpy/resources/pybind11/example/example8.py b/stormpy/resources/pybind11/example/example8.py deleted file mode 100755 index b12c5b999..000000000 --- a/stormpy/resources/pybind11/example/example8.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example import MyObject1 -from example import MyObject2 -from example import MyObject3 - -from example import make_object_1 -from example import make_object_2 -from example import make_myobject1_1 -from example import make_myobject1_2 -from example import make_myobject2_1 -from example import make_myobject2_2 -from example import make_myobject3_1 -from example import make_myobject3_2 - -from example import print_object_1 -from example import print_object_2 -from example import print_object_3 -from example import print_object_4 - -from example import print_myobject1_1 -from example import print_myobject1_2 -from example import print_myobject1_3 -from example import print_myobject1_4 - -from example import print_myobject2_1 -from example import print_myobject2_2 -from example import print_myobject2_3 -from example import print_myobject2_4 - -from example import print_myobject3_1 -from example import print_myobject3_2 -from example import print_myobject3_3 -from example import print_myobject3_4 - -for o in [make_object_1(), make_object_2(), MyObject1(3)]: - print("Reference count = %i" % o.getRefCount()) - print_object_1(o) - print_object_2(o) - print_object_3(o) - print_object_4(o) - -for o in [make_myobject1_1(), make_myobject1_2(), MyObject1(6), 7]: - print(o) - if not isinstance(o, int): - print_object_1(o) - print_object_2(o) - print_object_3(o) - print_object_4(o) - print_myobject1_1(o) - print_myobject1_2(o) - print_myobject1_3(o) - print_myobject1_4(o) - -for o in [MyObject2(8), make_myobject2_1(), make_myobject2_2()]: - print(o) - print_myobject2_1(o) - print_myobject2_2(o) - print_myobject2_3(o) - print_myobject2_4(o) - -for o in [MyObject3(9), make_myobject3_1(), make_myobject3_2()]: - print(o) - print_myobject3_1(o) - print_myobject3_2(o) - print_myobject3_3(o) - print_myobject3_4(o) diff --git a/stormpy/resources/pybind11/example/example8.ref b/stormpy/resources/pybind11/example/example8.ref deleted file mode 100644 index 641abd0c4..000000000 --- a/stormpy/resources/pybind11/example/example8.ref +++ /dev/null @@ -1,243 +0,0 @@ -MyObject1[1] constructor -Initialized ref from pointer 0x1347ba0 -MyObject1[2] constructor -Initialized ref from pointer 0x12b9270 -Initialized ref from ref 0x12b9270 -Destructing ref 0x12b9270 -MyObject1[3] constructor -Initialized ref from pointer 0x12a2a90 -MyObject1[1] -Created empty ref -Assigning ref 0x1347ba0 -Initialized ref from ref 0x1347ba0 -MyObject1[1] -Destructing ref 0x1347ba0 -Destructing ref 0x1347ba0 -Created empty ref -Assigning ref 0x1347ba0 -MyObject1[1] -Destructing ref 0x1347ba0 -Created empty ref -Assigning ref 0x1347ba0 -MyObject1[1] -Destructing ref 0x1347ba0 -MyObject1[2] -Created empty ref -Assigning ref 0x12b9270 -Initialized ref from ref 0x12b9270 -MyObject1[2] -Destructing ref 0x12b9270 -Destructing ref 0x12b9270 -Created empty ref -Assigning ref 0x12b9270 -MyObject1[2] -Destructing ref 0x12b9270 -Created empty ref -Assigning ref 0x12b9270 -MyObject1[2] -Destructing ref 0x12b9270 -MyObject1[3] -Created empty ref -Assigning ref 0x12a2a90 -Initialized ref from ref 0x12a2a90 -MyObject1[3] -Destructing ref 0x12a2a90 -Destructing ref 0x12a2a90 -Created empty ref -Assigning ref 0x12a2a90 -MyObject1[3] -Destructing ref 0x12a2a90 -Created empty ref -Assigning ref 0x12a2a90 -MyObject1[3] -Destructing ref 0x12a2a90 -Destructing ref 0x12b9270 -MyObject1[2] destructor -Destructing ref 0x1347ba0 -MyObject1[1] destructor -MyObject1[4] constructor -Initialized ref from pointer 0x1347ba0 -MyObject1[5] constructor -Initialized ref from pointer 0x1299190 -Initialized ref from ref 0x1299190 -Destructing ref 0x1299190 -MyObject1[6] constructor -Initialized ref from pointer 0x133e2f0 -Destructing ref 0x12a2a90 -MyObject1[3] destructor -MyObject1[4] -Created empty ref -Assigning ref 0x1347ba0 -Initialized ref from ref 0x1347ba0 -MyObject1[4] -Destructing ref 0x1347ba0 -Destructing ref 0x1347ba0 -Created empty ref -Assigning ref 0x1347ba0 -MyObject1[4] -Destructing ref 0x1347ba0 -Created empty ref -Assigning ref 0x1347ba0 -MyObject1[4] -Destructing ref 0x1347ba0 -MyObject1[4] -Created empty ref -Assigning ref 0x1347ba0 -Initialized ref from ref 0x1347ba0 -MyObject1[4] -Destructing ref 0x1347ba0 -Destructing ref 0x1347ba0 -Created empty ref -Assigning ref 0x1347ba0 -MyObject1[4] -Destructing ref 0x1347ba0 -Created empty ref -Assigning ref 0x1347ba0 -MyObject1[4] -Destructing ref 0x1347ba0 -MyObject1[5] -Created empty ref -Assigning ref 0x1299190 -Initialized ref from ref 0x1299190 -MyObject1[5] -Destructing ref 0x1299190 -Destructing ref 0x1299190 -Created empty ref -Assigning ref 0x1299190 -MyObject1[5] -Destructing ref 0x1299190 -Created empty ref -Assigning ref 0x1299190 -MyObject1[5] -Destructing ref 0x1299190 -MyObject1[5] -Created empty ref -Assigning ref 0x1299190 -Initialized ref from ref 0x1299190 -MyObject1[5] -Destructing ref 0x1299190 -Destructing ref 0x1299190 -Created empty ref -Assigning ref 0x1299190 -MyObject1[5] -Destructing ref 0x1299190 -Created empty ref -Assigning ref 0x1299190 -MyObject1[5] -Destructing ref 0x1299190 -MyObject1[6] -Created empty ref -Assigning ref 0x133e2f0 -Initialized ref from ref 0x133e2f0 -MyObject1[6] -Destructing ref 0x133e2f0 -Destructing ref 0x133e2f0 -Created empty ref -Assigning ref 0x133e2f0 -MyObject1[6] -Destructing ref 0x133e2f0 -Created empty ref -Assigning ref 0x133e2f0 -MyObject1[6] -Destructing ref 0x133e2f0 -MyObject1[6] -Created empty ref -Assigning ref 0x133e2f0 -Initialized ref from ref 0x133e2f0 -MyObject1[6] -Destructing ref 0x133e2f0 -Destructing ref 0x133e2f0 -Created empty ref -Assigning ref 0x133e2f0 -MyObject1[6] -Destructing ref 0x133e2f0 -Created empty ref -Assigning ref 0x133e2f0 -MyObject1[6] -Destructing ref 0x133e2f0 -MyObject1[7] constructor -Initialized ref from pointer 0x133f3a0 -MyObject1[7] -Destructing ref 0x133f3a0 -MyObject1[7] destructor -Created empty ref -MyObject1[7] constructor -Initialized ref from pointer 0x12a2a90 -Assigning ref 0x12a2a90 -Initialized ref from ref 0x12a2a90 -MyObject1[7] -Destructing ref 0x12a2a90 -Destructing ref 0x12a2a90 -Destructing ref 0x12a2a90 -MyObject1[7] destructor -Created empty ref -MyObject1[7] constructor -Initialized ref from pointer 0x133f3a0 -Assigning ref 0x133f3a0 -MyObject1[7] -Destructing ref 0x133f3a0 -Destructing ref 0x133f3a0 -MyObject1[7] destructor -Created empty ref -MyObject1[7] constructor -Initialized ref from pointer 0x12a2a90 -Assigning ref 0x12a2a90 -MyObject1[7] -Destructing ref 0x12a2a90 -Destructing ref 0x12a2a90 -MyObject1[7] destructor -Destructing ref 0x133e2f0 -MyObject1[6] destructor -Destructing ref 0x1299190 -MyObject1[5] destructor -Destructing ref 0x1347ba0 -MyObject1[4] destructor -MyObject2[8] constructor -MyObject2[6] constructor -MyObject2[7] constructor -MyObject2[8] -MyObject2[8] -MyObject2[8] -MyObject2[8] -MyObject2[6] -MyObject2[6] -MyObject2[6] -MyObject2[6] -MyObject2[7] -MyObject2[7] -MyObject2[7] -MyObject2[7] -MyObject2[6] destructor -MyObject2[8] destructor -MyObject3[9] constructor -MyObject3[8] constructor -MyObject3[9] constructor -MyObject2[7] destructor -MyObject3[9] -MyObject3[9] -MyObject3[9] -MyObject3[9] -MyObject3[8] -MyObject3[8] -MyObject3[8] -MyObject3[8] -MyObject3[9] -MyObject3[9] -MyObject3[9] -MyObject3[9] -MyObject3[8] destructor -MyObject3[9] destructor -Reference count = 1 -Reference count = 1 -Reference count = 1 - - - -7 - - - - - - -MyObject3[9] destructor diff --git a/stormpy/resources/pybind11/example/example9.cpp b/stormpy/resources/pybind11/example/example9.cpp deleted file mode 100644 index ca75ecc79..000000000 --- a/stormpy/resources/pybind11/example/example9.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - example/example9.cpp -- nested modules, importing modules, and - internal references - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" - -void submodule_func() { - std::cout << "submodule_func()" << std::endl; -} - -class A { -public: - A(int v) : v(v) { std::cout << "A constructor" << std::endl; } - ~A() { std::cout << "A destructor" << std::endl; } - A(const A&) { std::cout << "A copy constructor" << std::endl; } - std::string toString() { return "A[" + std::to_string(v) + "]"; } -private: - int v; -}; - -class B { -public: - B() { std::cout << "B constructor" << std::endl; } - ~B() { std::cout << "B destructor" << std::endl; } - B(const B&) { std::cout << "B copy constructor" << std::endl; } - A &get_a1() { return a1; } - A &get_a2() { return a2; } - - A a1{1}; - A a2{2}; -}; - -void init_ex9(py::module &m) { - py::module m_sub = m.def_submodule("submodule"); - m_sub.def("submodule_func", &submodule_func); - - py::class_(m_sub, "A") - .def(py::init()) - .def("__repr__", &A::toString); - - py::class_(m_sub, "B") - .def(py::init<>()) - .def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal) - .def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal) - .def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default - .def_readwrite("a2", &B::a2); - - m.attr("OD") = py::module::import("collections").attr("OrderedDict"); -} diff --git a/stormpy/resources/pybind11/example/example9.py b/stormpy/resources/pybind11/example/example9.py deleted file mode 100755 index 2262fcf5c..000000000 --- a/stormpy/resources/pybind11/example/example9.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -import example - -print(example.__name__) -print(example.submodule.__name__) - -from example.submodule import * -from example import OD - -submodule_func() - -b = B() -print(b.get_a1()) -print(b.a1) -print(b.get_a2()) -print(b.a2) - -b.a1 = A(42) -b.a2 = A(43) - -print(b.get_a1()) -print(b.a1) -print(b.get_a2()) -print(b.a2) - -print(OD([(1, 'a'), (2, 'b')])) diff --git a/stormpy/resources/pybind11/example/example9.ref b/stormpy/resources/pybind11/example/example9.ref deleted file mode 100644 index 9c783135c..000000000 --- a/stormpy/resources/pybind11/example/example9.ref +++ /dev/null @@ -1,22 +0,0 @@ -example -example.submodule -submodule_func() -A constructor -A constructor -B constructor -A[1] -A[1] -A[2] -A[2] -A constructor -A destructor -A constructor -A destructor -A[42] -A[42] -A[43] -A[43] -OrderedDict([(1, 'a'), (2, 'b')]) -B destructor -A destructor -A destructor diff --git a/stormpy/resources/pybind11/example/issues.cpp b/stormpy/resources/pybind11/example/issues.cpp deleted file mode 100644 index d75da1cef..000000000 --- a/stormpy/resources/pybind11/example/issues.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - example/issues.cpp -- collection of testcases for miscellaneous issues - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "example.h" -#include - -PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); - -void init_issues(py::module &m) { - py::module m2 = m.def_submodule("issues"); - -#if !defined(_MSC_VER) - // Visual Studio 2015 currently cannot compile this test - // (see the comment in type_caster_base::make_copy_constructor) - // #70 compilation issue if operator new is not public - class NonConstructible { private: void *operator new(size_t bytes) throw(); }; - py::class_(m, "Foo"); - m2.def("getstmt", []() -> NonConstructible * { return nullptr; }, - py::return_value_policy::reference); -#endif - - // #137: const char* isn't handled properly - m2.def("print_cchar", [](const char *string) { std::cout << string << std::endl; }); - - // #150: char bindings broken - m2.def("print_char", [](char c) { std::cout << c << std::endl; }); - - // #159: virtual function dispatch has problems with similar-named functions - struct Base { virtual void dispatch(void) const { - /* for some reason MSVC2015 can't compile this if the function is pure virtual */ - }; }; - - struct DispatchIssue : Base { - virtual void dispatch(void) const { - PYBIND11_OVERLOAD_PURE(void, Base, dispatch, /* no arguments */); - } - }; - - py::class_, DispatchIssue>(m2, "DispatchIssue") - .def(py::init<>()) - .def("dispatch", &Base::dispatch); - - m2.def("dispatch_issue_go", [](const Base * b) { b->dispatch(); }); - - struct Placeholder { int i; Placeholder(int i) : i(i) { } }; - - py::class_(m2, "Placeholder") - .def(py::init()) - .def("__repr__", [](const Placeholder &p) { return "Placeholder[" + std::to_string(p.i) + "]"; }); - - // #171: Can't return reference wrappers (or STL datastructures containing them) - m2.def("return_vec_of_reference_wrapper", [](std::reference_wrapper p4){ - Placeholder *p1 = new Placeholder{1}; - Placeholder *p2 = new Placeholder{2}; - Placeholder *p3 = new Placeholder{3}; - std::vector> v; - v.push_back(std::ref(*p1)); - v.push_back(std::ref(*p2)); - v.push_back(std::ref(*p3)); - v.push_back(p4); - return v; - }); - - // #181: iterator passthrough did not compile - m2.def("iterator_passthrough", [](py::iterator s) -> py::iterator { - return py::make_iterator(std::begin(s), std::end(s)); - }); - - // #187: issue involving std::shared_ptr<> return value policy & garbage collection - struct ElementBase { virtual void foo() { } /* Force creation of virtual table */ }; - struct ElementA : ElementBase { - ElementA(int v) : v(v) { } - int value() { return v; } - int v; - }; - - struct ElementList { - void add(std::shared_ptr e) { l.push_back(e); } - std::vector> l; - }; - - py::class_> (m2, "ElementBase"); - - py::class_>(m2, "ElementA", py::base()) - .def(py::init()) - .def("value", &ElementA::value); - - py::class_>(m2, "ElementList") - .def(py::init<>()) - .def("add", &ElementList::add) - .def("get", [](ElementList &el){ - py::list list; - for (auto &e : el.l) - list.append(py::cast(e)); - return list; - }); - - // (no id): should not be able to pass 'None' to a reference argument - m2.def("print_element", [](ElementA &el) { std::cout << el.value() << std::endl; }); - - // (no id): don't cast doubles to ints - m2.def("expect_float", [](float f) { return f; }); - m2.def("expect_int", [](int i) { return i; }); - - // (no id): don't invoke Python dispatch code when instantiating C++ - // classes that were not extended on the Python side - struct A { - virtual ~A() {} - virtual void f() { std::cout << "A.f()" << std::endl; } - }; - - struct PyA : A { - PyA() { std::cout << "PyA.PyA()" << std::endl; } - - void f() override { - std::cout << "PyA.f()" << std::endl; - PYBIND11_OVERLOAD(void, A, f); - } - }; - - auto call_f = [](A *a) { a->f(); }; - - pybind11::class_, PyA>(m2, "A") - .def(py::init<>()) - .def("f", &A::f); - - m2.def("call_f", call_f); - - try { - py::class_(m2, "Placeholder"); - throw std::logic_error("Expected an exception!"); - } catch (std::runtime_error &) { - /* All good */ - } -} diff --git a/stormpy/resources/pybind11/example/issues.py b/stormpy/resources/pybind11/example/issues.py deleted file mode 100644 index 257f08e18..000000000 --- a/stormpy/resources/pybind11/example/issues.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import sys -sys.path.append('.') - -from example.issues import print_cchar, print_char -from example.issues import DispatchIssue, dispatch_issue_go -from example.issues import Placeholder, return_vec_of_reference_wrapper -from example.issues import iterator_passthrough -from example.issues import ElementList, ElementA, print_element -from example.issues import expect_float, expect_int -from example.issues import A, call_f -import gc - -print_cchar("const char *") -print_char('c') - - -class PyClass1(DispatchIssue): - def dispatch(self): - print("Yay..") - - -class PyClass2(DispatchIssue): - def dispatch(self): - try: - super(PyClass2, self).dispatch() - except Exception as e: - print("Failed as expected: " + str(e)) - p = PyClass1() - dispatch_issue_go(p) - -b = PyClass2() -dispatch_issue_go(b) - -print(return_vec_of_reference_wrapper(Placeholder(4))) - -print(list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15])))) - -el = ElementList() -for i in range(10): - el.add(ElementA(i)) -gc.collect() -for i, v in enumerate(el.get()): - print("%i==%i, " % (i, v.value()), end='') -print() - -try: - print_element(None) -except Exception as e: - print("Failed as expected: " + str(e)) - -try: - print(expect_int(5.2)) -except Exception as e: - print("Failed as expected: " + str(e)) - -print(expect_float(12)) - -class B(A): - def __init__(self): - super(B, self).__init__() - - def f(self): - print("In python f()") - -print("C++ version") -a = A() -call_f(a) - -print("Python version") -b = B() -call_f(b) - diff --git a/stormpy/resources/pybind11/example/issues.ref b/stormpy/resources/pybind11/example/issues.ref deleted file mode 100644 index 58cc7985f..000000000 --- a/stormpy/resources/pybind11/example/issues.ref +++ /dev/null @@ -1,20 +0,0 @@ -const char * -c -Failed as expected: Tried to call pure virtual function "Base::dispatch" -Yay.. -[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]] -[3, 5, 7, 9, 11, 13, 15] -0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9, -Failed as expected: Incompatible function arguments. The following argument types are supported: - 1. (example.issues.ElementA) -> NoneType - Invoked with: None -Failed as expected: Incompatible function arguments. The following argument types are supported: - 1. (int) -> int - Invoked with: 5.2 -12.0 -C++ version -A.f() -Python version -PyA.PyA() -PyA.f() -In python f() diff --git a/stormpy/resources/pybind11/example/object.h b/stormpy/resources/pybind11/example/object.h deleted file mode 100644 index 8097bd671..000000000 --- a/stormpy/resources/pybind11/example/object.h +++ /dev/null @@ -1,160 +0,0 @@ -#if !defined(__OBJECT_H) -#define __OBJECT_H - -#include - -/// Reference counted object base class -class Object { -public: - /// Default constructor - Object() { } - - /// Copy constructor - Object(const Object &) : m_refCount(0) {} - - /// Return the current reference count - int getRefCount() const { return m_refCount; }; - - /// Increase the object's reference count by one - void incRef() const { ++m_refCount; } - - /** \brief Decrease the reference count of - * the object and possibly deallocate it. - * - * The object will automatically be deallocated once - * the reference count reaches zero. - */ - void decRef(bool dealloc = true) const { - --m_refCount; - if (m_refCount == 0 && dealloc) - delete this; - else if (m_refCount < 0) - throw std::runtime_error("Internal error: reference count < 0!"); - } - - virtual std::string toString() const = 0; -protected: - /** \brief Virtual protected deconstructor. - * (Will only be called by \ref ref) - */ - virtual ~Object() { } -private: - mutable std::atomic m_refCount { 0 }; -}; - -/** - * \brief Reference counting helper - * - * The \a ref refeference template is a simple wrapper to store a - * pointer to an object. It takes care of increasing and decreasing - * the reference count of the object. When the last reference goes - * out of scope, the associated object will be deallocated. - * - * \ingroup libcore - */ -template class ref { -public: - /// Create a nullptr reference - ref() : m_ptr(nullptr) { std::cout << "Created empty ref" << std::endl; } - - /// Construct a reference from a pointer - ref(T *ptr) : m_ptr(ptr) { - std::cout << "Initialized ref from pointer " << ptr<< std::endl; - if (m_ptr) ((Object *) m_ptr)->incRef(); - } - - /// Copy constructor - ref(const ref &r) : m_ptr(r.m_ptr) { - std::cout << "Initialized ref from ref " << r.m_ptr << std::endl; - if (m_ptr) - ((Object *) m_ptr)->incRef(); - } - - /// Move constructor - ref(ref &&r) : m_ptr(r.m_ptr) { - std::cout << "Initialized ref with move from ref " << r.m_ptr << std::endl; - r.m_ptr = nullptr; - } - - /// Destroy this reference - ~ref() { - std::cout << "Destructing ref " << m_ptr << std::endl; - if (m_ptr) - ((Object *) m_ptr)->decRef(); - } - - /// Move another reference into the current one - ref& operator=(ref&& r) { - std::cout << "Move-assigning ref " << r.m_ptr << std::endl; - if (*this == r) - return *this; - if (m_ptr) - ((Object *) m_ptr)->decRef(); - m_ptr = r.m_ptr; - r.m_ptr = nullptr; - return *this; - } - - /// Overwrite this reference with another reference - ref& operator=(const ref& r) { - std::cout << "Assigning ref " << r.m_ptr << std::endl; - if (m_ptr == r.m_ptr) - return *this; - if (m_ptr) - ((Object *) m_ptr)->decRef(); - m_ptr = r.m_ptr; - if (m_ptr) - ((Object *) m_ptr)->incRef(); - return *this; - } - - /// Overwrite this reference with a pointer to another object - ref& operator=(T *ptr) { - std::cout << "Assigning ptr " << ptr << " to ref" << std::endl; - if (m_ptr == ptr) - return *this; - if (m_ptr) - ((Object *) m_ptr)->decRef(); - m_ptr = ptr; - if (m_ptr) - ((Object *) m_ptr)->incRef(); - return *this; - } - - /// Compare this reference with another reference - bool operator==(const ref &r) const { return m_ptr == r.m_ptr; } - - /// Compare this reference with another reference - bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; } - - /// Compare this reference with a pointer - bool operator==(const T* ptr) const { return m_ptr == ptr; } - - /// Compare this reference with a pointer - bool operator!=(const T* ptr) const { return m_ptr != ptr; } - - /// Access the object referenced by this reference - T* operator->() { return m_ptr; } - - /// Access the object referenced by this reference - const T* operator->() const { return m_ptr; } - - /// Return a C++ reference to the referenced object - T& operator*() { return *m_ptr; } - - /// Return a const C++ reference to the referenced object - const T& operator*() const { return *m_ptr; } - - /// Return a pointer to the referenced object - operator T* () { return m_ptr; } - - /// Return a const pointer to the referenced object - T* get() { return m_ptr; } - - /// Return a pointer to the referenced object - const T* get() const { return m_ptr; } -private: - T *m_ptr; -}; - -#endif /* __OBJECT_H */ diff --git a/stormpy/resources/pybind11/example/run_test.py b/stormpy/resources/pybind11/example/run_test.py deleted file mode 100755 index 70ce4a6c0..000000000 --- a/stormpy/resources/pybind11/example/run_test.py +++ /dev/null @@ -1,73 +0,0 @@ -import sys -import os -import re -import subprocess -import difflib - -remove_unicode_marker = re.compile(r'u(\'[^\']*\')') -remove_long_marker = re.compile(r'([0-9])L') -remove_hex = re.compile(r'0x[0-9a-fA-F]+') -shorten_floats = re.compile(r'([1-9][0-9]*\.[0-9]{4})[0-9]*') - -relaxed = False - -def sanitize(lines): - lines = lines.split('\n') - for i in range(len(lines)): - line = lines[i] - if line.startswith(" |"): - line = "" - line = remove_unicode_marker.sub(r'\1', line) - line = remove_long_marker.sub(r'\1', line) - line = remove_hex.sub(r'0', line) - line = shorten_floats.sub(r'\1', line) - line = line.replace('__builtin__', 'builtins') - line = line.replace('example.', '') - line = line.replace('unicode', 'str') - line = line.replace('Example4.EMode', 'EMode') - line = line.replace('example.EMode', 'EMode') - line = line.replace('method of builtins.PyCapsule instance', '') - line = line.strip() - if relaxed: - lower = line.lower() - # The precise pattern of allocations and deallocations is dependent on the compiler - # and optimization level, so we unfortunately can't reliably check it in this kind of test case - if 'constructor' in lower or 'destructor' in lower \ - or 'ref' in lower or 'freeing' in lower: - line = "" - lines[i] = line - - return '\n'.join(sorted([l for l in lines if l != ""])) - -path = os.path.dirname(__file__) -if path != '': - os.chdir(path) - -if len(sys.argv) < 2: - print("Syntax: %s [--relaxed] " % sys.argv[0]) - exit(0) - -if len(sys.argv) == 3 and sys.argv[1] == '--relaxed': - del sys.argv[1] - relaxed = True - -name = sys.argv[1] -output_bytes = subprocess.check_output([sys.executable, name + ".py"], - stderr=subprocess.STDOUT) - -output = sanitize(output_bytes.decode('utf-8')) -reference = sanitize(open(name + '.ref', 'r').read()) - -if 'NumPy missing' in output: - print('Test "%s" could not be run.' % name) - exit(0) -elif output == reference: - print('Test "%s" succeeded.' % name) - exit(0) -else: - print('Test "%s" FAILED!' % name) - print('--- output') - print('+++ reference') - print(''.join(difflib.ndiff(output.splitlines(keepends=True), - reference.splitlines(keepends=True)))) - exit(-1) diff --git a/stormpy/resources/pybind11/include/pybind11/attr.h b/stormpy/resources/pybind11/include/pybind11/attr.h deleted file mode 100644 index 448612c52..000000000 --- a/stormpy/resources/pybind11/include/pybind11/attr.h +++ /dev/null @@ -1,362 +0,0 @@ -/* - pybind11/pybind11.h: Infrastructure for processing custom - type and function attributes - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "cast.h" - -NAMESPACE_BEGIN(pybind11) - -/// Annotation for methods -struct is_method { handle class_; is_method(const handle &c) : class_(c) { } }; - -/// Annotation for operators -struct is_operator { }; - -/// Annotation for parent scope -struct scope { handle value; scope(const handle &s) : value(s) { } }; - -/// Annotation for documentation -struct doc { const char *value; doc(const char *value) : value(value) { } }; - -/// Annotation for function names -struct name { const char *value; name(const char *value) : value(value) { } }; - -/// Annotation indicating that a function is an overload associated with a given "sibling" -struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } }; - -/// Annotation indicating that a class derives from another given type -template struct base { - PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") - base() { } -}; - -/// Keep patient alive while nurse lives -template struct keep_alive { }; - -/// Annotation indicating that a class is involved in a multiple inheritance relationship -struct multiple_inheritance { }; - -/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class -struct dynamic_attr { }; - -/// Annotation to mark enums as an arithmetic type -struct arithmetic { }; - -NAMESPACE_BEGIN(detail) -/* Forward declarations */ -enum op_id : int; -enum op_type : int; -struct undefined_t; -template struct op_; -template struct init; -template struct init_alias; -inline void keep_alive_impl(int Nurse, int Patient, handle args, handle ret); - -/// Internal data structure which holds metadata about a keyword argument -struct argument_record { - const char *name; ///< Argument name - const char *descr; ///< Human-readable version of the argument value - handle value; ///< Associated Python object - - argument_record(const char *name, const char *descr, handle value) - : name(name), descr(descr), value(value) { } -}; - -/// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) -struct function_record { - function_record() - : is_constructor(false), is_stateless(false), is_operator(false), - has_args(false), has_kwargs(false), is_method(false) { } - - /// Function name - char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ - - // User-specified documentation string - char *doc = nullptr; - - /// Human-readable version of the function signature - char *signature = nullptr; - - /// List of registered keyword arguments - std::vector args; - - /// Pointer to lambda function which converts arguments and performs the actual call - handle (*impl) (function_record *, handle, handle, handle) = nullptr; - - /// Storage for the wrapped function pointer and captured data, if any - void *data[3] = { }; - - /// Pointer to custom destructor for 'data' (if needed) - void (*free_data) (function_record *ptr) = nullptr; - - /// Return value policy associated with this function - return_value_policy policy = return_value_policy::automatic; - - /// True if name == '__init__' - bool is_constructor : 1; - - /// True if this is a stateless function pointer - bool is_stateless : 1; - - /// True if this is an operator (__add__), etc. - bool is_operator : 1; - - /// True if the function has a '*args' argument - bool has_args : 1; - - /// True if the function has a '**kwargs' argument - bool has_kwargs : 1; - - /// True if this is a method - bool is_method : 1; - - /// Number of arguments - uint16_t nargs; - - /// Python method object - PyMethodDef *def = nullptr; - - /// Python handle to the parent scope (a class or a module) - handle scope; - - /// Python handle to the sibling function representing an overload chain - handle sibling; - - /// Pointer to next overload - function_record *next = nullptr; -}; - -/// Special data structure which (temporarily) holds metadata about a bound class -struct type_record { - PYBIND11_NOINLINE type_record() { } - - /// Handle to the parent scope - handle scope; - - /// Name of the class - const char *name = nullptr; - - // Pointer to RTTI type_info data structure - const std::type_info *type = nullptr; - - /// How large is the underlying C++ type? - size_t type_size = 0; - - /// How large is pybind11::instance? - size_t instance_size = 0; - - /// Function pointer to class_<..>::init_holder - void (*init_holder)(PyObject *, const void *) = nullptr; - - /// Function pointer to class_<..>::dealloc - void (*dealloc)(PyObject *) = nullptr; - - /// List of base classes of the newly created type - list bases; - - /// Optional docstring - const char *doc = nullptr; - - /// Multiple inheritance marker - bool multiple_inheritance = false; - - /// Does the class manage a __dict__? - bool dynamic_attr = false; - - PYBIND11_NOINLINE void add_base(const std::type_info *base, void *(*caster)(void *)) { - auto base_info = detail::get_type_info(*base, false); - if (!base_info) { - std::string tname(base->name()); - detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + - "\" referenced unknown base type \"" + tname + "\""); - } - - bases.append((PyObject *) base_info->type); - - if (base_info->type->tp_dictoffset != 0) - dynamic_attr = true; - - if (caster) - base_info->implicit_casts.push_back(std::make_pair(type, caster)); - } -}; - -/** - * Partial template specializations to process custom attributes provided to - * cpp_function_ and class_. These are either used to initialize the respective - * fields in the type_record and function_record data structures or executed at - * runtime to deal with custom call policies (e.g. keep_alive). - */ -template struct process_attribute; - -template struct process_attribute_default { - /// Default implementation: do nothing - static void init(const T &, function_record *) { } - static void init(const T &, type_record *) { } - static void precall(handle) { } - static void postcall(handle, handle) { } -}; - -/// Process an attribute specifying the function's name -template <> struct process_attribute : process_attribute_default { - static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } -}; - -/// Process an attribute specifying the function's docstring -template <> struct process_attribute : process_attribute_default { - static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } -}; - -/// Process an attribute specifying the function's docstring (provided as a C-style string) -template <> struct process_attribute : process_attribute_default { - static void init(const char *d, function_record *r) { r->doc = const_cast(d); } - static void init(const char *d, type_record *r) { r->doc = const_cast(d); } -}; -template <> struct process_attribute : process_attribute { }; - -/// Process an attribute indicating the function's return value policy -template <> struct process_attribute : process_attribute_default { - static void init(const return_value_policy &p, function_record *r) { r->policy = p; } -}; - -/// Process an attribute which indicates that this is an overloaded function associated with a given sibling -template <> struct process_attribute : process_attribute_default { - static void init(const sibling &s, function_record *r) { r->sibling = s.value; } -}; - -/// Process an attribute which indicates that this function is a method -template <> struct process_attribute : process_attribute_default { - static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } -}; - -/// Process an attribute which indicates the parent scope of a method -template <> struct process_attribute : process_attribute_default { - static void init(const scope &s, function_record *r) { r->scope = s.value; } -}; - -/// Process an attribute which indicates that this function is an operator -template <> struct process_attribute : process_attribute_default { - static void init(const is_operator &, function_record *r) { r->is_operator = true; } -}; - -/// Process a keyword argument attribute (*without* a default value) -template <> struct process_attribute : process_attribute_default { - static void init(const arg &a, function_record *r) { - if (r->is_method && r->args.empty()) - r->args.emplace_back("self", nullptr, handle()); - r->args.emplace_back(a.name, nullptr, handle()); - } -}; - -/// Process a keyword argument attribute (*with* a default value) -template <> struct process_attribute : process_attribute_default { - static void init(const arg_v &a, function_record *r) { - if (r->is_method && r->args.empty()) - r->args.emplace_back("self", nullptr, handle()); - - if (!a.value) { -#if !defined(NDEBUG) - auto descr = "'" + std::string(a.name) + ": " + a.type + "'"; - if (r->is_method) { - if (r->name) - descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; - else - descr += " in method of '" + (std::string) str(r->scope) + "'"; - } else if (r->name) { - descr += " in function named '" + (std::string) r->name + "'"; - } - pybind11_fail("arg(): could not convert default keyword argument " - + descr + " into a Python object (type not registered yet?)"); -#else - pybind11_fail("arg(): could not convert default keyword argument " - "into a Python object (type not registered yet?). " - "Compile in debug mode for more information."); -#endif - } - r->args.emplace_back(a.name, a.descr, a.value.inc_ref()); - } -}; - -/// Process a parent class attribute -template -struct process_attribute::value>> : process_attribute_default { - static void init(const handle &h, type_record *r) { r->bases.append(h); } -}; - -/// Process a parent class attribute (deprecated, does not support multiple inheritance) -template -struct process_attribute> : process_attribute_default> { - static void init(const base &, type_record *r) { r->add_base(&typeid(T), nullptr); } -}; - -/// Process a multiple inheritance attribute -template <> -struct process_attribute : process_attribute_default { - static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } -}; - -template <> -struct process_attribute : process_attribute_default { - static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; } -}; - - -/// Process an 'arithmetic' attribute for enums (does nothing here) -template <> -struct process_attribute : process_attribute_default {}; - -/*** - * Process a keep_alive call policy -- invokes keep_alive_impl during the - * pre-call handler if both Nurse, Patient != 0 and use the post-call handler - * otherwise - */ -template struct process_attribute> : public process_attribute_default> { - template = 0> - static void precall(handle args) { keep_alive_impl(Nurse, Patient, args, handle()); } - template = 0> - static void postcall(handle, handle) { } - template = 0> - static void precall(handle) { } - template = 0> - static void postcall(handle args, handle ret) { keep_alive_impl(Nurse, Patient, args, ret); } -}; - -/// Recursively iterate over variadic template arguments -template struct process_attributes { - static void init(const Args&... args, function_record *r) { - int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; - ignore_unused(unused); - } - static void init(const Args&... args, type_record *r) { - int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; - ignore_unused(unused); - } - static void precall(handle fn_args) { - int unused[] = { 0, (process_attribute::type>::precall(fn_args), 0) ... }; - ignore_unused(unused); - } - static void postcall(handle fn_args, handle fn_ret) { - int unused[] = { 0, (process_attribute::type>::postcall(fn_args, fn_ret), 0) ... }; - ignore_unused(unused); - } -}; - -/// Check the number of named arguments at compile time -template ::value...), - size_t self = constexpr_sum(std::is_same::value...)> -constexpr bool expected_num_args(size_t nargs) { - return named == 0 || (self + named) == nargs; -} - -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/cast.h b/stormpy/resources/pybind11/include/pybind11/cast.h deleted file mode 100644 index a4e47d38f..000000000 --- a/stormpy/resources/pybind11/include/pybind11/cast.h +++ /dev/null @@ -1,1417 +0,0 @@ -/* - pybind11/cast.h: Partial template specializations to cast between - C++ and Python types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pytypes.h" -#include "typeid.h" -#include "descr.h" -#include -#include - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -/// Additional type information which does not fit into the PyTypeObject -struct type_info { - PyTypeObject *type; - size_t type_size; - void (*init_holder)(PyObject *, const void *); - std::vector implicit_conversions; - std::vector> implicit_casts; - std::vector *direct_conversions; - buffer_info *(*get_buffer)(PyObject *, void *) = nullptr; - void *get_buffer_data = nullptr; - /** A simple type never occurs as a (direct or indirect) parent - * of a class that makes use of multiple inheritance */ - bool simple_type = true; -}; - -PYBIND11_NOINLINE inline internals &get_internals() { - static internals *internals_ptr = nullptr; - if (internals_ptr) - return *internals_ptr; - handle builtins(PyEval_GetBuiltins()); - const char *id = PYBIND11_INTERNALS_ID; - if (builtins.contains(id) && isinstance(builtins[id])) { - internals_ptr = capsule(builtins[id]); - } else { - internals_ptr = new internals(); - #if defined(WITH_THREAD) - PyEval_InitThreads(); - PyThreadState *tstate = PyThreadState_Get(); - internals_ptr->tstate = PyThread_create_key(); - PyThread_set_key_value(internals_ptr->tstate, tstate); - internals_ptr->istate = tstate->interp; - #endif - builtins[id] = capsule(internals_ptr); - internals_ptr->registered_exception_translators.push_front( - [](std::exception_ptr p) -> void { - try { - if (p) std::rethrow_exception(p); - } catch (error_already_set &e) { e.restore(); return; - } catch (const builtin_exception &e) { e.set_error(); return; - } catch (const std::bad_alloc &e) { PyErr_SetString(PyExc_MemoryError, e.what()); return; - } catch (const std::domain_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::invalid_argument &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::length_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, e.what()); return; - } catch (const std::range_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::exception &e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return; - } catch (...) { - PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!"); - return; - } - } - ); - } - return *internals_ptr; -} - -PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) { - auto const &type_dict = get_internals().registered_types_py; - do { - auto it = type_dict.find(type); - if (it != type_dict.end()) - return (detail::type_info *) it->second; - type = type->tp_base; - if (!type) - return nullptr; - } while (true); -} - -PYBIND11_NOINLINE inline detail::type_info *get_type_info(const std::type_info &tp, - bool throw_if_missing = false) { - auto &types = get_internals().registered_types_cpp; - - auto it = types.find(std::type_index(tp)); - if (it != types.end()) - return (detail::type_info *) it->second; - if (throw_if_missing) { - std::string tname = tp.name(); - detail::clean_type_id(tname); - pybind11_fail("pybind11::detail::get_type_info: unable to find type info for \"" + tname + "\""); - } - return nullptr; -} - -PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { - detail::type_info *type_info = get_type_info(tp, throw_if_missing); - return handle(type_info ? ((PyObject *) type_info->type) : nullptr); -} - -PYBIND11_NOINLINE inline bool isinstance_generic(handle obj, const std::type_info &tp) { - const auto type = detail::get_type_handle(tp, false); - if (!type) - return false; - - const auto result = PyObject_IsInstance(obj.ptr(), type.ptr()); - if (result == -1) - throw error_already_set(); - return result != 0; -} - -PYBIND11_NOINLINE inline std::string error_string() { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred"); - return "Unknown internal error occurred"; - } - - error_scope scope; // Preserve error state - - std::string errorString; - if (scope.type) { - errorString += handle(scope.type).attr("__name__").cast(); - errorString += ": "; - } - if (scope.value) - errorString += (std::string) str(scope.value); - - PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace); - - if (scope.trace) { - PyFrameObject *frame = ((PyTracebackObject *) scope.trace)->tb_frame; - if (frame) { - errorString += "\n\nAt:\n"; - while (frame) { - int lineno = PyFrame_GetLineNumber(frame); - errorString += - " " + handle(frame->f_code->co_filename).cast() + - "(" + std::to_string(lineno) + "): " + - handle(frame->f_code->co_name).cast() + "\n"; - frame = frame->f_back; - } - } - } - - return errorString; -} - -PYBIND11_NOINLINE inline handle get_object_handle(const void *ptr, const detail::type_info *type ) { - auto &instances = get_internals().registered_instances; - auto range = instances.equal_range(ptr); - for (auto it = range.first; it != range.second; ++it) { - auto instance_type = detail::get_type_info(Py_TYPE(it->second)); - if (instance_type && instance_type == type) - return handle((PyObject *) it->second); - } - return handle(); -} - -inline PyThreadState *get_thread_state_unchecked() { -#if PY_VERSION_HEX < 0x03000000 - return _PyThreadState_Current; -#elif PY_VERSION_HEX < 0x03050000 - return (PyThreadState*) _Py_atomic_load_relaxed(&_PyThreadState_Current); -#elif PY_VERSION_HEX < 0x03050200 - return (PyThreadState*) _PyThreadState_Current.value; -#else - return _PyThreadState_UncheckedGet(); -#endif -} - -// Forward declaration -inline void keep_alive_impl(handle nurse, handle patient); - -class type_caster_generic { -public: - PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) - : typeinfo(get_type_info(type_info)) { } - - PYBIND11_NOINLINE bool load(handle src, bool convert) { - if (!src) - return false; - return load(src, convert, Py_TYPE(src.ptr())); - } - - bool load(handle src, bool convert, PyTypeObject *tobj) { - if (!src || !typeinfo) - return false; - if (src.is_none()) { - value = nullptr; - return true; - } - - if (typeinfo->simple_type) { /* Case 1: no multiple inheritance etc. involved */ - /* Check if we can safely perform a reinterpret-style cast */ - if (PyType_IsSubtype(tobj, typeinfo->type)) { - value = reinterpret_cast *>(src.ptr())->value; - return true; - } - } else { /* Case 2: multiple inheritance */ - /* Check if we can safely perform a reinterpret-style cast */ - if (tobj == typeinfo->type) { - value = reinterpret_cast *>(src.ptr())->value; - return true; - } - - /* If this is a python class, also check the parents recursively */ - auto const &type_dict = get_internals().registered_types_py; - bool new_style_class = PyType_Check(tobj); - if (type_dict.find(tobj) == type_dict.end() && new_style_class && tobj->tp_bases) { - auto parents = reinterpret_borrow(tobj->tp_bases); - for (handle parent : parents) { - bool result = load(src, convert, (PyTypeObject *) parent.ptr()); - if (result) - return true; - } - } - - /* Try implicit casts */ - for (auto &cast : typeinfo->implicit_casts) { - type_caster_generic sub_caster(*cast.first); - if (sub_caster.load(src, convert)) { - value = cast.second(sub_caster.value); - return true; - } - } - } - - /* Perform an implicit conversion */ - if (convert) { - for (auto &converter : typeinfo->implicit_conversions) { - temp = reinterpret_steal(converter(src.ptr(), typeinfo->type)); - if (load(temp, false)) - return true; - } - for (auto &converter : *typeinfo->direct_conversions) { - if (converter(src.ptr(), value)) - return true; - } - } - return false; - } - - PYBIND11_NOINLINE static handle cast(const void *_src, return_value_policy policy, handle parent, - const std::type_info *type_info, - const std::type_info *type_info_backup, - void *(*copy_constructor)(const void *), - void *(*move_constructor)(const void *), - const void *existing_holder = nullptr) { - void *src = const_cast(_src); - if (src == nullptr) - return none().inc_ref(); - - auto &internals = get_internals(); - - auto it = internals.registered_types_cpp.find(std::type_index(*type_info)); - if (it == internals.registered_types_cpp.end()) { - type_info = type_info_backup; - it = internals.registered_types_cpp.find(std::type_index(*type_info)); - } - - if (it == internals.registered_types_cpp.end()) { - std::string tname = type_info->name(); - detail::clean_type_id(tname); - std::string msg = "Unregistered type : " + tname; - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return handle(); - } - - auto tinfo = (const detail::type_info *) it->second; - - auto it_instances = internals.registered_instances.equal_range(src); - for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { - auto instance_type = detail::get_type_info(Py_TYPE(it_i->second)); - if (instance_type && instance_type == tinfo) - return handle((PyObject *) it_i->second).inc_ref(); - } - - auto inst = reinterpret_steal(PyType_GenericAlloc(tinfo->type, 0)); - - auto wrapper = (instance *) inst.ptr(); - - wrapper->value = nullptr; - wrapper->owned = false; - - switch (policy) { - case return_value_policy::automatic: - case return_value_policy::take_ownership: - wrapper->value = src; - wrapper->owned = true; - break; - - case return_value_policy::automatic_reference: - case return_value_policy::reference: - wrapper->value = src; - wrapper->owned = false; - break; - - case return_value_policy::copy: - if (copy_constructor) - wrapper->value = copy_constructor(src); - else - throw cast_error("return_value_policy = copy, but the " - "object is non-copyable!"); - wrapper->owned = true; - break; - - case return_value_policy::move: - if (move_constructor) - wrapper->value = move_constructor(src); - else if (copy_constructor) - wrapper->value = copy_constructor(src); - else - throw cast_error("return_value_policy = move, but the " - "object is neither movable nor copyable!"); - wrapper->owned = true; - break; - - case return_value_policy::reference_internal: - wrapper->value = src; - wrapper->owned = false; - detail::keep_alive_impl(inst, parent); - break; - - default: - throw cast_error("unhandled return_value_policy: should not happen!"); - } - - tinfo->init_holder(inst.ptr(), existing_holder); - - internals.registered_instances.emplace(wrapper->value, inst.ptr()); - - return inst.release(); - } - -protected: - const type_info *typeinfo = nullptr; - void *value = nullptr; - object temp; -}; - -/* Determine suitable casting operator */ -template -using cast_op_type = typename std::conditional::type>::value, - typename std::add_pointer>::type, - typename std::add_lvalue_reference>::type>::type; - -// std::is_copy_constructible isn't quite enough: it lets std::vector (and similar) through when -// T is non-copyable, but code containing such a copy constructor fails to actually compile. -template struct is_copy_constructible : std::is_copy_constructible {}; - -// Specialization for types that appear to be copy constructible but also look like stl containers -// (we specifically check for: has `value_type` and `reference` with `reference = value_type&`): if -// so, copy constructability depends on whether the value_type is copy constructible. -template struct is_copy_constructible::value && - std::is_same::value - >> : std::is_copy_constructible {}; - -/// Generic type caster for objects stored on the heap -template class type_caster_base : public type_caster_generic { - using itype = intrinsic_t; -public: - static PYBIND11_DESCR name() { return type_descr(_()); } - - type_caster_base() : type_caster_base(typeid(type)) { } - explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) { } - - static handle cast(const itype &src, return_value_policy policy, handle parent) { - if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) - policy = return_value_policy::copy; - return cast(&src, policy, parent); - } - - static handle cast(itype &&src, return_value_policy, handle parent) { - return cast(&src, return_value_policy::move, parent); - } - - static handle cast(const itype *src, return_value_policy policy, handle parent) { - return type_caster_generic::cast( - src, policy, parent, src ? &typeid(*src) : nullptr, &typeid(type), - make_copy_constructor(src), make_move_constructor(src)); - } - - template using cast_op_type = pybind11::detail::cast_op_type; - - operator itype*() { return (type *) value; } - operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); } - -protected: - typedef void *(*Constructor)(const void *stream); -#if !defined(_MSC_VER) - /* Only enabled when the types are {copy,move}-constructible *and* when the type - does not have a private operator new implementaton. */ - template ::value>> static auto make_copy_constructor(const T *value) -> decltype(new T(*value), Constructor(nullptr)) { - return [](const void *arg) -> void * { return new T(*((const T *) arg)); }; } - template static auto make_move_constructor(const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr)) { - return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *) arg))); }; } -#else - /* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations. - Use a workaround that only tests for constructibility for now. */ - template ::value>> - static Constructor make_copy_constructor(const T *value) { - return [](const void *arg) -> void * { return new T(*((const T *)arg)); }; } - template ::value>> - static Constructor make_move_constructor(const T *value) { - return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *)arg))); }; } -#endif - - static Constructor make_copy_constructor(...) { return nullptr; } - static Constructor make_move_constructor(...) { return nullptr; } -}; - -template class type_caster : public type_caster_base { }; -template using make_caster = type_caster>; - -template class type_caster> : public type_caster_base { -public: - static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { - return type_caster_base::cast(&src.get(), policy, parent); - } - template using cast_op_type = std::reference_wrapper; - operator std::reference_wrapper() { return std::ref(*((type *) this->value)); } -}; - -#define PYBIND11_TYPE_CASTER(type, py_name) \ - protected: \ - type value; \ - public: \ - static PYBIND11_DESCR name() { return type_descr(py_name); } \ - static handle cast(const type *src, return_value_policy policy, handle parent) { \ - return cast(*src, policy, parent); \ - } \ - operator type*() { return &value; } \ - operator type&() { return value; } \ - template using cast_op_type = pybind11::detail::cast_op_type<_T> - - -template -struct type_caster::value>> { - typedef typename std::conditional::type _py_type_0; - typedef typename std::conditional::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>::type _py_type_1; - typedef typename std::conditional::value, double, _py_type_1>::type py_type; -public: - - bool load(handle src, bool) { - py_type py_value; - - if (!src) { - return false; - } if (std::is_floating_point::value) { - py_value = (py_type) PyFloat_AsDouble(src.ptr()); - } else if (sizeof(T) <= sizeof(long)) { - if (PyFloat_Check(src.ptr())) - return false; - if (std::is_signed::value) - py_value = (py_type) PyLong_AsLong(src.ptr()); - else - py_value = (py_type) PyLong_AsUnsignedLong(src.ptr()); - } else { - if (PyFloat_Check(src.ptr())) - return false; - if (std::is_signed::value) - py_value = (py_type) PYBIND11_LONG_AS_LONGLONG(src.ptr()); - else - py_value = (py_type) PYBIND11_LONG_AS_UNSIGNED_LONGLONG(src.ptr()); - } - - if ((py_value == (py_type) -1 && PyErr_Occurred()) || - (std::is_integral::value && sizeof(py_type) != sizeof(T) && - (py_value < (py_type) std::numeric_limits::min() || - py_value > (py_type) std::numeric_limits::max()))) { -#if PY_VERSION_HEX < 0x03000000 - bool type_error = PyErr_ExceptionMatches(PyExc_SystemError); -#else - bool type_error = PyErr_ExceptionMatches(PyExc_TypeError); -#endif - PyErr_Clear(); - if (type_error && PyNumber_Check(src.ptr())) { - auto tmp = reinterpret_borrow(std::is_floating_point::value - ? PyNumber_Float(src.ptr()) - : PyNumber_Long(src.ptr())); - PyErr_Clear(); - return load(tmp, false); - } - return false; - } - - value = (T) py_value; - return true; - } - - static handle cast(T src, return_value_policy /* policy */, handle /* parent */) { - if (std::is_floating_point::value) { - return PyFloat_FromDouble((double) src); - } else if (sizeof(T) <= sizeof(long)) { - if (std::is_signed::value) - return PyLong_FromLong((long) src); - else - return PyLong_FromUnsignedLong((unsigned long) src); - } else { - if (std::is_signed::value) - return PyLong_FromLongLong((long long) src); - else - return PyLong_FromUnsignedLongLong((unsigned long long) src); - } - } - - PYBIND11_TYPE_CASTER(T, _::value>("int", "float")); -}; - -template struct void_caster { -public: - bool load(handle, bool) { return false; } - static handle cast(T, return_value_policy /* policy */, handle /* parent */) { - return none().inc_ref(); - } - PYBIND11_TYPE_CASTER(T, _("None")); -}; - -template <> class type_caster : public void_caster {}; - -template <> class type_caster : public type_caster { -public: - using type_caster::cast; - - bool load(handle h, bool) { - if (!h) { - return false; - } else if (h.is_none()) { - value = nullptr; - return true; - } - - /* Check if this is a capsule */ - if (isinstance(h)) { - value = reinterpret_borrow(h); - return true; - } - - /* Check if this is a C++ type */ - if (get_type_info((PyTypeObject *) h.get_type().ptr())) { - value = ((instance *) h.ptr())->value; - return true; - } - - /* Fail */ - return false; - } - - static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) { - if (ptr) - return capsule(ptr).release(); - else - return none().inc_ref(); - } - - template using cast_op_type = void*&; - operator void *&() { return value; } - static PYBIND11_DESCR name() { return type_descr(_("capsule")); } -private: - void *value = nullptr; -}; - -template <> class type_caster : public type_caster { }; - -template <> class type_caster { -public: - bool load(handle src, bool) { - if (!src) return false; - else if (src.ptr() == Py_True) { value = true; return true; } - else if (src.ptr() == Py_False) { value = false; return true; } - else return false; - } - static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) { - return handle(src ? Py_True : Py_False).inc_ref(); - } - PYBIND11_TYPE_CASTER(bool, _("bool")); -}; - -template <> class type_caster { -public: - bool load(handle src, bool) { - object temp; - handle load_src = src; - if (!src) { - return false; - } else if (PyUnicode_Check(load_src.ptr())) { - temp = reinterpret_steal(PyUnicode_AsUTF8String(load_src.ptr())); - if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError - load_src = temp; - } - char *buffer; - ssize_t length; - int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(load_src.ptr(), &buffer, &length); - if (err == -1) { PyErr_Clear(); return false; } // TypeError - value = std::string(buffer, (size_t) length); - success = true; - return true; - } - - static handle cast(const std::string &src, return_value_policy /* policy */, handle /* parent */) { - return PyUnicode_FromStringAndSize(src.c_str(), (ssize_t) src.length()); - } - - PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME)); -protected: - bool success = false; -}; - -template class type_caster> { -public: - static handle cast(std::unique_ptr &&src, return_value_policy policy, handle parent) { - handle result = type_caster_base::cast(src.get(), policy, parent); - if (result) - src.release(); - return result; - } - static PYBIND11_DESCR name() { return type_caster_base::name(); } -}; - -template <> class type_caster { -public: - bool load(handle src, bool) { - object temp; - handle load_src = src; - if (!src) { - return false; - } else if (!PyUnicode_Check(load_src.ptr())) { - temp = reinterpret_steal(PyUnicode_FromObject(load_src.ptr())); - if (!temp) { PyErr_Clear(); return false; } - load_src = temp; - } - wchar_t *buffer = nullptr; - ssize_t length = -1; -#if PY_MAJOR_VERSION >= 3 - buffer = PyUnicode_AsWideCharString(load_src.ptr(), &length); -#else - temp = reinterpret_steal( - sizeof(wchar_t) == sizeof(short) - ? PyUnicode_AsUTF16String(load_src.ptr()) - : PyUnicode_AsUTF32String(load_src.ptr())); - if (temp) { - int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), (char **) &buffer, &length); - if (err == -1) { buffer = nullptr; } // TypeError - length = length / (ssize_t) sizeof(wchar_t) - 1; ++buffer; // Skip BOM - } -#endif - if (!buffer) { PyErr_Clear(); return false; } - value = std::wstring(buffer, (size_t) length); - success = true; - return true; - } - - static handle cast(const std::wstring &src, return_value_policy /* policy */, handle /* parent */) { - return PyUnicode_FromWideChar(src.c_str(), (ssize_t) src.length()); - } - - PYBIND11_TYPE_CASTER(std::wstring, _(PYBIND11_STRING_NAME)); -protected: - bool success = false; -}; - -template <> class type_caster : public type_caster { -public: - bool load(handle src, bool convert) { - if (src.is_none()) return true; - return type_caster::load(src, convert); - } - - static handle cast(const char *src, return_value_policy /* policy */, handle /* parent */) { - if (src == nullptr) return none().inc_ref(); - return PyUnicode_FromString(src); - } - - static handle cast(char src, return_value_policy /* policy */, handle /* parent */) { - char str[2] = { src, '\0' }; - return PyUnicode_DecodeLatin1(str, 1, nullptr); - } - - operator char*() { return success ? (char *) value.c_str() : nullptr; } - operator char&() { return value[0]; } - - static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); } -}; - -template <> class type_caster : public type_caster { -public: - bool load(handle src, bool convert) { - if (src.is_none()) return true; - return type_caster::load(src, convert); - } - - static handle cast(const wchar_t *src, return_value_policy /* policy */, handle /* parent */) { - if (src == nullptr) return none().inc_ref(); - return PyUnicode_FromWideChar(src, (ssize_t) wcslen(src)); - } - - static handle cast(wchar_t src, return_value_policy /* policy */, handle /* parent */) { - wchar_t wstr[2] = { src, L'\0' }; - return PyUnicode_FromWideChar(wstr, 1); - } - - operator wchar_t*() { return success ? (wchar_t *) value.c_str() : nullptr; } - operator wchar_t&() { return value[0]; } - - static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); } -}; - -template class type_caster> { - typedef std::pair type; -public: - bool load(handle src, bool convert) { - if (!src) - return false; - else if (!PyTuple_Check(src.ptr()) || PyTuple_Size(src.ptr()) != 2) - return false; - return first.load(PyTuple_GET_ITEM(src.ptr(), 0), convert) && - second.load(PyTuple_GET_ITEM(src.ptr(), 1), convert); - } - - static handle cast(const type &src, return_value_policy policy, handle parent) { - auto o1 = reinterpret_steal(make_caster::cast(src.first, policy, parent)); - auto o2 = reinterpret_steal(make_caster::cast(src.second, policy, parent)); - if (!o1 || !o2) - return handle(); - tuple result(2); - PyTuple_SET_ITEM(result.ptr(), 0, o1.release().ptr()); - PyTuple_SET_ITEM(result.ptr(), 1, o2.release().ptr()); - return result.release(); - } - - static PYBIND11_DESCR name() { - return type_descr( - _("Tuple[") + make_caster::name() + _(", ") + make_caster::name() + _("]") - ); - } - - template using cast_op_type = type; - - operator type() { - return type(first.operator typename make_caster::template cast_op_type(), - second.operator typename make_caster::template cast_op_type()); - } -protected: - make_caster first; - make_caster second; -}; - -template class type_caster> { - typedef std::tuple type; - typedef std::tuple...> itype; - typedef std::tuple args_type; - typedef std::tuple args_kwargs_type; -public: - enum { size = sizeof...(Tuple) }; - - static constexpr const bool has_kwargs = std::is_same::value; - static constexpr const bool has_args = has_kwargs || std::is_same::value; - - bool load(handle src, bool convert) { - if (!src || !PyTuple_Check(src.ptr()) || PyTuple_GET_SIZE(src.ptr()) != size) - return false; - return load(src, convert, typename make_index_sequence::type()); - } - - template ::value && - !std::is_same::value, int> = 0> - bool load_args(handle args, handle, bool convert) { - return load(args, convert, typename make_index_sequence::type()); - } - - template ::value, int> = 0> - bool load_args(handle args, handle, bool convert) { - std::get<0>(value).load(args, convert); - return true; - } - - template ::value, int> = 0> - bool load_args(handle args, handle kwargs, bool convert) { - std::get<0>(value).load(args, convert); - std::get<1>(value).load(kwargs, convert); - return true; - } - - static handle cast(const type &src, return_value_policy policy, handle parent) { - return cast(src, policy, parent, typename make_index_sequence::type()); - } - - static PYBIND11_DESCR element_names() { - return detail::concat(make_caster::name()...); - } - - static PYBIND11_DESCR name() { - return type_descr(_("Tuple[") + element_names() + _("]")); - } - - template enable_if_t::value, ReturnValue> call(Func &&f) { - return call(std::forward(f), typename make_index_sequence::type()); - } - - template enable_if_t::value, void_type> call(Func &&f) { - call(std::forward(f), typename make_index_sequence::type()); - return void_type(); - } - - template using cast_op_type = type; - - operator type() { - return cast(typename make_index_sequence::type()); - } - -protected: - template ReturnValue call(Func &&f, index_sequence) { - return f(std::get(value) - .operator typename make_caster::template cast_op_type()...); - } - - template type cast(index_sequence) { - return type(std::get(value) - .operator typename make_caster::template cast_op_type()...); - } - - template bool load(handle src, bool convert, index_sequence) { - std::array success {{ - std::get(value).load(PyTuple_GET_ITEM(src.ptr(), Indices), convert)... - }}; - (void) convert; /* avoid a warning when the tuple is empty */ - for (bool r : success) - if (!r) - return false; - return true; - } - - /* Implementation: Convert a C++ tuple into a Python tuple */ - template static handle cast(const type &src, return_value_policy policy, handle parent, index_sequence) { - std::array entries {{ - reinterpret_steal(make_caster::cast(std::get(src), policy, parent))... - }}; - for (const auto &entry: entries) - if (!entry) - return handle(); - tuple result(size); - int counter = 0; - for (auto & entry: entries) - PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr()); - return result.release(); - } - -protected: - std::tuple...> value; -}; - -/// Type caster for holder types like std::shared_ptr, etc. -template class type_caster_holder : public type_caster_base { -public: - using base = type_caster_base; - using base::base; - using base::cast; - using base::typeinfo; - using base::value; - using base::temp; - - PYBIND11_NOINLINE bool load(handle src, bool convert) { - return load(src, convert, Py_TYPE(src.ptr())); - } - - bool load(handle src, bool convert, PyTypeObject *tobj) { - if (!src || !typeinfo) - return false; - if (src.is_none()) { - value = nullptr; - return true; - } - - if (typeinfo->simple_type) { /* Case 1: no multiple inheritance etc. involved */ - /* Check if we can safely perform a reinterpret-style cast */ - if (PyType_IsSubtype(tobj, typeinfo->type)) { - auto inst = (instance *) src.ptr(); - value = (void *) inst->value; - holder = inst->holder; - return true; - } - } else { /* Case 2: multiple inheritance */ - /* Check if we can safely perform a reinterpret-style cast */ - if (tobj == typeinfo->type) { - auto inst = (instance *) src.ptr(); - value = (void *) inst->value; - holder = inst->holder; - return true; - } - - /* If this is a python class, also check the parents recursively */ - auto const &type_dict = get_internals().registered_types_py; - bool new_style_class = PyType_Check(tobj); - if (type_dict.find(tobj) == type_dict.end() && new_style_class && tobj->tp_bases) { - auto parents = reinterpret_borrow(tobj->tp_bases); - for (handle parent : parents) { - bool result = load(src, convert, (PyTypeObject *) parent.ptr()); - if (result) - return true; - } - } - - if (try_implicit_casts(src, convert)) - return true; - } - - if (convert) { - for (auto &converter : typeinfo->implicit_conversions) { - temp = reinterpret_steal(converter(src.ptr(), typeinfo->type)); - if (load(temp, false)) - return true; - } - } - - return false; - } - - template ::value, int> = 0> - bool try_implicit_casts(handle, bool) { return false; } - - template ::value, int> = 0> - bool try_implicit_casts(handle src, bool convert) { - for (auto &cast : typeinfo->implicit_casts) { - type_caster_holder sub_caster(*cast.first); - if (sub_caster.load(src, convert)) { - value = cast.second(sub_caster.value); - holder = holder_type(sub_caster.holder, (type *) value); - return true; - } - } - return false; - } - - explicit operator type*() { return this->value; } - explicit operator type&() { return *(this->value); } - explicit operator holder_type*() { return &holder; } - - // Workaround for Intel compiler bug - // see pybind11 issue 94 - #if defined(__ICC) || defined(__INTEL_COMPILER) - operator holder_type&() { return holder; } - #else - explicit operator holder_type&() { return holder; } - #endif - - static handle cast(const holder_type &src, return_value_policy, handle) { - return type_caster_generic::cast( - src.get(), return_value_policy::take_ownership, handle(), - src.get() ? &typeid(*src.get()) : nullptr, &typeid(type), - nullptr, nullptr, &src); - } - -protected: - holder_type holder; -}; - -/// Specialize for the common std::shared_ptr, so users don't need to -template -class type_caster> : public type_caster_holder> { }; - -/// Create a specialization for custom holder types (silently ignores std::shared_ptr) -#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) \ - namespace pybind11 { namespace detail { \ - template \ - class type_caster::value>> \ - : public type_caster_holder { }; \ - }} - -// PYBIND11_DECLARE_HOLDER_TYPE holder types: -template struct is_holder_type : - std::is_base_of, detail::type_caster> {}; -// Specialization for always-supported unique_ptr holders: -template struct is_holder_type> : - std::true_type {}; - -template struct handle_type_name { static PYBIND11_DESCR name() { return _(); } }; -template <> struct handle_type_name { static PYBIND11_DESCR name() { return _(PYBIND11_BYTES_NAME); } }; -template <> struct handle_type_name { static PYBIND11_DESCR name() { return _("*args"); } }; -template <> struct handle_type_name { static PYBIND11_DESCR name() { return _("**kwargs"); } }; - -template -struct pyobject_caster { - template ::value, int> = 0> - bool load(handle src, bool /* convert */) { value = src; return static_cast(value); } - - template ::value, int> = 0> - bool load(handle src, bool /* convert */) { - if (!isinstance(src)) - return false; - value = reinterpret_borrow(src); - return true; - } - - static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) { - return src.inc_ref(); - } - PYBIND11_TYPE_CASTER(type, handle_type_name::name()); -}; - -template -class type_caster::value>> : public pyobject_caster { }; - -// Our conditions for enabling moving are quite restrictive: -// At compile time: -// - T needs to be a non-const, non-pointer, non-reference type -// - type_caster::operator T&() must exist -// - the type must be move constructible (obviously) -// At run-time: -// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it -// must have ref_count() == 1)h -// If any of the above are not satisfied, we fall back to copying. -template struct move_is_plain_type : std::false_type {}; -template struct move_is_plain_type::value && !std::is_pointer::value && !std::is_reference::value && !std::is_const::value - >> : std::true_type { }; -template struct move_always : std::false_type {}; -template struct move_always::value && - !std::is_copy_constructible::value && std::is_move_constructible::value && - std::is_same>().operator T&()), T&>::value - >> : std::true_type { }; -template struct move_if_unreferenced : std::false_type {}; -template struct move_if_unreferenced::value && - !move_always::value && std::is_move_constructible::value && - std::is_same>().operator T&()), T&>::value - >> : std::true_type { }; -template using move_never = std::integral_constant::value && !move_if_unreferenced::value>; - -// Detect whether returning a `type` from a cast on type's type_caster is going to result in a -// reference or pointer to a local variable of the type_caster. Basically, only -// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe; -// everything else returns a reference/pointer to a local variable. -template using cast_is_temporary_value_reference = bool_constant< - (std::is_reference::value || std::is_pointer::value) && - !std::is_base_of>::value ->; - -// Basic python -> C++ casting; throws if casting fails -template type_caster &load_type(type_caster &conv, const handle &handle) { - if (!conv.load(handle, true)) { -#if defined(NDEBUG) - throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)"); -#else - throw cast_error("Unable to cast Python instance of type " + - (std::string) str(handle.get_type()) + " to C++ type '" + type_id() + "''"); -#endif - } - return conv; -} -// Wrapper around the above that also constructs and returns a type_caster -template make_caster load_type(const handle &handle) { - make_caster conv; - load_type(conv, handle); - return conv; -} - -NAMESPACE_END(detail) - -// pytype -> C++ type -template ::value, int> = 0> -T cast(const handle &handle) { - static_assert(!detail::cast_is_temporary_value_reference::value, - "Unable to cast type to reference: value is local to type caster"); - using type_caster = detail::make_caster; - return detail::load_type(handle).operator typename type_caster::template cast_op_type(); -} - -// pytype -> pytype (calls converting constructor) -template ::value, int> = 0> -T cast(const handle &handle) { return T(reinterpret_borrow(handle)); } - -// C++ type -> py::object -template ::value, int> = 0> -object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference, - handle parent = handle()) { - if (policy == return_value_policy::automatic) - policy = std::is_pointer::value ? return_value_policy::take_ownership : return_value_policy::copy; - else if (policy == return_value_policy::automatic_reference) - policy = std::is_pointer::value ? return_value_policy::reference : return_value_policy::copy; - return reinterpret_steal(detail::make_caster::cast(value, policy, parent)); -} - -template T handle::cast() const { return pybind11::cast(*this); } -template <> inline void handle::cast() const { return; } - -template -detail::enable_if_t::value || detail::move_if_unreferenced::value, T> move(object &&obj) { - if (obj.ref_count() > 1) -#if defined(NDEBUG) - throw cast_error("Unable to cast Python instance to C++ rvalue: instance has multiple references" - " (compile in debug mode for details)"); -#else - throw cast_error("Unable to move from Python " + (std::string) str(obj.get_type()) + - " instance to C++ " + type_id() + " instance: instance has multiple references"); -#endif - - // Move into a temporary and return that, because the reference may be a local value of `conv` - T ret = std::move(detail::load_type(obj).operator T&()); - return ret; -} - -// Calling cast() on an rvalue calls pybind::cast with the object rvalue, which does: -// - If we have to move (because T has no copy constructor), do it. This will fail if the moved -// object has multiple references, but trying to copy will fail to compile. -// - If both movable and copyable, check ref count: if 1, move; otherwise copy -// - Otherwise (not movable), copy. -template detail::enable_if_t::value, T> cast(object &&object) { - return move(std::move(object)); -} -template detail::enable_if_t::value, T> cast(object &&object) { - if (object.ref_count() > 1) - return cast(object); - else - return move(std::move(object)); -} -template detail::enable_if_t::value, T> cast(object &&object) { - return cast(object); -} - -template T object::cast() const & { return pybind11::cast(*this); } -template T object::cast() && { return pybind11::cast(std::move(*this)); } -template <> inline void object::cast() const & { return; } -template <> inline void object::cast() && { return; } - -NAMESPACE_BEGIN(detail) - -struct overload_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the OVERLOAD_INT macro -template using overload_caster_t = conditional_t< - cast_is_temporary_value_reference::value, make_caster, overload_unused>; - -// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then -// store the result in the given variable. For other types, this is a no-op. -template enable_if_t::value, T> cast_ref(object &&o, make_caster &caster) { - return load_type(caster, o).operator typename make_caster::template cast_op_type(); -} -template enable_if_t::value, T> cast_ref(object &&, overload_unused &) { - pybind11_fail("Internal error: cast_ref fallback invoked"); } - -// Trampoline use: Having a pybind11::cast with an invalid reference type is going to static_assert, even -// though if it's in dead code, so we provide a "trampoline" to pybind11::cast that only does anything in -// cases where pybind11::cast is valid. -template enable_if_t::value, T> cast_safe(object &&o) { - return pybind11::cast(std::move(o)); } -template enable_if_t::value, T> cast_safe(object &&) { - pybind11_fail("Internal error: cast_safe fallback invoked"); } -template <> inline void cast_safe(object &&) {} - -NAMESPACE_END(detail) - -template tuple make_tuple(Args&&... args_) { - const size_t size = sizeof...(Args); - std::array args { - { reinterpret_steal(detail::make_caster::cast( - std::forward(args_), policy, nullptr))... } - }; - for (auto &arg_value : args) { - if (!arg_value) { -#if defined(NDEBUG) - throw cast_error("make_tuple(): unable to convert arguments to Python object (compile in debug mode for details)"); -#else - throw cast_error("make_tuple(): unable to convert arguments of types '" + - (std::string) type_id>() + "' to Python object"); -#endif - } - } - tuple result(size); - int counter = 0; - for (auto &arg_value : args) - PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr()); - return result; -} - -/// Annotation for keyword arguments -struct arg { - constexpr explicit arg(const char *name) : name(name) { } - template arg_v operator=(T &&value) const; - - const char *name; -}; - -/// Annotation for keyword arguments with values -struct arg_v : arg { - template - arg_v(const char *name, T &&x, const char *descr = nullptr) - : arg(name), - value(reinterpret_steal( - detail::make_caster::cast(x, return_value_policy::automatic, {}) - )), - descr(descr) -#if !defined(NDEBUG) - , type(type_id()) -#endif - { } - - object value; - const char *descr; -#if !defined(NDEBUG) - std::string type; -#endif -}; - -template -arg_v arg::operator=(T &&value) const { return {name, std::forward(value)}; } - -/// Alias for backward compatibility -- to be removed in version 2.0 -template using arg_t = arg_v; - -inline namespace literals { -/// String literal version of arg -constexpr arg operator"" _a(const char *name, size_t) { return arg(name); } -} - -NAMESPACE_BEGIN(detail) -NAMESPACE_BEGIN(constexpr_impl) -/// Implementation details for constexpr functions -constexpr int first(int i) { return i; } -template -constexpr int first(int i, T v, Ts... vs) { return v ? i : first(i + 1, vs...); } - -constexpr int last(int /*i*/, int result) { return result; } -template -constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); } -NAMESPACE_END(constexpr_impl) - -/// Return the index of the first type in Ts which satisfies Predicate -template class Predicate, typename... Ts> -constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate::value...); } - -/// Return the index of the last type in Ts which satisfies Predicate -template class Predicate, typename... Ts> -constexpr int constexpr_last() { return constexpr_impl::last(0, -1, Predicate::value...); } - -/// Helper class which collects only positional arguments for a Python function call. -/// A fancier version below can collect any argument, but this one is optimal for simple calls. -template -class simple_collector { -public: - template - explicit simple_collector(Ts &&...values) - : m_args(pybind11::make_tuple(std::forward(values)...)) { } - - const tuple &args() const & { return m_args; } - dict kwargs() const { return {}; } - - tuple args() && { return std::move(m_args); } - - /// Call a Python function and pass the collected arguments - object call(PyObject *ptr) const { - PyObject *result = PyObject_CallObject(ptr, m_args.ptr()); - if (!result) - throw error_already_set(); - return reinterpret_steal(result); - } - -private: - tuple m_args; -}; - -/// Helper class which collects positional, keyword, * and ** arguments for a Python function call -template -class unpacking_collector { -public: - template - explicit unpacking_collector(Ts &&...values) { - // Tuples aren't (easily) resizable so a list is needed for collection, - // but the actual function call strictly requires a tuple. - auto args_list = list(); - int _[] = { 0, (process(args_list, std::forward(values)), 0)... }; - ignore_unused(_); - - m_args = std::move(args_list); - } - - const tuple &args() const & { return m_args; } - const dict &kwargs() const & { return m_kwargs; } - - tuple args() && { return std::move(m_args); } - dict kwargs() && { return std::move(m_kwargs); } - - /// Call a Python function and pass the collected arguments - object call(PyObject *ptr) const { - PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr()); - if (!result) - throw error_already_set(); - return reinterpret_steal(result); - } - -private: - template - void process(list &args_list, T &&x) { - auto o = reinterpret_steal(detail::make_caster::cast(std::forward(x), policy, {})); - if (!o) { -#if defined(NDEBUG) - argument_cast_error(); -#else - argument_cast_error(std::to_string(args_list.size()), type_id()); -#endif - } - args_list.append(o); - } - - void process(list &args_list, detail::args_proxy ap) { - for (const auto &a : ap) - args_list.append(a); - } - - void process(list &/*args_list*/, arg_v a) { - if (m_kwargs.contains(a.name)) { -#if defined(NDEBUG) - multiple_values_error(); -#else - multiple_values_error(a.name); -#endif - } - if (!a.value) { -#if defined(NDEBUG) - argument_cast_error(); -#else - argument_cast_error(a.name, a.type); -#endif - } - m_kwargs[a.name] = a.value; - } - - void process(list &/*args_list*/, detail::kwargs_proxy kp) { - if (!kp) - return; - for (const auto &k : reinterpret_borrow(kp)) { - if (m_kwargs.contains(k.first)) { -#if defined(NDEBUG) - multiple_values_error(); -#else - multiple_values_error(str(k.first)); -#endif - } - m_kwargs[k.first] = k.second; - } - } - - [[noreturn]] static void multiple_values_error() { - throw type_error("Got multiple values for keyword argument " - "(compile in debug mode for details)"); - } - - [[noreturn]] static void multiple_values_error(std::string name) { - throw type_error("Got multiple values for keyword argument '" + name + "'"); - } - - [[noreturn]] static void argument_cast_error() { - throw cast_error("Unable to convert call argument to Python object " - "(compile in debug mode for details)"); - } - - [[noreturn]] static void argument_cast_error(std::string name, std::string type) { - throw cast_error("Unable to convert call argument '" + name - + "' of type '" + type + "' to Python object"); - } - -private: - tuple m_args; - dict m_kwargs; -}; - -/// Collect only positional arguments for a Python function call -template ::value>> -simple_collector collect_arguments(Args &&...args) { - return simple_collector(std::forward(args)...); -} - -/// Collect all arguments, including keywords and unpacking (only instantiated when needed) -template ::value>> -unpacking_collector collect_arguments(Args &&...args) { - // Following argument order rules for generalized unpacking according to PEP 448 - static_assert( - constexpr_last() < constexpr_first() - && constexpr_last() < constexpr_first(), - "Invalid function call: positional args must precede keywords and ** unpacking; " - "* unpacking must precede ** unpacking" - ); - return unpacking_collector(std::forward(args)...); -} - -template -template -object object_api::operator()(Args &&...args) const { - return detail::collect_arguments(std::forward(args)...).call(derived().ptr()); -} - -template -template -object object_api::call(Args &&...args) const { - return operator()(std::forward(args)...); -} - -NAMESPACE_END(detail) - -#define PYBIND11_MAKE_OPAQUE(Type) \ - namespace pybind11 { namespace detail { \ - template<> class type_caster : public type_caster_base { }; \ - }} - -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/chrono.h b/stormpy/resources/pybind11/include/pybind11/chrono.h deleted file mode 100755 index 2b37f56f1..000000000 --- a/stormpy/resources/pybind11/include/pybind11/chrono.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime - - Copyright (c) 2016 Trent Houliston and - Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include -#include -#include -#include - -// Backport the PyDateTime_DELTA functions from Python3.3 if required -#ifndef PyDateTime_DELTA_GET_DAYS -#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) -#endif -#ifndef PyDateTime_DELTA_GET_SECONDS -#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) -#endif -#ifndef PyDateTime_DELTA_GET_MICROSECONDS -#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) -#endif - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -template class duration_caster { -public: - typedef typename type::rep rep; - typedef typename type::period period; - - typedef std::chrono::duration> days; - - bool load(handle src, bool) { - using namespace std::chrono; - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - if (!src) return false; - // If invoked with datetime.delta object - if (PyDelta_Check(src.ptr())) { - value = type(duration_cast>( - days(PyDateTime_DELTA_GET_DAYS(src.ptr())) - + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) - + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr())))); - return true; - } - // If invoked with a float we assume it is seconds and convert - else if (PyFloat_Check(src.ptr())) { - value = type(duration_cast>(duration(PyFloat_AsDouble(src.ptr())))); - return true; - } - else return false; - } - - // If this is a duration just return it back - static const std::chrono::duration& get_duration(const std::chrono::duration &src) { - return src; - } - - // If this is a time_point get the time_since_epoch - template static std::chrono::duration get_duration(const std::chrono::time_point> &src) { - return src.time_since_epoch(); - } - - static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) { - using namespace std::chrono; - - // Use overloaded function to get our duration from our source - // Works out if it is a duration or time_point and get the duration - auto d = get_duration(src); - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - // Declare these special duration types so the conversions happen with the correct primitive types (int) - using dd_t = duration>; - using ss_t = duration>; - using us_t = duration; - - return PyDelta_FromDSU(duration_cast(d).count(), - duration_cast(d % days(1)).count(), - duration_cast(d % seconds(1)).count()); - } - - PYBIND11_TYPE_CASTER(type, _("datetime.timedelta")); -}; - -// This is for casting times on the system clock into datetime.datetime instances -template class type_caster> { -public: - typedef std::chrono::time_point type; - bool load(handle src, bool) { - using namespace std::chrono; - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - if (!src) return false; - if (PyDateTime_Check(src.ptr())) { - std::tm cal; - cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr()); - cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr()); - cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr()); - cal.tm_mday = PyDateTime_GET_DAY(src.ptr()); - cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1; - cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900; - cal.tm_isdst = -1; - - value = system_clock::from_time_t(std::mktime(&cal)) + microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr())); - return true; - } - else return false; - } - - static handle cast(const std::chrono::time_point &src, return_value_policy /* policy */, handle /* parent */) { - using namespace std::chrono; - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - std::time_t tt = system_clock::to_time_t(src); - // this function uses static memory so it's best to copy it out asap just in case - // otherwise other code that is using localtime may break this (not just python code) - std::tm localtime = *std::localtime(&tt); - - // Declare these special duration types so the conversions happen with the correct primitive types (int) - using us_t = duration; - - return PyDateTime_FromDateAndTime(localtime.tm_year + 1900, - localtime.tm_mon + 1, - localtime.tm_mday, - localtime.tm_hour, - localtime.tm_min, - localtime.tm_sec, - (duration_cast(src.time_since_epoch() % seconds(1))).count()); - } - PYBIND11_TYPE_CASTER(type, _("datetime.datetime")); -}; - -// Other clocks that are not the system clock are not measured as datetime.datetime objects -// since they are not measured on calendar time. So instead we just make them timedeltas -// Or if they have passed us a time as a float we convert that -template class type_caster> -: public duration_caster> { -}; - -template class type_caster> -: public duration_caster> { -}; - -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/common.h b/stormpy/resources/pybind11/include/pybind11/common.h deleted file mode 100644 index e0ebedeaf..000000000 --- a/stormpy/resources/pybind11/include/pybind11/common.h +++ /dev/null @@ -1,543 +0,0 @@ -/* - pybind11/common.h -- Basic macros - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#if !defined(NAMESPACE_BEGIN) -# define NAMESPACE_BEGIN(name) namespace name { -#endif -#if !defined(NAMESPACE_END) -# define NAMESPACE_END(name) } -#endif - -// Neither MSVC nor Intel support enough of C++14 yet (in particular, as of MSVC 2015 and ICC 17 -// beta, neither support extended constexpr, which we rely on in descr.h), so don't enable pybind -// CPP14 features for them. -#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER) -# if __cplusplus >= 201402L -# define PYBIND11_CPP14 -# if __cplusplus > 201402L /* Temporary: should be updated to >= the final C++17 value once known */ -# define PYBIND11_CPP17 -# endif -# endif -#endif - -#if !defined(PYBIND11_EXPORT) -# if defined(WIN32) || defined(_WIN32) -# define PYBIND11_EXPORT __declspec(dllexport) -# else -# define PYBIND11_EXPORT __attribute__ ((visibility("default"))) -# endif -#endif - -#if defined(_MSC_VER) -# define PYBIND11_NOINLINE __declspec(noinline) -#else -# define PYBIND11_NOINLINE __attribute__ ((noinline)) -#endif - -#if defined(PYBIND11_CPP14) -# define PYBIND11_DEPRECATED(reason) [[deprecated(reason)]] -#elif defined(__clang__) -# define PYBIND11_DEPRECATED(reason) __attribute__((deprecated(reason))) -#elif defined(__GNUG__) -# define PYBIND11_DEPRECATED(reason) __attribute__((deprecated)) -#elif defined(_MSC_VER) -# define PYBIND11_DEPRECATED(reason) __declspec(deprecated) -#endif - -#define PYBIND11_VERSION_MAJOR 1 -#define PYBIND11_VERSION_MINOR 9 -#define PYBIND11_VERSION_PATCH dev0 - -/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode -#if defined(_MSC_VER) -# define HAVE_ROUND -# pragma warning(push) -# pragma warning(disable: 4510 4610 4512 4005) -# if _DEBUG -# define PYBIND11_DEBUG_MARKER -# undef _DEBUG -# endif -#endif - -#include -#include -#include - -#if defined(_WIN32) && (defined(min) || defined(max)) -# error Macro clash with min and max -- define NOMINMAX when compiling your program on Windows -#endif - -#if defined(isalnum) -# undef isalnum -# undef isalpha -# undef islower -# undef isspace -# undef isupper -# undef tolower -# undef toupper -#endif - -#if defined(_MSC_VER) -# if defined(PYBIND11_DEBUG_MARKER) -# define _DEBUG -# undef PYBIND11_DEBUG_MARKER -# endif -# pragma warning(pop) -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions -#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr) -#define PYBIND11_BYTES_CHECK PyBytes_Check -#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString -#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize -#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize -#define PYBIND11_BYTES_AS_STRING PyBytes_AsString -#define PYBIND11_LONG_CHECK(o) PyLong_Check(o) -#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o) -#define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) PyLong_AsUnsignedLongLong(o) -#define PYBIND11_BYTES_NAME "bytes" -#define PYBIND11_STRING_NAME "str" -#define PYBIND11_SLICE_OBJECT PyObject -#define PYBIND11_FROM_STRING PyUnicode_FromString -#define PYBIND11_STR_TYPE ::pybind11::str -#define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_base.ob_base.ob_type -#define PYBIND11_PLUGIN_IMPL(name) \ - extern "C" PYBIND11_EXPORT PyObject *PyInit_##name() -#else -#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyMethod_New(ptr, nullptr, class_) -#define PYBIND11_BYTES_CHECK PyString_Check -#define PYBIND11_BYTES_FROM_STRING PyString_FromString -#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize -#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize -#define PYBIND11_BYTES_AS_STRING PyString_AsString -#define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o)) -#define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o)) -#define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) (PyInt_Check(o) ? (unsigned long long) PyLong_AsUnsignedLong(o) : PyLong_AsUnsignedLongLong(o)) -#define PYBIND11_BYTES_NAME "str" -#define PYBIND11_STRING_NAME "unicode" -#define PYBIND11_SLICE_OBJECT PySliceObject -#define PYBIND11_FROM_STRING PyString_FromString -#define PYBIND11_STR_TYPE ::pybind11::bytes -#define PYBIND11_OB_TYPE(ht_type) (ht_type).ob_type -#define PYBIND11_PLUGIN_IMPL(name) \ - extern "C" PYBIND11_EXPORT PyObject *init##name() -#endif - -#if PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03050200 -extern "C" { - struct _Py_atomic_address { void *value; }; - PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current; -} -#endif - -#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code -#define PYBIND11_STRINGIFY(x) #x -#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x) -#define PYBIND11_INTERNALS_ID "__pybind11_" \ - PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__" - -#define PYBIND11_PLUGIN(name) \ - static PyObject *pybind11_init(); \ - PYBIND11_PLUGIN_IMPL(name) { \ - int major, minor; \ - if (sscanf(Py_GetVersion(), "%i.%i", &major, &minor) != 2) { \ - PyErr_SetString(PyExc_ImportError, "Can't parse Python version."); \ - return nullptr; \ - } else if (major != PY_MAJOR_VERSION || minor != PY_MINOR_VERSION) { \ - PyErr_Format(PyExc_ImportError, \ - "Python version mismatch: module was compiled for " \ - "version %i.%i, while the interpreter is running " \ - "version %i.%i.", PY_MAJOR_VERSION, PY_MINOR_VERSION, \ - major, minor); \ - return nullptr; \ - } \ - try { \ - return pybind11_init(); \ - } catch (const std::exception &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } \ - } \ - PyObject *pybind11_init() - -NAMESPACE_BEGIN(pybind11) - -using ssize_t = Py_ssize_t; -using size_t = std::size_t; - -/// Approach used to cast a previously unknown C++ instance into a Python object -enum class return_value_policy : uint8_t { - /** This is the default return value policy, which falls back to the policy - return_value_policy::take_ownership when the return value is a pointer. - Otherwise, it uses return_value::move or return_value::copy for rvalue - and lvalue references, respectively. See below for a description of what - all of these different policies do. */ - automatic = 0, - - /** As above, but use policy return_value_policy::reference when the return - value is a pointer. This is the default conversion policy for function - arguments when calling Python functions manually from C++ code (i.e. via - handle::operator()). You probably won't need to use this. */ - automatic_reference, - - /** Reference an existing object (i.e. do not create a new copy) and take - ownership. Python will call the destructor and delete operator when the - object’s reference count reaches zero. Undefined behavior ensues when - the C++ side does the same.. */ - take_ownership, - - /** Create a new copy of the returned object, which will be owned by - Python. This policy is comparably safe because the lifetimes of the two - instances are decoupled. */ - copy, - - /** Use std::move to move the return value contents into a new instance - that will be owned by Python. This policy is comparably safe because the - lifetimes of the two instances (move source and destination) are - decoupled. */ - move, - - /** Reference an existing object, but do not take ownership. The C++ side - is responsible for managing the object’s lifetime and deallocating it - when it is no longer used. Warning: undefined behavior will ensue when - the C++ side deletes an object that is still referenced and used by - Python. */ - reference, - - /** This policy only applies to methods and properties. It references the - object without taking ownership similar to the above - return_value_policy::reference policy. In contrast to that policy, the - function or property’s implicit this argument (called the parent) is - considered to be the the owner of the return value (the child). - pybind11 then couples the lifetime of the parent to the child via a - reference relationship that ensures that the parent cannot be garbage - collected while Python is still using the child. More advanced - variations of this scheme are also possible using combinations of - return_value_policy::reference and the keep_alive call policy */ - reference_internal -}; - -/// Information record describing a Python buffer object -struct buffer_info { - void *ptr = nullptr; // Pointer to the underlying storage - size_t itemsize = 0; // Size of individual items in bytes - size_t size = 0; // Total number of entries - std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() - size_t ndim = 0; // Number of dimensions - std::vector shape; // Shape of the tensor (1 entry per dimension) - std::vector strides; // Number of entries between adjacent entries (for each per dimension) - - buffer_info() { } - - buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t ndim, - const std::vector &shape, const std::vector &strides) - : ptr(ptr), itemsize(itemsize), size(1), format(format), - ndim(ndim), shape(shape), strides(strides) { - for (size_t i = 0; i < ndim; ++i) - size *= shape[i]; - } - - buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t size) - : buffer_info(ptr, itemsize, format, 1, std::vector { size }, - std::vector { itemsize }) { } - - explicit buffer_info(Py_buffer *view, bool ownview = true) - : ptr(view->buf), itemsize((size_t) view->itemsize), size(1), format(view->format), - ndim((size_t) view->ndim), shape((size_t) view->ndim), strides((size_t) view->ndim), view(view), ownview(ownview) { - for (size_t i = 0; i < (size_t) view->ndim; ++i) { - shape[i] = (size_t) view->shape[i]; - strides[i] = (size_t) view->strides[i]; - size *= shape[i]; - } - } - - buffer_info(const buffer_info &) = delete; - buffer_info& operator=(const buffer_info &) = delete; - - buffer_info(buffer_info &&other) { - (*this) = std::move(other); - } - - buffer_info& operator=(buffer_info &&rhs) { - ptr = rhs.ptr; - itemsize = rhs.itemsize; - size = rhs.size; - format = std::move(rhs.format); - ndim = rhs.ndim; - shape = std::move(rhs.shape); - strides = std::move(rhs.strides); - std::swap(view, rhs.view); - std::swap(ownview, rhs.ownview); - return *this; - } - - ~buffer_info() { - if (view && ownview) { PyBuffer_Release(view); delete view; } - } - -private: - Py_buffer *view = nullptr; - bool ownview = false; -}; - -NAMESPACE_BEGIN(detail) - -inline static constexpr int log2(size_t n, int k = 0) { return (n <= 1) ? k : log2(n >> 1, k + 1); } - -inline std::string error_string(); - -/// Core part of the 'instance' type which POD (needed to be able to use 'offsetof') -template struct instance_essentials { - PyObject_HEAD - type *value; - PyObject *weakrefs; - bool owned : 1; - bool holder_constructed : 1; -}; - -/// PyObject wrapper around generic types, includes a special holder type that is responsible for lifetime management -template > struct instance : instance_essentials { - holder_type holder; -}; - -struct overload_hash { - inline size_t operator()(const std::pair& v) const { - size_t value = std::hash()(v.first); - value ^= std::hash()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2); - return value; - } -}; - -/// Internal data struture used to track registered instances and types -struct internals { - std::unordered_map registered_types_cpp; // std::type_index -> type_info - std::unordered_map registered_types_py; // PyTypeObject* -> type_info - std::unordered_multimap registered_instances; // void * -> PyObject* - std::unordered_set, overload_hash> inactive_overload_cache; - std::unordered_map> direct_conversions; - std::forward_list registered_exception_translators; - std::unordered_map shared_data; // Custom data to be shared across extensions -#if defined(WITH_THREAD) - decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x - PyInterpreterState *istate = nullptr; -#endif -}; - -/// Return a reference to the current 'internals' information -inline internals &get_internals(); - -/// Index sequence for convenient template metaprogramming involving tuples -template struct index_sequence { }; -template struct make_index_sequence : make_index_sequence { }; -template struct make_index_sequence <0, S...> { typedef index_sequence type; }; - -/// Strip the class from a method type -template struct remove_class { }; -template struct remove_class { typedef R type(A...); }; -template struct remove_class { typedef R type(A...); }; - -/// Helper template to strip away type modifiers -template struct intrinsic_type { typedef T type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template using intrinsic_t = typename intrinsic_type::type; - -/// Helper type to replace 'void' in some expressions -struct void_type { }; - -/// from __cpp_future__ import (convenient aliases from C++14/17) -template using bool_constant = std::integral_constant; -template using negation = bool_constant; -template using enable_if_t = typename std::enable_if::type; -template using conditional_t = typename std::conditional::type; - -/// Compile-time integer sum -constexpr size_t constexpr_sum() { return 0; } -template -constexpr size_t constexpr_sum(T n, Ts... ns) { return size_t{n} + constexpr_sum(ns...); } - -// Counts the number of types in the template parameter pack matching the predicate -#if !defined(_MSC_VER) -template class Predicate, typename... Ts> -using count_t = std::integral_constant::value...)>; -#else -// MSVC workaround (2015 Update 3 has issues with some member type aliases and constexpr) -template class Predicate, typename... Ts> struct count_t; -template class Predicate> struct count_t : std::integral_constant {}; -template class Predicate, class T, class... Ts> -struct count_t : std::integral_constant::value + count_t::value> {}; -#endif - -/// Return true if all/any Ts satify Predicate -template class Predicate, typename... Ts> -using all_of_t = bool_constant<(count_t::value == sizeof...(Ts))>; -template class Predicate, typename... Ts> -using any_of_t = bool_constant<(count_t::value > 0)>; - -// Extracts the first type from the template parameter pack matching the predicate, or Default if none match. -template class Predicate, class Default, class... Ts> struct first_of; -template class Predicate, class Default> struct first_of { - using type = Default; -}; -template class Predicate, class Default, class T, class... Ts> -struct first_of { - using type = typename std::conditional< - Predicate::value, - T, - typename first_of::type - >::type; -}; -template class Predicate, class Default, class... T> using first_of_t = typename first_of::type; - -/// Defer the evaluation of type T until types Us are instantiated -template struct deferred_type { using type = T; }; -template using deferred_t = typename deferred_type::type; - -template class Base> -struct is_template_base_of_impl { - template static std::true_type check(Base *); - static std::false_type check(...); -}; - -/// Check if a template is the base of a type. For example: -/// `is_template_base_of` is true if `struct T : Base {}` where U can be anything -template class Base, typename T> -#if !defined(_MSC_VER) -using is_template_base_of = decltype(is_template_base_of_impl::check((T*)nullptr)); -#else // MSVC2015 has trouble with decltype in template aliases -struct is_template_base_of : decltype(is_template_base_of_impl::check((T*)nullptr)) { }; -#endif - -/// Check if T is std::shared_ptr where U can be anything -template struct is_shared_ptr : std::false_type { }; -template struct is_shared_ptr> : std::true_type { }; - -/// Ignore that a variable is unused in compiler warnings -inline void ignore_unused(const int *) { } - -NAMESPACE_END(detail) - -/// Returns a named pointer that is shared among all extension modules (using the same -/// pybind11 version) running in the current interpreter. Names starting with underscores -/// are reserved for internal usage. Returns `nullptr` if no matching entry was found. -inline PYBIND11_NOINLINE void* get_shared_data(const std::string& name) { - auto& internals = detail::get_internals(); - auto it = internals.shared_data.find(name); - return it != internals.shared_data.end() ? it->second : nullptr; -} - -/// Set the shared data that can be later recovered by `get_shared_data()`. -inline PYBIND11_NOINLINE void *set_shared_data(const std::string& name, void *data) { - detail::get_internals().shared_data[name] = data; - return data; -} - -/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if -/// such entry exists. Otherwise, a new object of default-constructible type `T` is -/// added to the shared data under the given name and a reference to it is returned. -template T& get_or_create_shared_data(const std::string& name) { - auto& internals = detail::get_internals(); - auto it = internals.shared_data.find(name); - T* ptr = (T*) (it != internals.shared_data.end() ? it->second : nullptr); - if (!ptr) { - ptr = new T(); - internals.shared_data[name] = ptr; - } - return *ptr; -} - -/// Fetch and hold an error which was already set in Python -class error_already_set : public std::runtime_error { -public: - error_already_set() : std::runtime_error(detail::error_string()) { - PyErr_Fetch(&type, &value, &trace); - } - ~error_already_set() { Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(trace); } - - /// Give the error back to Python - void restore() { PyErr_Restore(type, value, trace); type = value = trace = nullptr; } - -private: - PyObject *type, *value, *trace; -}; - -/// C++ bindings of builtin Python exceptions -class builtin_exception : public std::runtime_error { -public: - using std::runtime_error::runtime_error; - virtual void set_error() const = 0; /// Set the error using the Python C API -}; - -#define PYBIND11_RUNTIME_EXCEPTION(name, type) \ - class name : public builtin_exception { public: \ - using builtin_exception::builtin_exception; \ - name() : name("") { } \ - void set_error() const override { PyErr_SetString(type, what()); } \ - }; - -PYBIND11_RUNTIME_EXCEPTION(stop_iteration, PyExc_StopIteration) -PYBIND11_RUNTIME_EXCEPTION(index_error, PyExc_IndexError) -PYBIND11_RUNTIME_EXCEPTION(key_error, PyExc_KeyError) -PYBIND11_RUNTIME_EXCEPTION(value_error, PyExc_ValueError) -PYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError) -PYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError) -PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or handle::call fail due to a type casting error -PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally - -[[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } -[[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } - -/// Format strings for basic number types -#define PYBIND11_DECL_FMT(t, v) template<> struct format_descriptor \ - { static constexpr const char* value = v; /* for backwards compatibility */ \ - static std::string format() { return value; } } - -template struct format_descriptor { }; - -template struct format_descriptor::value>> { - static constexpr const char c = "bBhHiIqQ"[detail::log2(sizeof(T))*2 + std::is_unsigned::value]; - static constexpr const char value[2] = { c, '\0' }; - static std::string format() { return std::string(1, c); } -}; - -template constexpr const char format_descriptor< - T, detail::enable_if_t::value>>::value[2]; - -/// RAII wrapper that temporarily clears any Python error state -struct error_scope { - PyObject *type, *value, *trace; - error_scope() { PyErr_Fetch(&type, &value, &trace); } - ~error_scope() { PyErr_Restore(type, value, trace); } -}; - -PYBIND11_DECL_FMT(float, "f"); -PYBIND11_DECL_FMT(double, "d"); -PYBIND11_DECL_FMT(bool, "?"); - -/// Dummy destructor wrapper that can be used to expose classes with a private destructor -struct nodelete { template void operator()(T*) { } }; - -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/complex.h b/stormpy/resources/pybind11/include/pybind11/complex.h deleted file mode 100644 index f767f354c..000000000 --- a/stormpy/resources/pybind11/include/pybind11/complex.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - pybind11/complex.h: Complex number support - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include - -/// glibc defines I as a macro which breaks things, e.g., boost template names -#ifdef I -# undef I -#endif - -NAMESPACE_BEGIN(pybind11) - -PYBIND11_DECL_FMT(std::complex, "Zf"); -PYBIND11_DECL_FMT(std::complex, "Zd"); - -NAMESPACE_BEGIN(detail) -template class type_caster> { -public: - bool load(handle src, bool) { - if (!src) - return false; - Py_complex result = PyComplex_AsCComplex(src.ptr()); - if (result.real == -1.0 && PyErr_Occurred()) { - PyErr_Clear(); - return false; - } - value = std::complex((T) result.real, (T) result.imag); - return true; - } - - static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) { - return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); - } - - PYBIND11_TYPE_CASTER(std::complex, _("complex")); -}; -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/descr.h b/stormpy/resources/pybind11/include/pybind11/descr.h deleted file mode 100644 index a9a1f67aa..000000000 --- a/stormpy/resources/pybind11/include/pybind11/descr.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - pybind11/descr.h: Helper type for concatenating type signatures - either at runtime (C++11) or compile time (C++14) - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "common.h" - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -#if defined(PYBIND11_CPP14) /* Concatenate type signatures at compile time using C++14 */ - -template class descr { - template friend class descr; -public: - constexpr descr(char const (&text) [Size1+1], const std::type_info * const (&types)[Size2+1]) - : descr(text, types, - typename make_index_sequence::type(), - typename make_index_sequence::type()) { } - - constexpr const char *text() const { return m_text; } - constexpr const std::type_info * const * types() const { return m_types; } - - template - constexpr descr operator+(const descr &other) const { - return concat(other, - typename make_index_sequence::type(), - typename make_index_sequence::type(), - typename make_index_sequence::type(), - typename make_index_sequence::type()); - } - -protected: - template - constexpr descr( - char const (&text) [Size1+1], - const std::type_info * const (&types) [Size2+1], - index_sequence, index_sequence) - : m_text{text[Indices1]..., '\0'}, - m_types{types[Indices2]..., nullptr } {} - - template - constexpr descr - concat(const descr &other, - index_sequence, index_sequence, - index_sequence, index_sequence) const { - return descr( - { m_text[Indices1]..., other.m_text[OtherIndices1]..., '\0' }, - { m_types[Indices2]..., other.m_types[OtherIndices2]..., nullptr } - ); - } - -protected: - char m_text[Size1 + 1]; - const std::type_info * m_types[Size2 + 1]; -}; - -template constexpr descr _(char const(&text)[Size]) { - return descr(text, { nullptr }); -} - -template struct int_to_str : int_to_str { }; -template struct int_to_str<0, Digits...> { - static constexpr auto digits = descr({ ('0' + Digits)..., '\0' }, { nullptr }); -}; - -// Ternary description (like std::conditional) -template -constexpr enable_if_t> _(char const(&text1)[Size1], char const(&)[Size2]) { - return _(text1); -} -template -constexpr enable_if_t> _(char const(&)[Size1], char const(&text2)[Size2]) { - return _(text2); -} - -template auto constexpr _() -> decltype(int_to_str::digits) { - return int_to_str::digits; -} - -template constexpr descr<1, 1> _() { - return descr<1, 1>({ '%', '\0' }, { &typeid(Type), nullptr }); -} - -inline constexpr descr<0, 0> concat() { return _(""); } -template auto constexpr concat(descr descr) { return descr; } -template auto constexpr concat(descr descr, Args&&... args) { return descr + _(", ") + concat(args...); } -template auto constexpr type_descr(descr descr) { return _("{") + descr + _("}"); } - -#define PYBIND11_DESCR constexpr auto - -#else /* Simpler C++11 implementation based on run-time memory allocation and copying */ - -class descr { -public: - PYBIND11_NOINLINE descr(const char *text, const std::type_info * const * types) { - size_t nChars = len(text), nTypes = len(types); - m_text = new char[nChars]; - m_types = new const std::type_info *[nTypes]; - memcpy(m_text, text, nChars * sizeof(char)); - memcpy(m_types, types, nTypes * sizeof(const std::type_info *)); - } - - PYBIND11_NOINLINE descr friend operator+(descr &&d1, descr &&d2) { - descr r; - - size_t nChars1 = len(d1.m_text), nTypes1 = len(d1.m_types); - size_t nChars2 = len(d2.m_text), nTypes2 = len(d2.m_types); - - r.m_text = new char[nChars1 + nChars2 - 1]; - r.m_types = new const std::type_info *[nTypes1 + nTypes2 - 1]; - memcpy(r.m_text, d1.m_text, (nChars1-1) * sizeof(char)); - memcpy(r.m_text + nChars1 - 1, d2.m_text, nChars2 * sizeof(char)); - memcpy(r.m_types, d1.m_types, (nTypes1-1) * sizeof(std::type_info *)); - memcpy(r.m_types + nTypes1 - 1, d2.m_types, nTypes2 * sizeof(std::type_info *)); - - delete[] d1.m_text; delete[] d1.m_types; - delete[] d2.m_text; delete[] d2.m_types; - - return r; - } - - char *text() { return m_text; } - const std::type_info * * types() { return m_types; } - -protected: - PYBIND11_NOINLINE descr() { } - - template static size_t len(const T *ptr) { // return length including null termination - const T *it = ptr; - while (*it++ != (T) 0) - ; - return static_cast(it - ptr); - } - - const std::type_info **m_types = nullptr; - char *m_text = nullptr; -}; - -/* The 'PYBIND11_NOINLINE inline' combinations below are intentional to get the desired linkage while producing as little object code as possible */ - -PYBIND11_NOINLINE inline descr _(const char *text) { - const std::type_info *types[1] = { nullptr }; - return descr(text, types); -} - -template PYBIND11_NOINLINE enable_if_t _(const char *text1, const char *) { return _(text1); } -template PYBIND11_NOINLINE enable_if_t _(char const *, const char *text2) { return _(text2); } - -template PYBIND11_NOINLINE descr _() { - const std::type_info *types[2] = { &typeid(Type), nullptr }; - return descr("%", types); -} - -template PYBIND11_NOINLINE descr _() { - const std::type_info *types[1] = { nullptr }; - return descr(std::to_string(Size).c_str(), types); -} - -PYBIND11_NOINLINE inline descr concat() { return _(""); } -PYBIND11_NOINLINE inline descr concat(descr &&d) { return d; } -template PYBIND11_NOINLINE descr concat(descr &&d, Args&&... args) { return std::move(d) + _(", ") + concat(std::forward(args)...); } -PYBIND11_NOINLINE inline descr type_descr(descr&& d) { return _("{") + std::move(d) + _("}"); } - -#define PYBIND11_DESCR ::pybind11::detail::descr -#endif - -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/eigen.h b/stormpy/resources/pybind11/include/pybind11/eigen.h deleted file mode 100644 index 0a1208e16..000000000 --- a/stormpy/resources/pybind11/include/pybind11/eigen.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "numpy.h" - -#if defined(__INTEL_COMPILER) -# pragma warning(disable: 1682) // implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) -#elif defined(__GNUG__) || defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wconversion" -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -#include -#include - -#if defined(__GNUG__) || defined(__clang__) -# pragma GCC diagnostic pop -#endif - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -#endif - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -template using is_eigen_dense = is_template_base_of; -template using is_eigen_sparse = is_template_base_of; -template using is_eigen_ref = is_template_base_of; - -// Test for objects inheriting from EigenBase that aren't captured by the above. This -// basically covers anything that can be assigned to a dense matrix but that don't have a typical -// matrix data layout that can be copied from their .data(). For example, DiagonalMatrix and -// SelfAdjointView fall into this category. -template using is_eigen_base = bool_constant< - is_template_base_of::value - && !is_eigen_dense::value && !is_eigen_sparse::value ->; - -template -struct type_caster::value && !is_eigen_ref::value>> { - typedef typename Type::Scalar Scalar; - static constexpr bool rowMajor = Type::Flags & Eigen::RowMajorBit; - static constexpr bool isVector = Type::IsVectorAtCompileTime; - - bool load(handle src, bool) { - auto buf = array_t::ensure(src); - if (!buf) - return false; - - if (buf.ndim() == 1) { - typedef Eigen::InnerStride<> Strides; - if (!isVector && - !(Type::RowsAtCompileTime == Eigen::Dynamic && - Type::ColsAtCompileTime == Eigen::Dynamic)) - return false; - - if (Type::SizeAtCompileTime != Eigen::Dynamic && - buf.shape(0) != (size_t) Type::SizeAtCompileTime) - return false; - - Strides::Index n_elts = (Strides::Index) buf.shape(0); - Strides::Index unity = 1; - - value = Eigen::Map( - buf.mutable_data(), - rowMajor ? unity : n_elts, - rowMajor ? n_elts : unity, - Strides(buf.strides(0) / sizeof(Scalar)) - ); - } else if (buf.ndim() == 2) { - typedef Eigen::Stride Strides; - - if ((Type::RowsAtCompileTime != Eigen::Dynamic && buf.shape(0) != (size_t) Type::RowsAtCompileTime) || - (Type::ColsAtCompileTime != Eigen::Dynamic && buf.shape(1) != (size_t) Type::ColsAtCompileTime)) - return false; - - value = Eigen::Map( - buf.mutable_data(), - typename Strides::Index(buf.shape(0)), - typename Strides::Index(buf.shape(1)), - Strides(buf.strides(rowMajor ? 0 : 1) / sizeof(Scalar), - buf.strides(rowMajor ? 1 : 0) / sizeof(Scalar)) - ); - } else { - return false; - } - return true; - } - - static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { - if (isVector) { - return array( - { (size_t) src.size() }, // shape - { sizeof(Scalar) * static_cast(src.innerStride()) }, // strides - src.data() // data - ).release(); - } else { - return array( - { (size_t) src.rows(), // shape - (size_t) src.cols() }, - { sizeof(Scalar) * static_cast(src.rowStride()), // strides - sizeof(Scalar) * static_cast(src.colStride()) }, - src.data() // data - ).release(); - } - } - - PYBIND11_TYPE_CASTER(Type, _("numpy.ndarray[") + npy_format_descriptor::name() + - _("[") + rows() + _(", ") + cols() + _("]]")); - -protected: - template = 0> - static PYBIND11_DESCR rows() { return _("m"); } - template = 0> - static PYBIND11_DESCR rows() { return _(); } - template = 0> - static PYBIND11_DESCR cols() { return _("n"); } - template = 0> - static PYBIND11_DESCR cols() { return _(); } -}; - -// Eigen::Ref satisfies is_eigen_dense, but isn't constructable, so it needs a special -// type_caster to handle argument copying/forwarding. -template -struct type_caster> { -protected: - using Type = Eigen::Ref; - using Derived = typename std::remove_const::type; - using DerivedCaster = type_caster; - DerivedCaster derived_caster; - std::unique_ptr value; -public: - bool load(handle src, bool convert) { if (derived_caster.load(src, convert)) { value.reset(new Type(derived_caster.operator Derived&())); return true; } return false; } - static handle cast(const Type &src, return_value_policy policy, handle parent) { return DerivedCaster::cast(src, policy, parent); } - static handle cast(const Type *src, return_value_policy policy, handle parent) { return DerivedCaster::cast(*src, policy, parent); } - - static PYBIND11_DESCR name() { return DerivedCaster::name(); } - - operator Type*() { return value.get(); } - operator Type&() { if (!value) pybind11_fail("Eigen::Ref<...> value not loaded"); return *value; } - template using cast_op_type = pybind11::detail::cast_op_type<_T>; -}; - -// type_caster for special matrix types (e.g. DiagonalMatrix): load() is not supported, but we can -// cast them into the python domain by first copying to a regular Eigen::Matrix, then casting that. -template -struct type_caster::value && !is_eigen_ref::value>> { -protected: - using Matrix = Eigen::Matrix; - using MatrixCaster = type_caster; -public: - [[noreturn]] bool load(handle, bool) { pybind11_fail("Unable to load() into specialized EigenBase object"); } - static handle cast(const Type &src, return_value_policy policy, handle parent) { return MatrixCaster::cast(Matrix(src), policy, parent); } - static handle cast(const Type *src, return_value_policy policy, handle parent) { return MatrixCaster::cast(Matrix(*src), policy, parent); } - - static PYBIND11_DESCR name() { return MatrixCaster::name(); } - - [[noreturn]] operator Type*() { pybind11_fail("Loading not supported for specialized EigenBase object"); } - [[noreturn]] operator Type&() { pybind11_fail("Loading not supported for specialized EigenBase object"); } - template using cast_op_type = pybind11::detail::cast_op_type<_T>; -}; - -template -struct type_caster::value>> { - typedef typename Type::Scalar Scalar; - typedef typename std::remove_reference().outerIndexPtr())>::type StorageIndex; - typedef typename Type::Index Index; - static constexpr bool rowMajor = Type::Flags & Eigen::RowMajorBit; - - bool load(handle src, bool) { - if (!src) - return false; - - auto obj = reinterpret_borrow(src); - object sparse_module = module::import("scipy.sparse"); - object matrix_type = sparse_module.attr( - rowMajor ? "csr_matrix" : "csc_matrix"); - - if (obj.get_type() != matrix_type.ptr()) { - try { - obj = matrix_type(obj); - } catch (const error_already_set &) { - return false; - } - } - - auto values = array_t((object) obj.attr("data")); - auto innerIndices = array_t((object) obj.attr("indices")); - auto outerIndices = array_t((object) obj.attr("indptr")); - auto shape = pybind11::tuple((pybind11::object) obj.attr("shape")); - auto nnz = obj.attr("nnz").cast(); - - if (!values || !innerIndices || !outerIndices) - return false; - - value = Eigen::MappedSparseMatrix( - shape[0].cast(), shape[1].cast(), nnz, - outerIndices.mutable_data(), innerIndices.mutable_data(), values.mutable_data()); - - return true; - } - - static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { - const_cast(src).makeCompressed(); - - object matrix_type = module::import("scipy.sparse").attr( - rowMajor ? "csr_matrix" : "csc_matrix"); - - array data((size_t) src.nonZeros(), src.valuePtr()); - array outerIndices((size_t) (rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr()); - array innerIndices((size_t) src.nonZeros(), src.innerIndexPtr()); - - return matrix_type( - std::make_tuple(data, innerIndices, outerIndices), - std::make_pair(src.rows(), src.cols()) - ).release(); - } - - PYBIND11_TYPE_CASTER(Type, _<(Type::Flags & Eigen::RowMajorBit) != 0>("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[") - + npy_format_descriptor::name() + _("]")); -}; - -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif diff --git a/stormpy/resources/pybind11/include/pybind11/eval.h b/stormpy/resources/pybind11/include/pybind11/eval.h deleted file mode 100755 index 204427d77..000000000 --- a/stormpy/resources/pybind11/include/pybind11/eval.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - pybind11/exec.h: Support for evaluating Python expressions and statements - from strings and files - - Copyright (c) 2016 Klemens Morgenstern and - Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#pragma once - -#include "pybind11.h" - -NAMESPACE_BEGIN(pybind11) - -enum eval_mode { - /// Evaluate a string containing an isolated expression - eval_expr, - - /// Evaluate a string containing a single statement. Returns \c none - eval_single_statement, - - /// Evaluate a string containing a sequence of statement. Returns \c none - eval_statements -}; - -template -object eval(str expr, object global = object(), object local = object()) { - if (!global) { - global = reinterpret_borrow(PyEval_GetGlobals()); - if (!global) - global = dict(); - } - if (!local) - local = global; - - /* PyRun_String does not accept a PyObject / encoding specifier, - this seems to be the only alternative */ - std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; - - int start; - switch (mode) { - case eval_expr: start = Py_eval_input; break; - case eval_single_statement: start = Py_single_input; break; - case eval_statements: start = Py_file_input; break; - default: pybind11_fail("invalid evaluation mode"); - } - - PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); - if (!result) - throw error_already_set(); - return reinterpret_steal(result); -} - -template -object eval_file(str fname, object global = object(), object local = object()) { - if (!global) { - global = reinterpret_borrow(PyEval_GetGlobals()); - if (!global) - global = dict(); - } - if (!local) - local = global; - - int start; - switch (mode) { - case eval_expr: start = Py_eval_input; break; - case eval_single_statement: start = Py_single_input; break; - case eval_statements: start = Py_file_input; break; - default: pybind11_fail("invalid evaluation mode"); - } - - int closeFile = 1; - std::string fname_str = (std::string) fname; -#if PY_VERSION_HEX >= 0x03040000 - FILE *f = _Py_fopen_obj(fname.ptr(), "r"); -#elif PY_VERSION_HEX >= 0x03000000 - FILE *f = _Py_fopen(fname.ptr(), "r"); -#else - /* No unicode support in open() :( */ - auto fobj = reinterpret_steal(PyFile_FromString( - const_cast(fname_str.c_str()), - const_cast("r"))); - FILE *f = nullptr; - if (fobj) - f = PyFile_AsFile(fobj.ptr()); - closeFile = 0; -#endif - if (!f) { - PyErr_Clear(); - pybind11_fail("File \"" + fname_str + "\" could not be opened!"); - } - - PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), - local.ptr(), closeFile); - if (!result) - throw error_already_set(); - return reinterpret_steal(result); -} - -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/functional.h b/stormpy/resources/pybind11/include/pybind11/functional.h deleted file mode 100644 index dbeea5dc7..000000000 --- a/stormpy/resources/pybind11/include/pybind11/functional.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - pybind11/functional.h: std::function<> support - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -template struct type_caster> { - typedef std::function type; - typedef typename std::conditional::value, void_type, Return>::type retval_type; -public: - bool load(handle src_, bool) { - if (src_.is_none()) - return true; - - src_ = detail::get_function(src_); - if (!src_ || !PyCallable_Check(src_.ptr())) - return false; - - /* - When passing a C++ function as an argument to another C++ - function via Python, every function call would normally involve - a full C++ -> Python -> C++ roundtrip, which can be prohibitive. - Here, we try to at least detect the case where the function is - stateless (i.e. function pointer or lambda function without - captured variables), in which case the roundtrip can be avoided. - */ - if (PyCFunction_Check(src_.ptr())) { - auto c = reinterpret_borrow(PyCFunction_GetSelf(src_.ptr())); - auto rec = (function_record *) c; - using FunctionType = Return (*) (Args...); - - if (rec && rec->is_stateless && rec->data[1] == &typeid(FunctionType)) { - struct capture { FunctionType f; }; - value = ((capture *) &rec->data)->f; - return true; - } - } - - auto src = reinterpret_borrow(src_); - value = [src](Args... args) -> Return { - gil_scoped_acquire acq; - object retval(src(std::move(args)...)); - /* Visual studio 2015 parser issue: need parentheses around this expression */ - return (retval.template cast()); - }; - return true; - } - - template - static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { - if (!f_) - return none().inc_ref(); - - auto result = f_.template target(); - if (result) - return cpp_function(*result, policy).release(); - else - return cpp_function(std::forward(f_), policy).release(); - } - - PYBIND11_TYPE_CASTER(type, _("Callable[[") + - type_caster>::element_names() + _("], ") + - type_caster::name() + - _("]")); -}; - -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/numpy.h b/stormpy/resources/pybind11/include/pybind11/numpy.h deleted file mode 100644 index 8950cb7cd..000000000 --- a/stormpy/resources/pybind11/include/pybind11/numpy.h +++ /dev/null @@ -1,1169 +0,0 @@ -/* - pybind11/numpy.h: Basic NumPy support, vectorize() wrapper - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include "complex.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -#endif - -/* This will be true on all flat address space platforms and allows us to reduce the - whole npy_intp / size_t / Py_intptr_t business down to just size_t for all size - and dimension types (e.g. shape, strides, indexing), instead of inflicting this - upon the library user. */ -static_assert(sizeof(size_t) == sizeof(Py_intptr_t), "size_t != Py_intptr_t"); - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) -template struct npy_format_descriptor { }; -template struct is_pod_struct; - -struct PyArrayDescr_Proxy { - PyObject_HEAD - PyObject *typeobj; - char kind; - char type; - char byteorder; - char flags; - int type_num; - int elsize; - int alignment; - char *subarray; - PyObject *fields; - PyObject *names; -}; - -struct PyArray_Proxy { - PyObject_HEAD - char *data; - int nd; - ssize_t *dimensions; - ssize_t *strides; - PyObject *base; - PyObject *descr; - int flags; -}; - -struct PyVoidScalarObject_Proxy { - PyObject_VAR_HEAD - char *obval; - PyArrayDescr_Proxy *descr; - int flags; - PyObject *base; -}; - -struct numpy_type_info { - PyObject* dtype_ptr; - std::string format_str; -}; - -struct numpy_internals { - std::unordered_map registered_dtypes; - - numpy_type_info *get_type_info(const std::type_info& tinfo, bool throw_if_missing = true) { - auto it = registered_dtypes.find(std::type_index(tinfo)); - if (it != registered_dtypes.end()) - return &(it->second); - if (throw_if_missing) - pybind11_fail(std::string("NumPy type info missing for ") + tinfo.name()); - return nullptr; - } - - template numpy_type_info *get_type_info(bool throw_if_missing = true) { - return get_type_info(typeid(typename std::remove_cv::type), throw_if_missing); - } -}; - -inline PYBIND11_NOINLINE void load_numpy_internals(numpy_internals* &ptr) { - ptr = &get_or_create_shared_data("_numpy_internals"); -} - -inline numpy_internals& get_numpy_internals() { - static numpy_internals* ptr = nullptr; - if (!ptr) - load_numpy_internals(ptr); - return *ptr; -} - -struct npy_api { - enum constants { - NPY_C_CONTIGUOUS_ = 0x0001, - NPY_F_CONTIGUOUS_ = 0x0002, - NPY_ARRAY_OWNDATA_ = 0x0004, - NPY_ARRAY_FORCECAST_ = 0x0010, - NPY_ENSURE_ARRAY_ = 0x0040, - NPY_ARRAY_ALIGNED_ = 0x0100, - NPY_ARRAY_WRITEABLE_ = 0x0400, - NPY_BOOL_ = 0, - NPY_BYTE_, NPY_UBYTE_, - NPY_SHORT_, NPY_USHORT_, - NPY_INT_, NPY_UINT_, - NPY_LONG_, NPY_ULONG_, - NPY_LONGLONG_, NPY_ULONGLONG_, - NPY_FLOAT_, NPY_DOUBLE_, NPY_LONGDOUBLE_, - NPY_CFLOAT_, NPY_CDOUBLE_, NPY_CLONGDOUBLE_, - NPY_OBJECT_ = 17, - NPY_STRING_, NPY_UNICODE_, NPY_VOID_ - }; - - static npy_api& get() { - static npy_api api = lookup(); - return api; - } - - bool PyArray_Check_(PyObject *obj) const { - return (bool) PyObject_TypeCheck(obj, PyArray_Type_); - } - bool PyArrayDescr_Check_(PyObject *obj) const { - return (bool) PyObject_TypeCheck(obj, PyArrayDescr_Type_); - } - - PyObject *(*PyArray_DescrFromType_)(int); - PyObject *(*PyArray_NewFromDescr_) - (PyTypeObject *, PyObject *, int, Py_intptr_t *, - Py_intptr_t *, void *, int, PyObject *); - PyObject *(*PyArray_DescrNewFromType_)(int); - PyObject *(*PyArray_NewCopy_)(PyObject *, int); - PyTypeObject *PyArray_Type_; - PyTypeObject *PyVoidArrType_Type_; - PyTypeObject *PyArrayDescr_Type_; - PyObject *(*PyArray_DescrFromScalar_)(PyObject *); - PyObject *(*PyArray_FromAny_) (PyObject *, PyObject *, int, int, int, PyObject *); - int (*PyArray_DescrConverter_) (PyObject *, PyObject **); - bool (*PyArray_EquivTypes_) (PyObject *, PyObject *); - int (*PyArray_GetArrayParamsFromObject_)(PyObject *, PyObject *, char, PyObject **, int *, - Py_ssize_t *, PyObject **, PyObject *); - PyObject *(*PyArray_Squeeze_)(PyObject *); -private: - enum functions { - API_PyArray_Type = 2, - API_PyArrayDescr_Type = 3, - API_PyVoidArrType_Type = 39, - API_PyArray_DescrFromType = 45, - API_PyArray_DescrFromScalar = 57, - API_PyArray_FromAny = 69, - API_PyArray_NewCopy = 85, - API_PyArray_NewFromDescr = 94, - API_PyArray_DescrNewFromType = 9, - API_PyArray_DescrConverter = 174, - API_PyArray_EquivTypes = 182, - API_PyArray_GetArrayParamsFromObject = 278, - API_PyArray_Squeeze = 136 - }; - - static npy_api lookup() { - module m = module::import("numpy.core.multiarray"); - auto c = m.attr("_ARRAY_API"); -#if PY_MAJOR_VERSION >= 3 - void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL); -#else - void **api_ptr = (void **) PyCObject_AsVoidPtr(c.ptr()); -#endif - npy_api api; -#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func]; - DECL_NPY_API(PyArray_Type); - DECL_NPY_API(PyVoidArrType_Type); - DECL_NPY_API(PyArrayDescr_Type); - DECL_NPY_API(PyArray_DescrFromType); - DECL_NPY_API(PyArray_DescrFromScalar); - DECL_NPY_API(PyArray_FromAny); - DECL_NPY_API(PyArray_NewCopy); - DECL_NPY_API(PyArray_NewFromDescr); - DECL_NPY_API(PyArray_DescrNewFromType); - DECL_NPY_API(PyArray_DescrConverter); - DECL_NPY_API(PyArray_EquivTypes); - DECL_NPY_API(PyArray_GetArrayParamsFromObject); - DECL_NPY_API(PyArray_Squeeze); -#undef DECL_NPY_API - return api; - } -}; - -inline PyArray_Proxy* array_proxy(void* ptr) { - return reinterpret_cast(ptr); -} - -inline const PyArray_Proxy* array_proxy(const void* ptr) { - return reinterpret_cast(ptr); -} - -inline PyArrayDescr_Proxy* array_descriptor_proxy(PyObject* ptr) { - return reinterpret_cast(ptr); -} - -inline const PyArrayDescr_Proxy* array_descriptor_proxy(const PyObject* ptr) { - return reinterpret_cast(ptr); -} - -inline bool check_flags(const void* ptr, int flag) { - return (flag == (array_proxy(ptr)->flags & flag)); -} - -NAMESPACE_END(detail) - -class dtype : public object { -public: - PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_); - - explicit dtype(const buffer_info &info) { - dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format))); - // If info.itemsize == 0, use the value calculated from the format string - m_ptr = descr.strip_padding(info.itemsize ? info.itemsize : descr.itemsize()).release().ptr(); - } - - explicit dtype(const std::string &format) { - m_ptr = from_args(pybind11::str(format)).release().ptr(); - } - - dtype(const char *format) : dtype(std::string(format)) { } - - dtype(list names, list formats, list offsets, size_t itemsize) { - dict args; - args["names"] = names; - args["formats"] = formats; - args["offsets"] = offsets; - args["itemsize"] = pybind11::int_(itemsize); - m_ptr = from_args(args).release().ptr(); - } - - /// This is essentially the same as calling numpy.dtype(args) in Python. - static dtype from_args(object args) { - PyObject *ptr = nullptr; - if (!detail::npy_api::get().PyArray_DescrConverter_(args.release().ptr(), &ptr) || !ptr) - throw error_already_set(); - return reinterpret_steal(ptr); - } - - /// Return dtype associated with a C++ type. - template static dtype of() { - return detail::npy_format_descriptor::type>::dtype(); - } - - /// Size of the data type in bytes. - size_t itemsize() const { - return (size_t) detail::array_descriptor_proxy(m_ptr)->elsize; - } - - /// Returns true for structured data types. - bool has_fields() const { - return detail::array_descriptor_proxy(m_ptr)->names != nullptr; - } - - /// Single-character type code. - char kind() const { - return detail::array_descriptor_proxy(m_ptr)->kind; - } - -private: - static object _dtype_from_pep3118() { - static PyObject *obj = module::import("numpy.core._internal") - .attr("_dtype_from_pep3118").cast().release().ptr(); - return reinterpret_borrow(obj); - } - - dtype strip_padding(size_t itemsize) { - // Recursively strip all void fields with empty names that are generated for - // padding fields (as of NumPy v1.11). - if (!has_fields()) - return *this; - - struct field_descr { PYBIND11_STR_TYPE name; object format; pybind11::int_ offset; }; - std::vector field_descriptors; - - for (auto field : attr("fields").attr("items")()) { - auto spec = field.cast(); - auto name = spec[0].cast(); - auto format = spec[1].cast()[0].cast(); - auto offset = spec[1].cast()[1].cast(); - if (!len(name) && format.kind() == 'V') - continue; - field_descriptors.push_back({(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset}); - } - - std::sort(field_descriptors.begin(), field_descriptors.end(), - [](const field_descr& a, const field_descr& b) { - return a.offset.cast() < b.offset.cast(); - }); - - list names, formats, offsets; - for (auto& descr : field_descriptors) { - names.append(descr.name); - formats.append(descr.format); - offsets.append(descr.offset); - } - return dtype(names, formats, offsets, itemsize); - } -}; - -class array : public buffer { -public: - PYBIND11_OBJECT_CVT(array, buffer, detail::npy_api::get().PyArray_Check_, raw_array) - - enum { - c_style = detail::npy_api::NPY_C_CONTIGUOUS_, - f_style = detail::npy_api::NPY_F_CONTIGUOUS_, - forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_ - }; - - array() : array(0, static_cast(nullptr)) {} - - array(const pybind11::dtype &dt, const std::vector &shape, - const std::vector &strides, const void *ptr = nullptr, - handle base = handle()) { - auto& api = detail::npy_api::get(); - auto ndim = shape.size(); - if (shape.size() != strides.size()) - pybind11_fail("NumPy: shape ndim doesn't match strides ndim"); - auto descr = dt; - - int flags = 0; - if (base && ptr) { - if (isinstance(base)) - /* Copy flags from base (except baseship bit) */ - flags = reinterpret_borrow(base).flags() & ~detail::npy_api::NPY_ARRAY_OWNDATA_; - else - /* Writable by default, easy to downgrade later on if needed */ - flags = detail::npy_api::NPY_ARRAY_WRITEABLE_; - } - - auto tmp = reinterpret_steal(api.PyArray_NewFromDescr_( - api.PyArray_Type_, descr.release().ptr(), (int) ndim, (Py_intptr_t *) shape.data(), - (Py_intptr_t *) strides.data(), const_cast(ptr), flags, nullptr)); - if (!tmp) - pybind11_fail("NumPy: unable to create array!"); - if (ptr) { - if (base) { - detail::array_proxy(tmp.ptr())->base = base.inc_ref().ptr(); - } else { - tmp = reinterpret_steal(api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */)); - } - } - m_ptr = tmp.release().ptr(); - } - - array(const pybind11::dtype &dt, const std::vector &shape, - const void *ptr = nullptr, handle base = handle()) - : array(dt, shape, default_strides(shape, dt.itemsize()), ptr, base) { } - - array(const pybind11::dtype &dt, size_t count, const void *ptr = nullptr, - handle base = handle()) - : array(dt, std::vector{ count }, ptr, base) { } - - template array(const std::vector& shape, - const std::vector& strides, - const T* ptr, handle base = handle()) - : array(pybind11::dtype::of(), shape, strides, (void *) ptr, base) { } - - template - array(const std::vector &shape, const T *ptr, - handle base = handle()) - : array(shape, default_strides(shape, sizeof(T)), ptr, base) { } - - template - array(size_t count, const T *ptr, handle base = handle()) - : array(std::vector{ count }, ptr, base) { } - - explicit array(const buffer_info &info) - : array(pybind11::dtype(info), info.shape, info.strides, info.ptr) { } - - /// Array descriptor (dtype) - pybind11::dtype dtype() const { - return reinterpret_borrow(detail::array_proxy(m_ptr)->descr); - } - - /// Total number of elements - size_t size() const { - return std::accumulate(shape(), shape() + ndim(), (size_t) 1, std::multiplies()); - } - - /// Byte size of a single element - size_t itemsize() const { - return (size_t) detail::array_descriptor_proxy(detail::array_proxy(m_ptr)->descr)->elsize; - } - - /// Total number of bytes - size_t nbytes() const { - return size() * itemsize(); - } - - /// Number of dimensions - size_t ndim() const { - return (size_t) detail::array_proxy(m_ptr)->nd; - } - - /// Base object - object base() const { - return reinterpret_borrow(detail::array_proxy(m_ptr)->base); - } - - /// Dimensions of the array - const size_t* shape() const { - return reinterpret_cast(detail::array_proxy(m_ptr)->dimensions); - } - - /// Dimension along a given axis - size_t shape(size_t dim) const { - if (dim >= ndim()) - fail_dim_check(dim, "invalid axis"); - return shape()[dim]; - } - - /// Strides of the array - const size_t* strides() const { - return reinterpret_cast(detail::array_proxy(m_ptr)->strides); - } - - /// Stride along a given axis - size_t strides(size_t dim) const { - if (dim >= ndim()) - fail_dim_check(dim, "invalid axis"); - return strides()[dim]; - } - - /// Return the NumPy array flags - int flags() const { - return detail::array_proxy(m_ptr)->flags; - } - - /// If set, the array is writeable (otherwise the buffer is read-only) - bool writeable() const { - return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_WRITEABLE_); - } - - /// If set, the array owns the data (will be freed when the array is deleted) - bool owndata() const { - return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_OWNDATA_); - } - - /// Pointer to the contained data. If index is not provided, points to the - /// beginning of the buffer. May throw if the index would lead to out of bounds access. - template const void* data(Ix... index) const { - return static_cast(detail::array_proxy(m_ptr)->data + offset_at(index...)); - } - - /// Mutable pointer to the contained data. If index is not provided, points to the - /// beginning of the buffer. May throw if the index would lead to out of bounds access. - /// May throw if the array is not writeable. - template void* mutable_data(Ix... index) { - check_writeable(); - return static_cast(detail::array_proxy(m_ptr)->data + offset_at(index...)); - } - - /// Byte offset from beginning of the array to a given index (full or partial). - /// May throw if the index would lead to out of bounds access. - template size_t offset_at(Ix... index) const { - if (sizeof...(index) > ndim()) - fail_dim_check(sizeof...(index), "too many indices for an array"); - return byte_offset(size_t(index)...); - } - - size_t offset_at() const { return 0; } - - /// Item count from beginning of the array to a given index (full or partial). - /// May throw if the index would lead to out of bounds access. - template size_t index_at(Ix... index) const { - return offset_at(index...) / itemsize(); - } - - /// Return a new view with all of the dimensions of length 1 removed - array squeeze() { - auto& api = detail::npy_api::get(); - return reinterpret_steal(api.PyArray_Squeeze_(m_ptr)); - } - - /// Ensure that the argument is a NumPy array - /// In case of an error, nullptr is returned and the Python error is cleared. - static array ensure(handle h, int ExtraFlags = 0) { - auto result = reinterpret_steal(raw_array(h.ptr(), ExtraFlags)); - if (!result) - PyErr_Clear(); - return result; - } - -protected: - template friend struct detail::npy_format_descriptor; - - void fail_dim_check(size_t dim, const std::string& msg) const { - throw index_error(msg + ": " + std::to_string(dim) + - " (ndim = " + std::to_string(ndim()) + ")"); - } - - template size_t byte_offset(Ix... index) const { - check_dimensions(index...); - return byte_offset_unsafe(index...); - } - - template size_t byte_offset_unsafe(size_t i, Ix... index) const { - return i * strides()[dim] + byte_offset_unsafe(index...); - } - - template size_t byte_offset_unsafe() const { return 0; } - - void check_writeable() const { - if (!writeable()) - throw std::runtime_error("array is not writeable"); - } - - static std::vector default_strides(const std::vector& shape, size_t itemsize) { - auto ndim = shape.size(); - std::vector strides(ndim); - if (ndim) { - std::fill(strides.begin(), strides.end(), itemsize); - for (size_t i = 0; i < ndim - 1; i++) - for (size_t j = 0; j < ndim - 1 - i; j++) - strides[j] *= shape[ndim - 1 - i]; - } - return strides; - } - - template void check_dimensions(Ix... index) const { - check_dimensions_impl(size_t(0), shape(), size_t(index)...); - } - - void check_dimensions_impl(size_t, const size_t*) const { } - - template void check_dimensions_impl(size_t axis, const size_t* shape, size_t i, Ix... index) const { - if (i >= *shape) { - throw index_error(std::string("index ") + std::to_string(i) + - " is out of bounds for axis " + std::to_string(axis) + - " with size " + std::to_string(*shape)); - } - check_dimensions_impl(axis + 1, shape + 1, index...); - } - - /// Create array from any object -- always returns a new reference - static PyObject *raw_array(PyObject *ptr, int ExtraFlags = 0) { - if (ptr == nullptr) - return nullptr; - return detail::npy_api::get().PyArray_FromAny_( - ptr, nullptr, 0, 0, detail::npy_api::NPY_ENSURE_ARRAY_ | ExtraFlags, nullptr); - } -}; - -template class array_t : public array { -public: - array_t() : array(0, static_cast(nullptr)) {} - array_t(handle h, borrowed_t) : array(h, borrowed) { } - array_t(handle h, stolen_t) : array(h, stolen) { } - - PYBIND11_DEPRECATED("Use array_t::ensure() instead") - array_t(handle h, bool is_borrowed) : array(raw_array_t(h.ptr()), stolen) { - if (!m_ptr) PyErr_Clear(); - if (!is_borrowed) Py_XDECREF(h.ptr()); - } - - array_t(const object &o) : array(raw_array_t(o.ptr()), stolen) { - if (!m_ptr) throw error_already_set(); - } - - explicit array_t(const buffer_info& info) : array(info) { } - - array_t(const std::vector &shape, - const std::vector &strides, const T *ptr = nullptr, - handle base = handle()) - : array(shape, strides, ptr, base) { } - - explicit array_t(const std::vector &shape, const T *ptr = nullptr, - handle base = handle()) - : array(shape, ptr, base) { } - - explicit array_t(size_t count, const T *ptr = nullptr, handle base = handle()) - : array(count, ptr, base) { } - - constexpr size_t itemsize() const { - return sizeof(T); - } - - template size_t index_at(Ix... index) const { - return offset_at(index...) / itemsize(); - } - - template const T* data(Ix... index) const { - return static_cast(array::data(index...)); - } - - template T* mutable_data(Ix... index) { - return static_cast(array::mutable_data(index...)); - } - - // Reference to element at a given index - template const T& at(Ix... index) const { - if (sizeof...(index) != ndim()) - fail_dim_check(sizeof...(index), "index dimension mismatch"); - return *(static_cast(array::data()) + byte_offset(size_t(index)...) / itemsize()); - } - - // Mutable reference to element at a given index - template T& mutable_at(Ix... index) { - if (sizeof...(index) != ndim()) - fail_dim_check(sizeof...(index), "index dimension mismatch"); - return *(static_cast(array::mutable_data()) + byte_offset(size_t(index)...) / itemsize()); - } - - /// Ensure that the argument is a NumPy array of the correct dtype. - /// In case of an error, nullptr is returned and the Python error is cleared. - static array_t ensure(handle h) { - auto result = reinterpret_steal(raw_array_t(h.ptr())); - if (!result) - PyErr_Clear(); - return result; - } - - static bool _check(handle h) { - const auto &api = detail::npy_api::get(); - return api.PyArray_Check_(h.ptr()) - && api.PyArray_EquivTypes_(detail::array_proxy(h.ptr())->descr, dtype::of().ptr()); - } - -protected: - /// Create array from any object -- always returns a new reference - static PyObject *raw_array_t(PyObject *ptr) { - if (ptr == nullptr) - return nullptr; - return detail::npy_api::get().PyArray_FromAny_( - ptr, dtype::of().release().ptr(), 0, 0, - detail::npy_api::NPY_ENSURE_ARRAY_ | ExtraFlags, nullptr); - } -}; - -template -struct format_descriptor::value>> { - static std::string format() { - return detail::npy_format_descriptor::type>::format(); - } -}; - -template struct format_descriptor { - static std::string format() { return std::to_string(N) + "s"; } -}; -template struct format_descriptor> { - static std::string format() { return std::to_string(N) + "s"; } -}; - -template -struct format_descriptor::value>> { - static std::string format() { - return format_descriptor< - typename std::remove_cv::type>::type>::format(); - } -}; - -NAMESPACE_BEGIN(detail) -template -struct pyobject_caster> { - using type = array_t; - - bool load(handle src, bool /* convert */) { - value = type::ensure(src); - return static_cast(value); - } - - static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) { - return src.inc_ref(); - } - PYBIND11_TYPE_CASTER(type, handle_type_name::name()); -}; - -template struct is_std_array : std::false_type { }; -template struct is_std_array> : std::true_type { }; - -template -struct is_pod_struct { - enum { value = std::is_pod::value && // offsetof only works correctly for POD types - !std::is_reference::value && - !std::is_array::value && - !is_std_array::value && - !std::is_integral::value && - !std::is_enum::value && - !std::is_same::type, float>::value && - !std::is_same::type, double>::value && - !std::is_same::type, bool>::value && - !std::is_same::type, std::complex>::value && - !std::is_same::type, std::complex>::value }; -}; - -template struct npy_format_descriptor::value>> { -private: - constexpr static const int values[8] = { - npy_api::NPY_BYTE_, npy_api::NPY_UBYTE_, npy_api::NPY_SHORT_, npy_api::NPY_USHORT_, - npy_api::NPY_INT_, npy_api::NPY_UINT_, npy_api::NPY_LONGLONG_, npy_api::NPY_ULONGLONG_ }; -public: - enum { value = values[detail::log2(sizeof(T)) * 2 + (std::is_unsigned::value ? 1 : 0)] }; - static pybind11::dtype dtype() { - if (auto ptr = npy_api::get().PyArray_DescrFromType_(value)) - return reinterpret_borrow(ptr); - pybind11_fail("Unsupported buffer format!"); - } - template ::value, int> = 0> - static PYBIND11_DESCR name() { return _("int") + _(); } - template ::value, int> = 0> - static PYBIND11_DESCR name() { return _("uint") + _(); } -}; -template constexpr const int npy_format_descriptor< - T, enable_if_t::value>>::values[8]; - -#define DECL_FMT(Type, NumPyName, Name) template<> struct npy_format_descriptor { \ - enum { value = npy_api::NumPyName }; \ - static pybind11::dtype dtype() { \ - if (auto ptr = npy_api::get().PyArray_DescrFromType_(value)) \ - return reinterpret_borrow(ptr); \ - pybind11_fail("Unsupported buffer format!"); \ - } \ - static PYBIND11_DESCR name() { return _(Name); } } -DECL_FMT(float, NPY_FLOAT_, "float32"); -DECL_FMT(double, NPY_DOUBLE_, "float64"); -DECL_FMT(bool, NPY_BOOL_, "bool"); -DECL_FMT(std::complex, NPY_CFLOAT_, "complex64"); -DECL_FMT(std::complex, NPY_CDOUBLE_, "complex128"); -#undef DECL_FMT - -#define DECL_CHAR_FMT \ - static PYBIND11_DESCR name() { return _("S") + _(); } \ - static pybind11::dtype dtype() { return pybind11::dtype(std::string("S") + std::to_string(N)); } -template struct npy_format_descriptor { DECL_CHAR_FMT }; -template struct npy_format_descriptor> { DECL_CHAR_FMT }; -#undef DECL_CHAR_FMT - -template struct npy_format_descriptor::value>> { -private: - using base_descr = npy_format_descriptor::type>; -public: - static PYBIND11_DESCR name() { return base_descr::name(); } - static pybind11::dtype dtype() { return base_descr::dtype(); } -}; - -struct field_descriptor { - const char *name; - size_t offset; - size_t size; - size_t alignment; - std::string format; - dtype descr; -}; - -inline PYBIND11_NOINLINE void register_structured_dtype( - const std::initializer_list& fields, - const std::type_info& tinfo, size_t itemsize, - bool (*direct_converter)(PyObject *, void *&)) { - - auto& numpy_internals = get_numpy_internals(); - if (numpy_internals.get_type_info(tinfo, false)) - pybind11_fail("NumPy: dtype is already registered"); - - list names, formats, offsets; - for (auto field : fields) { - if (!field.descr) - pybind11_fail(std::string("NumPy: unsupported field dtype: `") + - field.name + "` @ " + tinfo.name()); - names.append(PYBIND11_STR_TYPE(field.name)); - formats.append(field.descr); - offsets.append(pybind11::int_(field.offset)); - } - auto dtype_ptr = pybind11::dtype(names, formats, offsets, itemsize).release().ptr(); - - // There is an existing bug in NumPy (as of v1.11): trailing bytes are - // not encoded explicitly into the format string. This will supposedly - // get fixed in v1.12; for further details, see these: - // - https://github.com/numpy/numpy/issues/7797 - // - https://github.com/numpy/numpy/pull/7798 - // Because of this, we won't use numpy's logic to generate buffer format - // strings and will just do it ourselves. - std::vector ordered_fields(fields); - std::sort(ordered_fields.begin(), ordered_fields.end(), - [](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; }); - size_t offset = 0; - std::ostringstream oss; - oss << "T{"; - for (auto& field : ordered_fields) { - if (field.offset > offset) - oss << (field.offset - offset) << 'x'; - // mark unaligned fields with '=' - if (field.offset % field.alignment) - oss << '='; - oss << field.format << ':' << field.name << ':'; - offset = field.offset + field.size; - } - if (itemsize > offset) - oss << (itemsize - offset) << 'x'; - oss << '}'; - auto format_str = oss.str(); - - // Sanity check: verify that NumPy properly parses our buffer format string - auto& api = npy_api::get(); - auto arr = array(buffer_info(nullptr, itemsize, format_str, 1)); - if (!api.PyArray_EquivTypes_(dtype_ptr, arr.dtype().ptr())) - pybind11_fail("NumPy: invalid buffer descriptor!"); - - auto tindex = std::type_index(tinfo); - numpy_internals.registered_dtypes[tindex] = { dtype_ptr, format_str }; - get_internals().direct_conversions[tindex].push_back(direct_converter); -} - -template -struct npy_format_descriptor::value>> { - static PYBIND11_DESCR name() { return _("struct"); } - - static pybind11::dtype dtype() { - return reinterpret_borrow(dtype_ptr()); - } - - static std::string format() { - static auto format_str = get_numpy_internals().get_type_info(true)->format_str; - return format_str; - } - - static void register_dtype(const std::initializer_list& fields) { - register_structured_dtype(fields, typeid(typename std::remove_cv::type), - sizeof(T), &direct_converter); - } - -private: - static PyObject* dtype_ptr() { - static PyObject* ptr = get_numpy_internals().get_type_info(true)->dtype_ptr; - return ptr; - } - - static bool direct_converter(PyObject *obj, void*& value) { - auto& api = npy_api::get(); - if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_)) - return false; - if (auto descr = reinterpret_steal(api.PyArray_DescrFromScalar_(obj))) { - if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) { - value = ((PyVoidScalarObject_Proxy *) obj)->obval; - return true; - } - } - return false; - } -}; - -#define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \ - ::pybind11::detail::field_descriptor { \ - Name, offsetof(T, Field), sizeof(decltype(std::declval().Field)), \ - alignof(decltype(std::declval().Field)), \ - ::pybind11::format_descriptor().Field)>::format(), \ - ::pybind11::detail::npy_format_descriptor().Field)>::dtype() \ - } - -// Extract name, offset and format descriptor for a struct field -#define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #Field) - -// The main idea of this macro is borrowed from https://github.com/swansontec/map-macro -// (C) William Swanson, Paul Fultz -#define PYBIND11_EVAL0(...) __VA_ARGS__ -#define PYBIND11_EVAL1(...) PYBIND11_EVAL0 (PYBIND11_EVAL0 (PYBIND11_EVAL0 (__VA_ARGS__))) -#define PYBIND11_EVAL2(...) PYBIND11_EVAL1 (PYBIND11_EVAL1 (PYBIND11_EVAL1 (__VA_ARGS__))) -#define PYBIND11_EVAL3(...) PYBIND11_EVAL2 (PYBIND11_EVAL2 (PYBIND11_EVAL2 (__VA_ARGS__))) -#define PYBIND11_EVAL4(...) PYBIND11_EVAL3 (PYBIND11_EVAL3 (PYBIND11_EVAL3 (__VA_ARGS__))) -#define PYBIND11_EVAL(...) PYBIND11_EVAL4 (PYBIND11_EVAL4 (PYBIND11_EVAL4 (__VA_ARGS__))) -#define PYBIND11_MAP_END(...) -#define PYBIND11_MAP_OUT -#define PYBIND11_MAP_COMMA , -#define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END -#define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT -#define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0 (test, next, 0) -#define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1 (PYBIND11_MAP_GET_END test, next) -#ifdef _MSC_VER // MSVC is not as eager to expand macros, hence this workaround -#define PYBIND11_MAP_LIST_NEXT1(test, next) \ - PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) -#else -#define PYBIND11_MAP_LIST_NEXT1(test, next) \ - PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) -#endif -#define PYBIND11_MAP_LIST_NEXT(test, next) \ - PYBIND11_MAP_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) -#define PYBIND11_MAP_LIST0(f, t, x, peek, ...) \ - f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST1) (f, t, peek, __VA_ARGS__) -#define PYBIND11_MAP_LIST1(f, t, x, peek, ...) \ - f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST0) (f, t, peek, __VA_ARGS__) -// PYBIND11_MAP_LIST(f, t, a1, a2, ...) expands to f(t, a1), f(t, a2), ... -#define PYBIND11_MAP_LIST(f, t, ...) \ - PYBIND11_EVAL (PYBIND11_MAP_LIST1 (f, t, __VA_ARGS__, (), 0)) - -#define PYBIND11_NUMPY_DTYPE(Type, ...) \ - ::pybind11::detail::npy_format_descriptor::register_dtype \ - ({PYBIND11_MAP_LIST (PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)}) - -#ifdef _MSC_VER -#define PYBIND11_MAP2_LIST_NEXT1(test, next) \ - PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) -#else -#define PYBIND11_MAP2_LIST_NEXT1(test, next) \ - PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) -#endif -#define PYBIND11_MAP2_LIST_NEXT(test, next) \ - PYBIND11_MAP2_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) -#define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...) \ - f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST1) (f, t, peek, __VA_ARGS__) -#define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...) \ - f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST0) (f, t, peek, __VA_ARGS__) -// PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ... -#define PYBIND11_MAP2_LIST(f, t, ...) \ - PYBIND11_EVAL (PYBIND11_MAP2_LIST1 (f, t, __VA_ARGS__, (), 0)) - -#define PYBIND11_NUMPY_DTYPE_EX(Type, ...) \ - ::pybind11::detail::npy_format_descriptor::register_dtype \ - ({PYBIND11_MAP2_LIST (PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)}) - -template -using array_iterator = typename std::add_pointer::type; - -template -array_iterator array_begin(const buffer_info& buffer) { - return array_iterator(reinterpret_cast(buffer.ptr)); -} - -template -array_iterator array_end(const buffer_info& buffer) { - return array_iterator(reinterpret_cast(buffer.ptr) + buffer.size); -} - -class common_iterator { -public: - using container_type = std::vector; - using value_type = container_type::value_type; - using size_type = container_type::size_type; - - common_iterator() : p_ptr(0), m_strides() {} - - common_iterator(void* ptr, const container_type& strides, const std::vector& shape) - : p_ptr(reinterpret_cast(ptr)), m_strides(strides.size()) { - m_strides.back() = static_cast(strides.back()); - for (size_type i = m_strides.size() - 1; i != 0; --i) { - size_type j = i - 1; - value_type s = static_cast(shape[i]); - m_strides[j] = strides[j] + m_strides[i] - strides[i] * s; - } - } - - void increment(size_type dim) { - p_ptr += m_strides[dim]; - } - - void* data() const { - return p_ptr; - } - -private: - char* p_ptr; - container_type m_strides; -}; - -template class multi_array_iterator { -public: - using container_type = std::vector; - - multi_array_iterator(const std::array &buffers, - const std::vector &shape) - : m_shape(shape.size()), m_index(shape.size(), 0), - m_common_iterator() { - - // Manual copy to avoid conversion warning if using std::copy - for (size_t i = 0; i < shape.size(); ++i) - m_shape[i] = static_cast(shape[i]); - - container_type strides(shape.size()); - for (size_t i = 0; i < N; ++i) - init_common_iterator(buffers[i], shape, m_common_iterator[i], strides); - } - - multi_array_iterator& operator++() { - for (size_t j = m_index.size(); j != 0; --j) { - size_t i = j - 1; - if (++m_index[i] != m_shape[i]) { - increment_common_iterator(i); - break; - } else { - m_index[i] = 0; - } - } - return *this; - } - - template const T& data() const { - return *reinterpret_cast(m_common_iterator[K].data()); - } - -private: - - using common_iter = common_iterator; - - void init_common_iterator(const buffer_info &buffer, - const std::vector &shape, - common_iter &iterator, container_type &strides) { - auto buffer_shape_iter = buffer.shape.rbegin(); - auto buffer_strides_iter = buffer.strides.rbegin(); - auto shape_iter = shape.rbegin(); - auto strides_iter = strides.rbegin(); - - while (buffer_shape_iter != buffer.shape.rend()) { - if (*shape_iter == *buffer_shape_iter) - *strides_iter = static_cast(*buffer_strides_iter); - else - *strides_iter = 0; - - ++buffer_shape_iter; - ++buffer_strides_iter; - ++shape_iter; - ++strides_iter; - } - - std::fill(strides_iter, strides.rend(), 0); - iterator = common_iter(buffer.ptr, strides, shape); - } - - void increment_common_iterator(size_t dim) { - for (auto &iter : m_common_iterator) - iter.increment(dim); - } - - container_type m_shape; - container_type m_index; - std::array m_common_iterator; -}; - -template -bool broadcast(const std::array& buffers, size_t& ndim, std::vector& shape) { - ndim = std::accumulate(buffers.begin(), buffers.end(), size_t(0), [](size_t res, const buffer_info& buf) { - return std::max(res, buf.ndim); - }); - - shape = std::vector(ndim, 1); - bool trivial_broadcast = true; - for (size_t i = 0; i < N; ++i) { - auto res_iter = shape.rbegin(); - bool i_trivial_broadcast = (buffers[i].size == 1) || (buffers[i].ndim == ndim); - for (auto shape_iter = buffers[i].shape.rbegin(); - shape_iter != buffers[i].shape.rend(); ++shape_iter, ++res_iter) { - - if (*res_iter == 1) - *res_iter = *shape_iter; - else if ((*shape_iter != 1) && (*res_iter != *shape_iter)) - pybind11_fail("pybind11::vectorize: incompatible size/dimension of inputs!"); - - i_trivial_broadcast = i_trivial_broadcast && (*res_iter == *shape_iter); - } - trivial_broadcast = trivial_broadcast && i_trivial_broadcast; - } - return trivial_broadcast; -} - -template -struct vectorize_helper { - typename std::remove_reference::type f; - - template - explicit vectorize_helper(T&&f) : f(std::forward(f)) { } - - object operator()(array_t... args) { - return run(args..., typename make_index_sequence::type()); - } - - template object run(array_t&... args, index_sequence index) { - /* Request buffers from all parameters */ - const size_t N = sizeof...(Args); - - std::array buffers {{ args.request()... }}; - - /* Determine dimensions parameters of output array */ - size_t ndim = 0; - std::vector shape(0); - bool trivial_broadcast = broadcast(buffers, ndim, shape); - - size_t size = 1; - std::vector strides(ndim); - if (ndim > 0) { - strides[ndim-1] = sizeof(Return); - for (size_t i = ndim - 1; i > 0; --i) { - strides[i - 1] = strides[i] * shape[i]; - size *= shape[i]; - } - size *= shape[0]; - } - - if (size == 1) - return cast(f(*((Args *) buffers[Index].ptr)...)); - - array_t result(shape, strides); - auto buf = result.request(); - auto output = (Return *) buf.ptr; - - if (trivial_broadcast) { - /* Call the function */ - for (size_t i = 0; i < size; ++i) { - output[i] = f((buffers[Index].size == 1 - ? *((Args *) buffers[Index].ptr) - : ((Args *) buffers[Index].ptr)[i])...); - } - } else { - apply_broadcast(buffers, buf, index); - } - - return result; - } - - template - void apply_broadcast(const std::array &buffers, - buffer_info &output, index_sequence) { - using input_iterator = multi_array_iterator; - using output_iterator = array_iterator; - - input_iterator input_iter(buffers, output.shape); - output_iterator output_end = array_end(output); - - for (output_iterator iter = array_begin(output); - iter != output_end; ++iter, ++input_iter) { - *iter = f((input_iter.template data())...); - } - } -}; - -template struct handle_type_name> { - static PYBIND11_DESCR name() { return _("numpy.ndarray[") + type_caster::name() + _("]"); } -}; - -NAMESPACE_END(detail) - -template -detail::vectorize_helper vectorize(const Func &f, Return (*) (Args ...)) { - return detail::vectorize_helper(f); -} - -template -detail::vectorize_helper vectorize(Return (*f) (Args ...)) { - return vectorize(f, f); -} - -template -auto vectorize(Func &&f) -> decltype( - vectorize(std::forward(f), (typename detail::remove_class::type::operator())>::type *) nullptr)) { - return vectorize(std::forward(f), (typename detail::remove_class::type::operator())>::type *) nullptr); -} - -NAMESPACE_END(pybind11) - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif diff --git a/stormpy/resources/pybind11/include/pybind11/operators.h b/stormpy/resources/pybind11/include/pybind11/operators.h deleted file mode 100644 index 2e78c01a3..000000000 --- a/stormpy/resources/pybind11/include/pybind11/operators.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - pybind11/operator.h: Metatemplates for operator overloading - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" - -#if defined(__clang__) && !defined(__INTEL_COMPILER) -# pragma clang diagnostic ignored "-Wunsequenced" // multiple unsequenced modifications to 'self' (when using def(py::self OP Type())) -#endif - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -/// Enumeration with all supported operator types -enum op_id : int { - 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, op_bool, op_nonzero, - op_repr, op_truediv -}; - -enum op_type : int { - op_l, /* base type on left */ - op_r, /* base type on right */ - op_u /* unary operator */ -}; - -struct self_t { }; -static const self_t self = self_t(); - -/// Type for an unused type slot -struct undefined_t { }; - -/// Don't warn about an unused variable -inline self_t __self() { return self; } - -/// base template of operator implementations -template struct op_impl { }; - -/// Operator implementation generator -template struct op_ { - template void execute(Class &cl, const Extra&... extra) const { - typedef typename Class::type Base; - typedef typename std::conditional::value, Base, L>::type L_type; - typedef typename std::conditional::value, Base, R>::type R_type; - typedef op_impl op; - cl.def(op::name(), &op::execute, is_operator(), extra...); - } - template void execute_cast(Class &cl, const Extra&... extra) const { - typedef typename Class::type Base; - typedef typename std::conditional::value, Base, L>::type L_type; - typedef typename std::conditional::value, Base, R>::type R_type; - typedef op_impl op; - cl.def(op::name(), &op::execute_cast, is_operator(), extra...); - } -}; - -#define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \ -template struct op_impl { \ - static char const* name() { return "__" #id "__"; } \ - static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \ - static B execute_cast(const L &l, const R &r) { return B(expr); } \ -}; \ -template struct op_impl { \ - static char const* name() { return "__" #rid "__"; } \ - static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \ - static B execute_cast(const R &r, const L &l) { return B(expr); } \ -}; \ -inline op_ op(const self_t &, const self_t &) { \ - return op_(); \ -} \ -template op_ op(const self_t &, const T &) { \ - return op_(); \ -} \ -template op_ op(const T &, const self_t &) { \ - return op_(); \ -} - -#define PYBIND11_INPLACE_OPERATOR(id, op, expr) \ -template struct op_impl { \ - static char const* name() { return "__" #id "__"; } \ - static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \ - static B execute_cast(L &l, const R &r) { return B(expr); } \ -}; \ -template op_ op(const self_t &, const T &) { \ - return op_(); \ -} - -#define PYBIND11_UNARY_OPERATOR(id, op, expr) \ -template struct op_impl { \ - static char const* name() { return "__" #id "__"; } \ - static auto execute(const L &l) -> decltype(expr) { return expr; } \ - static B execute_cast(const L &l) { return B(expr); } \ -}; \ -inline op_ op(const self_t &) { \ - return op_(); \ -} - -PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) -PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) -PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) -#if PY_MAJOR_VERSION >= 3 -PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) -#else -PYBIND11_BINARY_OPERATOR(div, rdiv, operator/, l / r) -#endif -PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) -PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) -PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) -PYBIND11_BINARY_OPERATOR(and, rand, operator&, l & r) -PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r) -PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r) -PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r) -PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r) -PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r) -PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r) -PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r) -PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) -//PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r)) -PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) -PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) -PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) -PYBIND11_INPLACE_OPERATOR(idiv, operator/=, l /= r) -PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) -PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) -PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) -PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r) -PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r) -PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r) -PYBIND11_UNARY_OPERATOR(neg, operator-, -l) -PYBIND11_UNARY_OPERATOR(pos, operator+, +l) -PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l)) -PYBIND11_UNARY_OPERATOR(invert, operator~, (~l)) -PYBIND11_UNARY_OPERATOR(bool, operator!, !!l) -PYBIND11_UNARY_OPERATOR(int, int_, (int) l) -PYBIND11_UNARY_OPERATOR(float, float_, (double) l) - -#undef PYBIND11_BINARY_OPERATOR -#undef PYBIND11_INPLACE_OPERATOR -#undef PYBIND11_UNARY_OPERATOR -NAMESPACE_END(detail) - -using detail::self; - -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/options.h b/stormpy/resources/pybind11/include/pybind11/options.h deleted file mode 100755 index 3105551dd..000000000 --- a/stormpy/resources/pybind11/include/pybind11/options.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - pybind11/options.h: global settings that are configurable at runtime. - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "common.h" - -NAMESPACE_BEGIN(pybind11) - -class options { -public: - - // Default RAII constructor, which leaves settings as they currently are. - options() : previous_state(global_state()) {} - - // Class is non-copyable. - options(const options&) = delete; - options& operator=(const options&) = delete; - - // Destructor, which restores settings that were in effect before. - ~options() { - global_state() = previous_state; - } - - // Setter methods (affect the global state): - - options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; } - - options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; } - - options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; } - - options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; } - - // Getter methods (return the global state): - - static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; } - - static bool show_function_signatures() { return global_state().show_function_signatures; } - - // This type is not meant to be allocated on the heap. - void* operator new(size_t) = delete; - -private: - - struct state { - bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. - bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. - }; - - static state &global_state() { - static state instance; - return instance; - } - - state previous_state; -}; - -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/pybind11.h b/stormpy/resources/pybind11/include/pybind11/pybind11.h deleted file mode 100644 index b7d75d981..000000000 --- a/stormpy/resources/pybind11/include/pybind11/pybind11.h +++ /dev/null @@ -1,1722 +0,0 @@ -/* - pybind11/pybind11.h: Main header file of the C++11 python - binding generator library - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter -# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -# pragma warning(disable: 4512) // warning C4512: Assignment operator was implicitly defined as deleted -# pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) -# pragma warning(disable: 4996) // warning C4996: The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name -# pragma warning(disable: 4702) // warning C4702: unreachable code -# pragma warning(disable: 4522) // warning C4522: multiple assignment operators specified -#elif defined(__INTEL_COMPILER) -# pragma warning(push) -# pragma warning(disable: 186) // pointless comparison of unsigned integer with zero -# pragma warning(disable: 1334) // the "template" keyword used for syntactic disambiguation may only be used within a template -# pragma warning(disable: 2196) // warning #2196: routine is both "inline" and "noinline" -#elif defined(__GNUG__) && !defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-but-set-parameter" -# pragma GCC diagnostic ignored "-Wunused-but-set-variable" -# pragma GCC diagnostic ignored "-Wmissing-field-initializers" -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -# pragma GCC diagnostic ignored "-Wattributes" -#endif - -#include "attr.h" -#include "options.h" - -NAMESPACE_BEGIN(pybind11) - -/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object -class cpp_function : public function { -public: - cpp_function() { } - - /// Construct a cpp_function from a vanilla function pointer - template - cpp_function(Return (*f)(Args...), const Extra&... extra) { - initialize(f, f, extra...); - } - - /// Construct a cpp_function from a lambda function (possibly with internal state) - template cpp_function(Func &&f, const Extra&... extra) { - initialize(std::forward(f), - (typename detail::remove_class::type::operator())>::type *) nullptr, extra...); - } - - /// Construct a cpp_function from a class method (non-const) - template - cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) { - initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); }, - (Return (*) (Class *, Arg...)) nullptr, extra...); - } - - /// Construct a cpp_function from a class method (const) - template - cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) { - initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); }, - (Return (*)(const Class *, Arg ...)) nullptr, extra...); - } - - /// Return the function name - object name() const { return attr("__name__"); } - -protected: - /// Space optimization: don't inline this frequently instantiated fragment - PYBIND11_NOINLINE detail::function_record *make_function_record() { - return new detail::function_record(); - } - - /// Special internal constructor for functors, lambda functions, etc. - template - void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) { - static_assert(detail::expected_num_args(sizeof...(Args)), - "The number of named arguments does not match the function signature"); - - struct capture { typename std::remove_reference::type f; }; - - /* Store the function including any extra state it might have (e.g. a lambda capture object) */ - auto rec = make_function_record(); - - /* Store the capture object directly in the function record if there is enough space */ - if (sizeof(capture) <= sizeof(rec->data)) { - /* Without these pragmas, GCC warns that there might not be - enough space to use the placement new operator. However, the - 'if' statement above ensures that this is the case. */ -#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wplacement-new" -#endif - new ((capture *) &rec->data) capture { std::forward(f) }; -#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 -# pragma GCC diagnostic pop -#endif - if (!std::is_trivially_destructible::value) - rec->free_data = [](detail::function_record *r) { ((capture *) &r->data)->~capture(); }; - } else { - rec->data[0] = new capture { std::forward(f) }; - rec->free_data = [](detail::function_record *r) { delete ((capture *) r->data[0]); }; - } - - /* Type casters for the function arguments and return value */ - typedef detail::type_caster> cast_in; - typedef detail::type_caster::value, detail::void_type, - typename detail::intrinsic_type::type>::type> cast_out; - - /* Dispatch code which converts function arguments and performs the actual function call */ - rec->impl = [](detail::function_record *rec, handle args, handle kwargs, handle parent) -> handle { - cast_in args_converter; - - /* Try to cast the function arguments into the C++ domain */ - if (!args_converter.load_args(args, kwargs, true)) - return PYBIND11_TRY_NEXT_OVERLOAD; - - /* Invoke call policy pre-call hook */ - detail::process_attributes::precall(args); - - /* Get a pointer to the capture object */ - capture *cap = (capture *) (sizeof(capture) <= sizeof(rec->data) - ? &rec->data : rec->data[0]); - - /* Override policy for rvalues -- always move */ - constexpr auto is_rvalue = !std::is_pointer::value - && !std::is_lvalue_reference::value; - const auto policy = is_rvalue ? return_value_policy::move : rec->policy; - - /* Perform the function call */ - handle result = cast_out::cast(args_converter.template call(cap->f), - policy, parent); - - /* Invoke call policy post-call hook */ - detail::process_attributes::postcall(args, result); - - return result; - }; - - /* Process any user-provided function attributes */ - detail::process_attributes::init(extra..., rec); - - /* Generate a readable signature describing the function's arguments and return value types */ - using detail::descr; using detail::_; - PYBIND11_DESCR signature = _("(") + cast_in::element_names() + _(") -> ") + cast_out::name(); - - /* Register the function with Python from generic (non-templated) code */ - initialize_generic(rec, signature.text(), signature.types(), sizeof...(Args)); - - if (cast_in::has_args) rec->has_args = true; - if (cast_in::has_kwargs) rec->has_kwargs = true; - - /* Stash some additional information used by an important optimization in 'functional.h' */ - using FunctionType = Return (*)(Args...); - constexpr bool is_function_ptr = - std::is_convertible::value && - sizeof(capture) == sizeof(void *); - if (is_function_ptr) { - rec->is_stateless = true; - rec->data[1] = (void *) &typeid(FunctionType); - } - } - - /// Register a function call with Python (generic non-templated code goes here) - void initialize_generic(detail::function_record *rec, const char *text, - const std::type_info *const *types, size_t args) { - - /* Create copies of all referenced C-style strings */ - rec->name = strdup(rec->name ? rec->name : ""); - if (rec->doc) rec->doc = strdup(rec->doc); - for (auto &a: rec->args) { - if (a.name) - a.name = strdup(a.name); - if (a.descr) - a.descr = strdup(a.descr); - else if (a.value) - a.descr = strdup(a.value.attr("__repr__")().cast().c_str()); - } - - /* Generate a proper function signature */ - std::string signature; - size_t type_depth = 0, char_index = 0, type_index = 0, arg_index = 0; - while (true) { - char c = text[char_index++]; - if (c == '\0') - break; - - if (c == '{') { - // Write arg name for everything except *args, **kwargs and return type. - if (type_depth == 0 && text[char_index] != '*' && arg_index < args) { - if (!rec->args.empty()) { - signature += rec->args[arg_index].name; - } else if (arg_index == 0 && rec->is_method) { - signature += "self"; - } else { - signature += "arg" + std::to_string(arg_index - (rec->is_method ? 1 : 0)); - } - signature += ": "; - } - ++type_depth; - } else if (c == '}') { - --type_depth; - if (type_depth == 0) { - if (arg_index < rec->args.size() && rec->args[arg_index].descr) { - signature += "="; - signature += rec->args[arg_index].descr; - } - arg_index++; - } - } else if (c == '%') { - const std::type_info *t = types[type_index++]; - if (!t) - pybind11_fail("Internal error while parsing type signature (1)"); - if (auto tinfo = detail::get_type_info(*t)) { - signature += tinfo->type->tp_name; - } else { - std::string tname(t->name()); - detail::clean_type_id(tname); - signature += tname; - } - } else { - signature += c; - } - } - if (type_depth != 0 || types[type_index] != nullptr) - pybind11_fail("Internal error while parsing type signature (2)"); - - #if !defined(PYBIND11_CPP14) - delete[] types; - delete[] text; - #endif - -#if PY_MAJOR_VERSION < 3 - if (strcmp(rec->name, "__next__") == 0) { - std::free(rec->name); - rec->name = strdup("next"); - } else if (strcmp(rec->name, "__bool__") == 0) { - std::free(rec->name); - rec->name = strdup("__nonzero__"); - } -#endif - rec->signature = strdup(signature.c_str()); - rec->args.shrink_to_fit(); - rec->is_constructor = !strcmp(rec->name, "__init__") || !strcmp(rec->name, "__setstate__"); - rec->nargs = (uint16_t) args; - -#if PY_MAJOR_VERSION < 3 - if (rec->sibling && PyMethod_Check(rec->sibling.ptr())) - rec->sibling = PyMethod_GET_FUNCTION(rec->sibling.ptr()); -#endif - - detail::function_record *chain = nullptr, *chain_start = rec; - if (rec->sibling) { - if (PyCFunction_Check(rec->sibling.ptr())) { - auto rec_capsule = reinterpret_borrow(PyCFunction_GetSelf(rec->sibling.ptr())); - chain = (detail::function_record *) rec_capsule; - /* Never append a method to an overload chain of a parent class; - instead, hide the parent's overloads in this case */ - if (chain->scope != rec->scope) - chain = nullptr; - } - // Don't trigger for things like the default __init__, which are wrapper_descriptors that we are intentionally replacing - else if (!rec->sibling.is_none() && rec->name[0] != '_') - pybind11_fail("Cannot overload existing non-function object \"" + std::string(rec->name) + - "\" with a function of the same name"); - } - - if (!chain) { - /* No existing overload was found, create a new function object */ - rec->def = new PyMethodDef(); - memset(rec->def, 0, sizeof(PyMethodDef)); - rec->def->ml_name = rec->name; - rec->def->ml_meth = reinterpret_cast(*dispatcher); - rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS; - - capsule rec_capsule(rec, [](PyObject *o) { - destruct((detail::function_record *) PyCapsule_GetPointer(o, nullptr)); - }); - - object scope_module; - if (rec->scope) { - if (hasattr(rec->scope, "__module__")) { - scope_module = rec->scope.attr("__module__"); - } else if (hasattr(rec->scope, "__name__")) { - scope_module = rec->scope.attr("__name__"); - } - } - - m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr()); - if (!m_ptr) - pybind11_fail("cpp_function::cpp_function(): Could not allocate function object"); - } else { - /* Append at the end of the overload chain */ - m_ptr = rec->sibling.ptr(); - inc_ref(); - chain_start = chain; - while (chain->next) - chain = chain->next; - chain->next = rec; - } - - std::string signatures; - int index = 0; - /* Create a nice pydoc rec including all signatures and - docstrings of the functions in the overload chain */ - if (chain && options::show_function_signatures()) { - // First a generic signature - signatures += rec->name; - signatures += "(*args, **kwargs)\n"; - signatures += "Overloaded function.\n\n"; - } - // Then specific overload signatures - for (auto it = chain_start; it != nullptr; it = it->next) { - if (options::show_function_signatures()) { - if (chain) - signatures += std::to_string(++index) + ". "; - signatures += rec->name; - signatures += it->signature; - signatures += "\n"; - } - if (it->doc && strlen(it->doc) > 0 && options::show_user_defined_docstrings()) { - if (options::show_function_signatures()) signatures += "\n"; - signatures += it->doc; - if (options::show_function_signatures()) signatures += "\n"; - } - if (it->next) - signatures += "\n"; - } - - /* Install docstring */ - PyCFunctionObject *func = (PyCFunctionObject *) m_ptr; - if (func->m_ml->ml_doc) - std::free((char *) func->m_ml->ml_doc); - func->m_ml->ml_doc = strdup(signatures.c_str()); - - if (rec->is_method) { - m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr()); - if (!m_ptr) - pybind11_fail("cpp_function::cpp_function(): Could not allocate instance method object"); - Py_DECREF(func); - } - } - - /// When a cpp_function is GCed, release any memory allocated by pybind11 - static void destruct(detail::function_record *rec) { - while (rec) { - detail::function_record *next = rec->next; - if (rec->free_data) - rec->free_data(rec); - std::free((char *) rec->name); - std::free((char *) rec->doc); - std::free((char *) rec->signature); - for (auto &arg: rec->args) { - std::free((char *) arg.name); - std::free((char *) arg.descr); - arg.value.dec_ref(); - } - if (rec->def) { - std::free((char *) rec->def->ml_doc); - delete rec->def; - } - delete rec; - rec = next; - } - } - - /// Main dispatch logic for calls to functions bound using pybind11 - static PyObject *dispatcher(PyObject *self, PyObject *args, PyObject *kwargs) { - /* Iterator over the list of potentially admissible overloads */ - detail::function_record *overloads = (detail::function_record *) PyCapsule_GetPointer(self, nullptr), - *it = overloads; - - /* Need to know how many arguments + keyword arguments there are to pick the right overload */ - size_t nargs = (size_t) PyTuple_GET_SIZE(args), - nkwargs = kwargs ? (size_t) PyDict_Size(kwargs) : 0; - - handle parent = nargs > 0 ? PyTuple_GET_ITEM(args, 0) : nullptr, - result = PYBIND11_TRY_NEXT_OVERLOAD; - try { - for (; it != nullptr; it = it->next) { - auto args_ = reinterpret_borrow(args); - size_t kwargs_consumed = 0; - - /* For each overload: - 1. If the required list of arguments is longer than the - actually provided amount, create a copy of the argument - list and fill in any available keyword/default arguments. - 2. Ensure that all keyword arguments were "consumed" - 3. Call the function call dispatcher (function_record::impl) - */ - size_t nargs_ = nargs; - if (nargs < it->args.size()) { - nargs_ = it->args.size(); - args_ = tuple(nargs_); - for (size_t i = 0; i < nargs; ++i) { - handle item = PyTuple_GET_ITEM(args, i); - PyTuple_SET_ITEM(args_.ptr(), i, item.inc_ref().ptr()); - } - - int arg_ctr = 0; - for (auto const &it2 : it->args) { - int index = arg_ctr++; - if (PyTuple_GET_ITEM(args_.ptr(), index)) - continue; - - handle value; - if (kwargs) - value = PyDict_GetItemString(kwargs, it2.name); - - if (value) - kwargs_consumed++; - else if (it2.value) - value = it2.value; - - if (value) { - PyTuple_SET_ITEM(args_.ptr(), index, value.inc_ref().ptr()); - } else { - kwargs_consumed = (size_t) -1; /* definite failure */ - break; - } - } - } - - try { - if ((kwargs_consumed == nkwargs || it->has_kwargs) && - (nargs_ == it->nargs || it->has_args)) - result = it->impl(it, args_, kwargs, parent); - } catch (reference_cast_error &) { - result = PYBIND11_TRY_NEXT_OVERLOAD; - } - - if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) - break; - } - } catch (error_already_set &e) { - e.restore(); - return nullptr; - } catch (...) { - /* When an exception is caught, give each registered exception - translator a chance to translate it to a Python exception - in reverse order of registration. - - A translator may choose to do one of the following: - - - catch the exception and call PyErr_SetString or PyErr_SetObject - to set a standard (or custom) Python exception, or - - do nothing and let the exception fall through to the next translator, or - - delegate translation to the next translator by throwing a new type of exception. */ - - auto last_exception = std::current_exception(); - auto ®istered_exception_translators = pybind11::detail::get_internals().registered_exception_translators; - for (auto& translator : registered_exception_translators) { - try { - translator(last_exception); - } catch (...) { - last_exception = std::current_exception(); - continue; - } - return nullptr; - } - PyErr_SetString(PyExc_SystemError, "Exception escaped from default exception translator!"); - return nullptr; - } - - if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) { - if (overloads->is_operator) - return handle(Py_NotImplemented).inc_ref().ptr(); - - std::string msg = std::string(overloads->name) + "(): incompatible " + - std::string(overloads->is_constructor ? "constructor" : "function") + - " arguments. The following argument types are supported:\n"; - - int ctr = 0; - for (detail::function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) { - msg += " "+ std::to_string(++ctr) + ". "; - - bool wrote_sig = false; - if (overloads->is_constructor) { - // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as `Object(arg0, ...)` - std::string sig = it2->signature; - size_t start = sig.find('(') + 7; // skip "(self: " - if (start < sig.size()) { - // End at the , for the next argument - size_t end = sig.find(", "), next = end + 2; - size_t ret = sig.rfind(" -> "); - // Or the ), if there is no comma: - if (end >= sig.size()) next = end = sig.find(')'); - if (start < end && next < sig.size()) { - msg.append(sig, start, end - start); - msg += '('; - msg.append(sig, next, ret - next); - wrote_sig = true; - } - } - } - if (!wrote_sig) msg += it2->signature; - - msg += "\n"; - } - msg += "\nInvoked with: "; - auto args_ = reinterpret_borrow(args); - for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) { - msg += pybind11::repr(args_[ti]); - if ((ti + 1) != args_.size() ) - msg += ", "; - } - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return nullptr; - } else if (!result) { - std::string msg = "Unable to convert function return value to a " - "Python type! The signature was\n\t"; - msg += it->signature; - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return nullptr; - } else { - if (overloads->is_constructor) { - /* When a constructor ran successfully, the corresponding - holder type (e.g. std::unique_ptr) must still be initialized. */ - PyObject *inst = PyTuple_GET_ITEM(args, 0); - auto tinfo = detail::get_type_info(Py_TYPE(inst)); - tinfo->init_holder(inst, nullptr); - } - return result.ptr(); - } - } -}; - -/// Wrapper for Python extension modules -class module : public object { -public: - PYBIND11_OBJECT_DEFAULT(module, object, PyModule_Check) - - explicit module(const char *name, const char *doc = nullptr) { - if (!options::show_user_defined_docstrings()) doc = nullptr; -#if PY_MAJOR_VERSION >= 3 - PyModuleDef *def = new PyModuleDef(); - memset(def, 0, sizeof(PyModuleDef)); - def->m_name = name; - def->m_doc = doc; - def->m_size = -1; - Py_INCREF(def); - m_ptr = PyModule_Create(def); -#else - m_ptr = Py_InitModule3(name, nullptr, doc); -#endif - if (m_ptr == nullptr) - pybind11_fail("Internal error in module::module()"); - inc_ref(); - } - - template - module &def(const char *name_, Func &&f, const Extra& ... extra) { - cpp_function func(std::forward(f), name(name_), scope(*this), - sibling(getattr(*this, name_, none())), extra...); - // NB: allow overwriting here because cpp_function sets up a chain with the intention of - // overwriting (and has already checked internally that it isn't overwriting non-functions). - add_object(name_, func, true /* overwrite */); - return *this; - } - - module def_submodule(const char *name, const char *doc = nullptr) { - std::string full_name = std::string(PyModule_GetName(m_ptr)) - + std::string(".") + std::string(name); - auto result = reinterpret_borrow(PyImport_AddModule(full_name.c_str())); - if (doc && options::show_user_defined_docstrings()) - result.attr("__doc__") = pybind11::str(doc); - attr(name) = result; - return result; - } - - static module import(const char *name) { - PyObject *obj = PyImport_ImportModule(name); - if (!obj) - throw import_error("Module \"" + std::string(name) + "\" not found!"); - return reinterpret_steal(obj); - } - - // Adds an object to the module using the given name. Throws if an object with the given name - // already exists. - // - // overwrite should almost always be false: attempting to overwrite objects that pybind11 has - // established will, in most cases, break things. - PYBIND11_NOINLINE void add_object(const char *name, object &obj, bool overwrite = false) { - if (!overwrite && hasattr(*this, name)) - pybind11_fail("Error during initialization: multiple incompatible definitions with name \"" + - std::string(name) + "\""); - - obj.inc_ref(); // PyModule_AddObject() steals a reference - PyModule_AddObject(ptr(), name, obj.ptr()); - } -}; - -NAMESPACE_BEGIN(detail) -extern "C" inline PyObject *get_dict(PyObject *op, void *) { - PyObject *&dict = *_PyObject_GetDictPtr(op); - if (!dict) { - dict = PyDict_New(); - } - Py_XINCREF(dict); - return dict; -} - -extern "C" inline int set_dict(PyObject *op, PyObject *new_dict, void *) { - if (!PyDict_Check(new_dict)) { - PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%.200s'", - Py_TYPE(new_dict)->tp_name); - return -1; - } - PyObject *&dict = *_PyObject_GetDictPtr(op); - Py_INCREF(new_dict); - Py_CLEAR(dict); - dict = new_dict; - return 0; -} - -static PyGetSetDef generic_getset[] = { - {const_cast("__dict__"), get_dict, set_dict, nullptr, nullptr}, - {nullptr, nullptr, nullptr, nullptr, nullptr} -}; - -/// Generic support for creating new Python heap types -class generic_type : public object { - template friend class class_; -public: - PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check) -protected: - void initialize(type_record *rec) { - auto &internals = get_internals(); - auto tindex = std::type_index(*(rec->type)); - - if (get_type_info(*(rec->type))) - pybind11_fail("generic_type: type \"" + std::string(rec->name) + - "\" is already registered!"); - - auto name = reinterpret_steal(PYBIND11_FROM_STRING(rec->name)); - object scope_module; - if (rec->scope) { - if (hasattr(rec->scope, rec->name)) - pybind11_fail("generic_type: cannot initialize type \"" + std::string(rec->name) + - "\": an object with that name is already defined"); - - if (hasattr(rec->scope, "__module__")) { - scope_module = rec->scope.attr("__module__"); - } else if (hasattr(rec->scope, "__name__")) { - scope_module = rec->scope.attr("__name__"); - } - } - -#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 - /* Qualified names for Python >= 3.3 */ - object scope_qualname; - if (rec->scope && hasattr(rec->scope, "__qualname__")) - scope_qualname = rec->scope.attr("__qualname__"); - object ht_qualname; - if (scope_qualname) { - ht_qualname = reinterpret_steal(PyUnicode_FromFormat( - "%U.%U", scope_qualname.ptr(), name.ptr())); - } else { - ht_qualname = name; - } -#endif - - size_t num_bases = rec->bases.size(); - auto bases = tuple(rec->bases); - - std::string full_name = (scope_module ? ((std::string) pybind11::str(scope_module) + "." + rec->name) - : std::string(rec->name)); - - char *tp_doc = nullptr; - if (rec->doc && options::show_user_defined_docstrings()) { - /* Allocate memory for docstring (using PyObject_MALLOC, since - Python will free this later on) */ - size_t size = strlen(rec->doc) + 1; - tp_doc = (char *) PyObject_MALLOC(size); - memcpy((void *) tp_doc, rec->doc, size); - } - - /* Danger zone: from now (and until PyType_Ready), make sure to - issue no Python C API calls which could potentially invoke the - garbage collector (the GC will call type_traverse(), which will in - turn find the newly constructed type in an invalid state) */ - - auto type_holder = reinterpret_steal(PyType_Type.tp_alloc(&PyType_Type, 0)); - auto type = (PyHeapTypeObject*) type_holder.ptr(); - - if (!type_holder || !name) - pybind11_fail(std::string(rec->name) + ": Unable to create type object!"); - - /* Register supplemental type information in C++ dict */ - detail::type_info *tinfo = new detail::type_info(); - tinfo->type = (PyTypeObject *) type; - tinfo->type_size = rec->type_size; - tinfo->init_holder = rec->init_holder; - tinfo->direct_conversions = &internals.direct_conversions[tindex]; - internals.registered_types_cpp[tindex] = tinfo; - internals.registered_types_py[type] = tinfo; - - /* Basic type attributes */ - type->ht_type.tp_name = strdup(full_name.c_str()); - type->ht_type.tp_basicsize = (ssize_t) rec->instance_size; - - if (num_bases > 0) { - type->ht_type.tp_base = (PyTypeObject *) ((object) bases[0]).inc_ref().ptr(); - type->ht_type.tp_bases = bases.release().ptr(); - rec->multiple_inheritance |= num_bases > 1; - } - - type->ht_name = name.release().ptr(); - -#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 - type->ht_qualname = ht_qualname.release().ptr(); -#endif - - /* Supported protocols */ - type->ht_type.tp_as_number = &type->as_number; - type->ht_type.tp_as_sequence = &type->as_sequence; - type->ht_type.tp_as_mapping = &type->as_mapping; - - /* Supported elementary operations */ - type->ht_type.tp_init = (initproc) init; - type->ht_type.tp_new = (newfunc) new_instance; - type->ht_type.tp_dealloc = rec->dealloc; - - /* Support weak references (needed for the keep_alive feature) */ - type->ht_type.tp_weaklistoffset = offsetof(instance_essentials, weakrefs); - - /* Flags */ - type->ht_type.tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; -#if PY_MAJOR_VERSION < 3 - type->ht_type.tp_flags |= Py_TPFLAGS_CHECKTYPES; -#endif - type->ht_type.tp_flags &= ~Py_TPFLAGS_HAVE_GC; - - /* Support dynamic attributes */ - if (rec->dynamic_attr) { - type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_GC; - type->ht_type.tp_dictoffset = type->ht_type.tp_basicsize; // place the dict at the end - type->ht_type.tp_basicsize += sizeof(PyObject *); // and allocate enough space for it - type->ht_type.tp_getset = generic_getset; - type->ht_type.tp_traverse = traverse; - type->ht_type.tp_clear = clear; - } - - type->ht_type.tp_doc = tp_doc; - - if (PyType_Ready(&type->ht_type) < 0) - pybind11_fail(std::string(rec->name) + ": PyType_Ready failed (" + - detail::error_string() + ")!"); - - m_ptr = type_holder.ptr(); - - if (scope_module) // Needed by pydoc - attr("__module__") = scope_module; - - /* Register type with the parent scope */ - if (rec->scope) - rec->scope.attr(handle(type->ht_name)) = *this; - - if (rec->multiple_inheritance) - mark_parents_nonsimple(&type->ht_type); - - type_holder.release(); - } - - /// Helper function which tags all parents of a type using mult. inheritance - void mark_parents_nonsimple(PyTypeObject *value) { - auto t = reinterpret_borrow(value->tp_bases); - for (handle h : t) { - auto tinfo2 = get_type_info((PyTypeObject *) h.ptr()); - if (tinfo2) - tinfo2->simple_type = false; - mark_parents_nonsimple((PyTypeObject *) h.ptr()); - } - } - - /// Allocate a metaclass on demand (for static properties) - handle metaclass() { - auto &ht_type = ((PyHeapTypeObject *) m_ptr)->ht_type; - auto &ob_type = PYBIND11_OB_TYPE(ht_type); - - if (ob_type == &PyType_Type) { - std::string name_ = std::string(ht_type.tp_name) + "__Meta"; -#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 - auto ht_qualname = reinterpret_steal(PyUnicode_FromFormat("%U__Meta", attr("__qualname__").ptr())); -#endif - auto name = reinterpret_steal(PYBIND11_FROM_STRING(name_.c_str())); - auto type_holder = reinterpret_steal(PyType_Type.tp_alloc(&PyType_Type, 0)); - if (!type_holder || !name) - pybind11_fail("generic_type::metaclass(): unable to create type object!"); - - auto type = (PyHeapTypeObject*) type_holder.ptr(); - type->ht_name = name.release().ptr(); - -#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 - /* Qualified names for Python >= 3.3 */ - type->ht_qualname = ht_qualname.release().ptr(); -#endif - type->ht_type.tp_name = strdup(name_.c_str()); - type->ht_type.tp_base = ob_type; - type->ht_type.tp_flags |= (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE) & - ~Py_TPFLAGS_HAVE_GC; - - if (PyType_Ready(&type->ht_type) < 0) - pybind11_fail("generic_type::metaclass(): PyType_Ready failed!"); - - ob_type = (PyTypeObject *) type_holder.release().ptr(); - } - return handle((PyObject *) ob_type); - } - - static int init(void *self, PyObject *, PyObject *) { - std::string msg = std::string(Py_TYPE(self)->tp_name) + ": No constructor defined!"; - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return -1; - } - - static PyObject *new_instance(PyTypeObject *type, PyObject *, PyObject *) { - instance *self = (instance *) PyType_GenericAlloc((PyTypeObject *) type, 0); - auto tinfo = detail::get_type_info(type); - self->value = ::operator new(tinfo->type_size); - self->owned = true; - self->holder_constructed = false; - detail::get_internals().registered_instances.emplace(self->value, (PyObject *) self); - return (PyObject *) self; - } - - static void dealloc(instance *self) { - if (self->value) { - auto instance_type = Py_TYPE(self); - auto ®istered_instances = detail::get_internals().registered_instances; - auto range = registered_instances.equal_range(self->value); - bool found = false; - for (auto it = range.first; it != range.second; ++it) { - if (instance_type == Py_TYPE(it->second)) { - registered_instances.erase(it); - found = true; - break; - } - } - if (!found) - pybind11_fail("generic_type::dealloc(): Tried to deallocate unregistered instance!"); - - if (self->weakrefs) - PyObject_ClearWeakRefs((PyObject *) self); - - PyObject **dict_ptr = _PyObject_GetDictPtr((PyObject *) self); - if (dict_ptr) { - Py_CLEAR(*dict_ptr); - } - } - Py_TYPE(self)->tp_free((PyObject*) self); - } - - static int traverse(PyObject *op, visitproc visit, void *arg) { - PyObject *&dict = *_PyObject_GetDictPtr(op); - Py_VISIT(dict); - return 0; - } - - static int clear(PyObject *op) { - PyObject *&dict = *_PyObject_GetDictPtr(op); - Py_CLEAR(dict); - return 0; - } - - void install_buffer_funcs( - buffer_info *(*get_buffer)(PyObject *, void *), - void *get_buffer_data) { - PyHeapTypeObject *type = (PyHeapTypeObject*) m_ptr; - type->ht_type.tp_as_buffer = &type->as_buffer; -#if PY_MAJOR_VERSION < 3 - type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; -#endif - type->as_buffer.bf_getbuffer = getbuffer; - type->as_buffer.bf_releasebuffer = releasebuffer; - auto tinfo = detail::get_type_info(&type->ht_type); - tinfo->get_buffer = get_buffer; - tinfo->get_buffer_data = get_buffer_data; - } - - static int getbuffer(PyObject *obj, Py_buffer *view, int flags) { - auto tinfo = detail::get_type_info(Py_TYPE(obj)); - if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer) { - PyErr_SetString(PyExc_BufferError, "generic_type::getbuffer(): Internal error"); - return -1; - } - memset(view, 0, sizeof(Py_buffer)); - buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data); - view->obj = obj; - view->ndim = 1; - view->internal = info; - view->buf = info->ptr; - view->itemsize = (ssize_t) info->itemsize; - view->len = view->itemsize; - for (auto s : info->shape) - view->len *= s; - if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) - view->format = const_cast(info->format.c_str()); - if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { - view->ndim = (int) info->ndim; - view->strides = (ssize_t *) &info->strides[0]; - view->shape = (ssize_t *) &info->shape[0]; - } - Py_INCREF(view->obj); - return 0; - } - - static void releasebuffer(PyObject *, Py_buffer *view) { delete (buffer_info *) view->internal; } -}; - -NAMESPACE_END(detail) - -template -class class_ : public detail::generic_type { - template using is_holder = detail::is_holder_type; - template using is_subtype = detail::bool_constant::value && !std::is_same::value>; - template using is_base = detail::bool_constant::value && !std::is_same::value>; - template using is_valid_class_option = - detail::bool_constant< - is_holder::value || - is_subtype::value || - is_base::value - >; - -public: - using type = type_; - using type_alias = detail::first_of_t; - constexpr static bool has_alias = !std::is_void::value; - using holder_type = detail::first_of_t, options...>; - using instance_type = detail::instance; - - static_assert(detail::all_of_t::value, - "Unknown/invalid class_ template parameters provided"); - - PYBIND11_OBJECT(class_, generic_type, PyType_Check) - - template - class_(handle scope, const char *name, const Extra &... extra) { - detail::type_record record; - record.scope = scope; - record.name = name; - record.type = &typeid(type); - record.type_size = sizeof(detail::conditional_t); - record.instance_size = sizeof(instance_type); - record.init_holder = init_holder; - record.dealloc = dealloc; - - /* Register base classes specified via template arguments to class_, if any */ - bool unused[] = { (add_base(record), false)..., false }; - (void) unused; - - /* Process optional arguments, if any */ - detail::process_attributes::init(extra..., &record); - - detail::generic_type::initialize(&record); - - if (has_alias) { - auto &instances = pybind11::detail::get_internals().registered_types_cpp; - instances[std::type_index(typeid(type_alias))] = instances[std::type_index(typeid(type))]; - } - } - - template ::value, int> = 0> - static void add_base(detail::type_record &rec) { - rec.add_base(&typeid(Base), [](void *src) -> void * { - return static_cast(reinterpret_cast(src)); - }); - } - - template ::value, int> = 0> - static void add_base(detail::type_record &) { } - - template - class_ &def(const char *name_, Func&& f, const Extra&... extra) { - cpp_function cf(std::forward(f), name(name_), is_method(*this), - sibling(getattr(*this, name_, none())), extra...); - attr(cf.name()) = cf; - return *this; - } - - template class_ & - def_static(const char *name_, Func f, const Extra&... extra) { - cpp_function cf(std::forward(f), name(name_), scope(*this), - sibling(getattr(*this, name_, none())), extra...); - attr(cf.name()) = cf; - return *this; - } - - template - class_ &def(const detail::op_ &op, const Extra&... extra) { - op.execute(*this, extra...); - return *this; - } - - template - class_ & def_cast(const detail::op_ &op, const Extra&... extra) { - op.execute_cast(*this, extra...); - return *this; - } - - template - class_ &def(const detail::init &init, const Extra&... extra) { - init.execute(*this, extra...); - return *this; - } - - template - class_ &def(const detail::init_alias &init, const Extra&... extra) { - init.execute(*this, extra...); - return *this; - } - - template class_& def_buffer(Func &&func) { - struct capture { Func func; }; - capture *ptr = new capture { std::forward(func) }; - install_buffer_funcs([](PyObject *obj, void *ptr) -> buffer_info* { - detail::type_caster caster; - if (!caster.load(obj, false)) - return nullptr; - return new buffer_info(((capture *) ptr)->func(caster)); - }, ptr); - return *this; - } - - template - class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) { - cpp_function fget([pm](const C &c) -> const D &{ return c.*pm; }, is_method(*this)), - fset([pm](C &c, const D &value) { c.*pm = value; }, is_method(*this)); - def_property(name, fget, fset, return_value_policy::reference_internal, extra...); - return *this; - } - - template - class_ &def_readonly(const char *name, const D C::*pm, const Extra& ...extra) { - cpp_function fget([pm](const C &c) -> const D &{ return c.*pm; }, is_method(*this)); - def_property_readonly(name, fget, return_value_policy::reference_internal, extra...); - return *this; - } - - template - class_ &def_readwrite_static(const char *name, D *pm, const Extra& ...extra) { - cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)), - fset([pm](object, const D &value) { *pm = value; }, scope(*this)); - def_property_static(name, fget, fset, return_value_policy::reference, extra...); - return *this; - } - - template - class_ &def_readonly_static(const char *name, const D *pm, const Extra& ...extra) { - cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)); - def_property_readonly_static(name, fget, return_value_policy::reference, extra...); - return *this; - } - - /// Uses return_value_policy::reference_internal by default - template - class_ &def_property_readonly(const char *name, const Getter &fget, const Extra& ...extra) { - return def_property_readonly(name, cpp_function(fget), return_value_policy::reference_internal, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property_readonly(const char *name, const cpp_function &fget, const Extra& ...extra) { - return def_property(name, fget, cpp_function(), extra...); - } - - /// Uses return_value_policy::reference by default - template - class_ &def_property_readonly_static(const char *name, const Getter &fget, const Extra& ...extra) { - return def_property_readonly_static(name, cpp_function(fget), return_value_policy::reference, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property_readonly_static(const char *name, const cpp_function &fget, const Extra& ...extra) { - return def_property_static(name, fget, cpp_function(), extra...); - } - - /// Uses return_value_policy::reference_internal by default - template - class_ &def_property(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { - return def_property(name, cpp_function(fget), fset, return_value_policy::reference_internal, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { - return def_property_static(name, fget, fset, is_method(*this), extra...); - } - - /// Uses return_value_policy::reference by default - template - class_ &def_property_static(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { - return def_property_static(name, cpp_function(fget), fset, return_value_policy::reference, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property_static(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { - auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset); - char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific documentation string */ - detail::process_attributes::init(extra..., rec_fget); - if (rec_fget->doc && rec_fget->doc != doc_prev) { - free(doc_prev); - rec_fget->doc = strdup(rec_fget->doc); - } - if (rec_fset) { - doc_prev = rec_fset->doc; - detail::process_attributes::init(extra..., rec_fset); - if (rec_fset->doc && rec_fset->doc != doc_prev) { - free(doc_prev); - rec_fset->doc = strdup(rec_fset->doc); - } - } - pybind11::str doc_obj = pybind11::str((rec_fget->doc && pybind11::options::show_user_defined_docstrings()) ? rec_fget->doc : ""); - const auto property = reinterpret_steal( - PyObject_CallFunctionObjArgs((PyObject *) &PyProperty_Type, fget.ptr() ? fget.ptr() : Py_None, - fset.ptr() ? fset.ptr() : Py_None, Py_None, doc_obj.ptr(), nullptr)); - if (rec_fget->is_method && rec_fget->scope) - attr(name) = property; - else - metaclass().attr(name) = property; - return *this; - } - -private: - /// Initialize holder object, variant 1: object derives from enable_shared_from_this - template - static void init_holder_helper(instance_type *inst, const holder_type * /* unused */, const std::enable_shared_from_this * /* dummy */) { - try { - new (&inst->holder) holder_type(std::static_pointer_cast(inst->value->shared_from_this())); - } catch (const std::bad_weak_ptr &) { - new (&inst->holder) holder_type(inst->value); - } - inst->holder_constructed = true; - } - - /// Initialize holder object, variant 2: try to construct from existing holder object, if possible - template ::value, int> = 0> - static void init_holder_helper(instance_type *inst, const holder_type *holder_ptr, const void * /* dummy */) { - if (holder_ptr) - new (&inst->holder) holder_type(*holder_ptr); - else - new (&inst->holder) holder_type(inst->value); - inst->holder_constructed = true; - } - - /// Initialize holder object, variant 3: holder is not copy constructible (e.g. unique_ptr), always initialize from raw pointer - template ::value, int> = 0> - static void init_holder_helper(instance_type *inst, const holder_type * /* unused */, const void * /* dummy */) { - if (inst->owned) { - new (&inst->holder) holder_type(inst->value); - inst->holder_constructed = true; - } - } - - /// Initialize holder object of an instance, possibly given a pointer to an existing holder - static void init_holder(PyObject *inst_, const void *holder_ptr) { - auto inst = (instance_type *) inst_; - init_holder_helper(inst, (const holder_type *) holder_ptr, inst->value); - } - - static void dealloc(PyObject *inst_) { - instance_type *inst = (instance_type *) inst_; - if (inst->holder_constructed) - inst->holder.~holder_type(); - else if (inst->owned) - ::operator delete(inst->value); - - generic_type::dealloc((detail::instance *) inst); - } - - static detail::function_record *get_function_record(handle h) { - h = detail::get_function(h); - return h ? (detail::function_record *) reinterpret_borrow(PyCFunction_GetSelf(h.ptr())) - : nullptr; - } -}; - -/// Binds C++ enumerations and enumeration classes to Python -template class enum_ : public class_ { -public: - using class_::def; - using Scalar = typename std::underlying_type::type; - template using arithmetic_tag = std::is_same; - - template - enum_(const handle &scope, const char *name, const Extra&... extra) - : class_(scope, name, extra...), m_parent(scope) { - - constexpr bool is_arithmetic = - !std::is_same, - void>::value; - - auto entries = new std::unordered_map(); - def("__repr__", [name, entries](Type value) -> std::string { - auto it = entries->find((Scalar) value); - return std::string(name) + "." + - ((it == entries->end()) ? std::string("???") - : std::string(it->second)); - }); - def("__init__", [](Type& value, Scalar i) { value = (Type)i; }); - def("__init__", [](Type& value, Scalar i) { new (&value) Type((Type) i); }); - def("__int__", [](Type value) { return (Scalar) value; }); - def("__eq__", [](const Type &value, Type *value2) { return value2 && value == *value2; }); - def("__ne__", [](const Type &value, Type *value2) { return !value2 || value != *value2; }); - if (is_arithmetic) { - def("__lt__", [](const Type &value, Type *value2) { return value2 && value < *value2; }); - def("__gt__", [](const Type &value, Type *value2) { return value2 && value > *value2; }); - def("__le__", [](const Type &value, Type *value2) { return value2 && value <= *value2; }); - def("__ge__", [](const Type &value, Type *value2) { return value2 && value >= *value2; }); - } - if (std::is_convertible::value) { - // Don't provide comparison with the underlying type if the enum isn't convertible, - // i.e. if Type is a scoped enum, mirroring the C++ behaviour. (NB: we explicitly - // convert Type to Scalar below anyway because this needs to compile). - def("__eq__", [](const Type &value, Scalar value2) { return (Scalar) value == value2; }); - def("__ne__", [](const Type &value, Scalar value2) { return (Scalar) value != value2; }); - if (is_arithmetic) { - def("__lt__", [](const Type &value, Scalar value2) { return (Scalar) value < value2; }); - def("__gt__", [](const Type &value, Scalar value2) { return (Scalar) value > value2; }); - def("__le__", [](const Type &value, Scalar value2) { return (Scalar) value <= value2; }); - def("__ge__", [](const Type &value, Scalar value2) { return (Scalar) value >= value2; }); - def("__invert__", [](const Type &value) { return ~((Scalar) value); }); - def("__and__", [](const Type &value, Scalar value2) { return (Scalar) value & value2; }); - def("__or__", [](const Type &value, Scalar value2) { return (Scalar) value | value2; }); - def("__xor__", [](const Type &value, Scalar value2) { return (Scalar) value ^ value2; }); - def("__rand__", [](const Type &value, Scalar value2) { return (Scalar) value & value2; }); - def("__ror__", [](const Type &value, Scalar value2) { return (Scalar) value | value2; }); - def("__rxor__", [](const Type &value, Scalar value2) { return (Scalar) value ^ value2; }); - def("__and__", [](const Type &value, const Type &value2) { return (Scalar) value & (Scalar) value2; }); - def("__or__", [](const Type &value, const Type &value2) { return (Scalar) value | (Scalar) value2; }); - def("__xor__", [](const Type &value, const Type &value2) { return (Scalar) value ^ (Scalar) value2; }); - } - } - def("__hash__", [](const Type &value) { return (Scalar) value; }); - // Pickling and unpickling -- needed for use with the 'multiprocessing' module - def("__getstate__", [](const Type &value) { return pybind11::make_tuple((Scalar) value); }); - def("__setstate__", [](Type &p, tuple t) { new (&p) Type((Type) t[0].cast()); }); - m_entries = entries; - } - - /// Export enumeration entries into the parent scope - enum_ &export_values() { - PyObject *dict = ((PyTypeObject *) this->m_ptr)->tp_dict; - PyObject *key, *value; - ssize_t pos = 0; - while (PyDict_Next(dict, &pos, &key, &value)) - if (PyObject_IsInstance(value, this->m_ptr)) - m_parent.attr(key) = value; - return *this; - } - - /// Add an enumeration entry - enum_& value(char const* name, Type value) { - this->attr(name) = pybind11::cast(value, return_value_policy::copy); - (*m_entries)[(Scalar) value] = name; - return *this; - } -private: - std::unordered_map *m_entries; - handle m_parent; -}; - -NAMESPACE_BEGIN(detail) -template struct init { - template = 0> - static void execute(Class &cl, const Extra&... extra) { - using Base = typename Class::type; - /// Function which calls a specific C++ in-place constructor - cl.def("__init__", [](Base *self_, Args... args) { new (self_) Base(args...); }, extra...); - } - - template ::value, int> = 0> - static void execute(Class &cl, const Extra&... extra) { - using Base = typename Class::type; - using Alias = typename Class::type_alias; - handle cl_type = cl; - cl.def("__init__", [cl_type](handle self_, Args... args) { - if (self_.get_type() == cl_type) - new (self_.cast()) Base(args...); - else - new (self_.cast()) Alias(args...); - }, extra...); - } - - template ::value, int> = 0> - static void execute(Class &cl, const Extra&... extra) { - init_alias::execute(cl, extra...); - } -}; -template struct init_alias { - template ::value, int> = 0> - static void execute(Class &cl, const Extra&... extra) { - using Alias = typename Class::type_alias; - cl.def("__init__", [](Alias *self_, Args... args) { new (self_) Alias(args...); }, extra...); - } -}; - - -inline void keep_alive_impl(handle nurse, handle patient) { - /* Clever approach based on weak references taken from Boost.Python */ - if (!nurse || !patient) - pybind11_fail("Could not activate keep_alive!"); - - if (patient.is_none() || nurse.is_none()) - return; /* Nothing to keep alive or nothing to be kept alive by */ - - cpp_function disable_lifesupport( - [patient](handle weakref) { patient.dec_ref(); weakref.dec_ref(); }); - - weakref wr(nurse, disable_lifesupport); - - patient.inc_ref(); /* reference patient and leak the weak reference */ - (void) wr.release(); -} - -PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, handle args, handle ret) { - handle nurse (Nurse > 0 ? PyTuple_GetItem(args.ptr(), Nurse - 1) : ret.ptr()); - handle patient(Patient > 0 ? PyTuple_GetItem(args.ptr(), Patient - 1) : ret.ptr()); - - keep_alive_impl(nurse, patient); -} - -template -struct iterator_state { - Iterator it; - Sentinel end; - bool first; -}; - -NAMESPACE_END(detail) - -template detail::init init() { return detail::init(); } -template detail::init_alias init_alias() { return detail::init_alias(); } - -template ()), - typename... Extra> -iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) { - typedef detail::iterator_state state; - - if (!detail::get_type_info(typeid(state), false)) { - class_(handle(), "iterator") - .def("__iter__", [](state &s) -> state& { return s; }) - .def("__next__", [](state &s) -> ValueType { - if (!s.first) - ++s.it; - else - s.first = false; - if (s.it == s.end) - throw stop_iteration(); - return *s.it; - }, std::forward(extra)..., Policy); - } - - return (iterator) cast(state { first, last, true }); -} - -template ()).first), - typename... Extra> -iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) { - typedef detail::iterator_state state; - - if (!detail::get_type_info(typeid(state), false)) { - class_(handle(), "iterator") - .def("__iter__", [](state &s) -> state& { return s; }) - .def("__next__", [](state &s) -> KeyType { - if (!s.first) - ++s.it; - else - s.first = false; - if (s.it == s.end) - throw stop_iteration(); - return (*s.it).first; - }, std::forward(extra)..., Policy); - } - - return (iterator) cast(state { first, last, true }); -} - -template iterator make_iterator(Type &value, Extra&&... extra) { - return make_iterator(std::begin(value), std::end(value), extra...); -} - -template iterator make_key_iterator(Type &value, Extra&&... extra) { - return make_key_iterator(std::begin(value), std::end(value), extra...); -} - -template void implicitly_convertible() { - auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * { - if (!detail::type_caster().load(obj, false)) - return nullptr; - tuple args(1); - args[0] = obj; - PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr); - if (result == nullptr) - PyErr_Clear(); - return result; - }; - - if (auto tinfo = detail::get_type_info(typeid(OutputType))) - tinfo->implicit_conversions.push_back(implicit_caster); - else - pybind11_fail("implicitly_convertible: Unable to find type " + type_id()); -} - -template -void register_exception_translator(ExceptionTranslator&& translator) { - detail::get_internals().registered_exception_translators.push_front( - std::forward(translator)); -} - -/* Wrapper to generate a new Python exception type. - * - * This should only be used with PyErr_SetString for now. - * It is not (yet) possible to use as a py::base. - * Template type argument is reserved for future use. - */ -template -class exception : public object { -public: - exception(handle scope, const char *name, PyObject *base = PyExc_Exception) { - std::string full_name = scope.attr("__name__").cast() + - std::string(".") + name; - m_ptr = PyErr_NewException((char *) full_name.c_str(), base, NULL); - if (hasattr(scope, name)) - pybind11_fail("Error during initialization: multiple incompatible " - "definitions with name \"" + std::string(name) + "\""); - scope.attr(name) = *this; - } - - // Sets the current python exception to this exception object with the given message - void operator()(const char *message) { - PyErr_SetString(m_ptr, message); - } -}; - -/** Registers a Python exception in `m` of the given `name` and installs an exception translator to - * translate the C++ exception to the created Python exception using the exceptions what() method. - * This is intended for simple exception translations; for more complex translation, register the - * exception object and translator directly. - */ -template -exception ®ister_exception(handle scope, - const char *name, - PyObject *base = PyExc_Exception) { - static exception ex(scope, name, base); - register_exception_translator([](std::exception_ptr p) { - if (!p) return; - try { - std::rethrow_exception(p); - } catch (const CppException &e) { - ex(e.what()); - } - }); - return ex; -} - -NAMESPACE_BEGIN(detail) -PYBIND11_NOINLINE inline void print(tuple args, dict kwargs) { - auto strings = tuple(args.size()); - for (size_t i = 0; i < args.size(); ++i) { - strings[i] = str(args[i]); - } - auto sep = kwargs.contains("sep") ? kwargs["sep"] : cast(" "); - auto line = sep.attr("join")(strings); - - object file; - if (kwargs.contains("file")) { - file = kwargs["file"].cast(); - } else { - try { - file = module::import("sys").attr("stdout"); - } catch (const import_error &) { - /* If print() is called from code that is executed as - part of garbage collection during interpreter shutdown, - importing 'sys' can fail. Give up rather than crashing the - interpreter in this case. */ - return; - } - } - - auto write = file.attr("write"); - write(line); - write(kwargs.contains("end") ? kwargs["end"] : cast("\n")); - - if (kwargs.contains("flush") && kwargs["flush"].cast()) - file.attr("flush")(); -} -NAMESPACE_END(detail) - -template -void print(Args &&...args) { - auto c = detail::collect_arguments(std::forward(args)...); - detail::print(c.args(), c.kwargs()); -} - -#if defined(WITH_THREAD) - -/* The functions below essentially reproduce the PyGILState_* API using a RAII - * pattern, but there are a few important differences: - * - * 1. When acquiring the GIL from an non-main thread during the finalization - * phase, the GILState API blindly terminates the calling thread, which - * is often not what is wanted. This API does not do this. - * - * 2. The gil_scoped_release function can optionally cut the relationship - * of a PyThreadState and its associated thread, which allows moving it to - * another thread (this is a fairly rare/advanced use case). - * - * 3. The reference count of an acquired thread state can be controlled. This - * can be handy to prevent cases where callbacks issued from an external - * thread would otherwise constantly construct and destroy thread state data - * structures. - * - * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an - * example which uses features 2 and 3 to migrate the Python thread of - * execution to another thread (to run the event loop on the original thread, - * in this case). - */ - -class gil_scoped_acquire { -public: - PYBIND11_NOINLINE gil_scoped_acquire() { - auto const &internals = detail::get_internals(); - tstate = (PyThreadState *) PyThread_get_key_value(internals.tstate); - - if (!tstate) { - tstate = PyThreadState_New(internals.istate); - #if !defined(NDEBUG) - if (!tstate) - pybind11_fail("scoped_acquire: could not create thread state!"); - #endif - tstate->gilstate_counter = 0; - #if PY_MAJOR_VERSION < 3 - PyThread_delete_key_value(internals.tstate); - #endif - PyThread_set_key_value(internals.tstate, tstate); - } else { - release = detail::get_thread_state_unchecked() != tstate; - } - - if (release) { - /* Work around an annoying assertion in PyThreadState_Swap */ - #if defined(Py_DEBUG) - PyInterpreterState *interp = tstate->interp; - tstate->interp = nullptr; - #endif - PyEval_AcquireThread(tstate); - #if defined(Py_DEBUG) - tstate->interp = interp; - #endif - } - - inc_ref(); - } - - void inc_ref() { - ++tstate->gilstate_counter; - } - - PYBIND11_NOINLINE void dec_ref() { - --tstate->gilstate_counter; - #if !defined(NDEBUG) - if (detail::get_thread_state_unchecked() != tstate) - pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!"); - if (tstate->gilstate_counter < 0) - pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!"); - #endif - if (tstate->gilstate_counter == 0) { - #if !defined(NDEBUG) - if (!release) - pybind11_fail("scoped_acquire::dec_ref(): internal error!"); - #endif - PyThreadState_Clear(tstate); - PyThreadState_DeleteCurrent(); - PyThread_delete_key_value(detail::get_internals().tstate); - release = false; - } - } - - PYBIND11_NOINLINE ~gil_scoped_acquire() { - dec_ref(); - if (release) - PyEval_SaveThread(); - } -private: - PyThreadState *tstate = nullptr; - bool release = true; -}; - -class gil_scoped_release { -public: - explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) { - tstate = PyEval_SaveThread(); - if (disassoc) { - auto key = detail::get_internals().tstate; - #if PY_MAJOR_VERSION < 3 - PyThread_delete_key_value(key); - #else - PyThread_set_key_value(key, nullptr); - #endif - } - } - ~gil_scoped_release() { - if (!tstate) - return; - PyEval_RestoreThread(tstate); - if (disassoc) { - auto key = detail::get_internals().tstate; - #if PY_MAJOR_VERSION < 3 - PyThread_delete_key_value(key); - #endif - PyThread_set_key_value(key, tstate); - } - } -private: - PyThreadState *tstate; - bool disassoc; -}; -#else -class gil_scoped_acquire { }; -class gil_scoped_release { }; -#endif - -inline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) { - handle py_object = detail::get_object_handle(this_ptr, this_type); - if (!py_object) - return function(); - handle type = py_object.get_type(); - auto key = std::make_pair(type.ptr(), name); - - /* Cache functions that aren't overloaded in Python to avoid - many costly Python dictionary lookups below */ - auto &cache = detail::get_internals().inactive_overload_cache; - if (cache.find(key) != cache.end()) - return function(); - - function overload = getattr(py_object, name, function()); - if (overload.is_cpp_function()) { - cache.insert(key); - return function(); - } - - /* Don't call dispatch code if invoked from overridden function */ - PyFrameObject *frame = PyThreadState_Get()->frame; - if (frame && (std::string) str(frame->f_code->co_name) == name && - frame->f_code->co_argcount > 0) { - PyFrame_FastToLocals(frame); - PyObject *self_caller = PyDict_GetItem( - frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0)); - if (self_caller == py_object.ptr()) - return function(); - } - return overload; -} - -template function get_overload(const T *this_ptr, const char *name) { - auto tinfo = detail::get_type_info(typeid(T)); - return tinfo ? get_type_overload(this_ptr, tinfo, name) : function(); -} - -#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) { \ - pybind11::gil_scoped_acquire gil; \ - pybind11::function overload = pybind11::get_overload(static_cast(this), name); \ - if (overload) { \ - auto o = overload(__VA_ARGS__); \ - if (pybind11::detail::cast_is_temporary_value_reference::value) { \ - static pybind11::detail::overload_caster_t caster; \ - return pybind11::detail::cast_ref(std::move(o), caster); \ - } \ - else return pybind11::detail::cast_safe(std::move(o)); \ - } \ - } - -#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, cname, name, __VA_ARGS__) \ - return cname::fn(__VA_ARGS__) - -#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, cname, name, __VA_ARGS__) \ - pybind11::pybind11_fail("Tried to call pure virtual function \"" #cname "::" name "\""); - -#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \ - PYBIND11_OVERLOAD_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) - -#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \ - PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) - -NAMESPACE_END(pybind11) - -#if defined(_MSC_VER) -# pragma warning(pop) -#elif defined(__INTEL_COMPILER) -/* Leave ignored warnings on */ -#elif defined(__GNUG__) && !defined(__clang__) -# pragma GCC diagnostic pop -#endif diff --git a/stormpy/resources/pybind11/include/pybind11/pytypes.h b/stormpy/resources/pybind11/include/pybind11/pytypes.h deleted file mode 100644 index d078d58e0..000000000 --- a/stormpy/resources/pybind11/include/pybind11/pytypes.h +++ /dev/null @@ -1,899 +0,0 @@ -/* - pybind11/typeid.h: Convenience wrapper classes for basic Python types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "common.h" -#include -#include - -NAMESPACE_BEGIN(pybind11) - -/* A few forward declarations */ -class handle; class object; -class str; class iterator; -struct arg; struct arg_v; - -NAMESPACE_BEGIN(detail) -class args_proxy; -inline bool isinstance_generic(handle obj, const std::type_info &tp); - -// Accessor forward declarations -template class accessor; -namespace accessor_policies { - struct obj_attr; - struct str_attr; - struct generic_item; - struct sequence_item; - struct list_item; - struct tuple_item; -} -using obj_attr_accessor = accessor; -using str_attr_accessor = accessor; -using item_accessor = accessor; -using sequence_accessor = accessor; -using list_accessor = accessor; -using tuple_accessor = accessor; - -/// Tag and check to identify a class which implements the Python object API -class pyobject_tag { }; -template using is_pyobject = std::is_base_of; - -/// Mixin which adds common functions to handle, object and various accessors. -/// The only requirement for `Derived` is to implement `PyObject *Derived::ptr() const`. -template -class object_api : public pyobject_tag { - const Derived &derived() const { return static_cast(*this); } - -public: - iterator begin() const; - iterator end() const; - item_accessor operator[](handle key) const; - item_accessor operator[](const char *key) const; - obj_attr_accessor attr(handle key) const; - str_attr_accessor attr(const char *key) const; - args_proxy operator*() const; - template bool contains(T &&key) const; - - template - object operator()(Args &&...args) const; - template - PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)") - object call(Args&&... args) const; - - bool is_none() const { return derived().ptr() == Py_None; } - PYBIND11_DEPRECATED("Instead of obj.str(), use py::str(obj)") - pybind11::str str() const; - - int ref_count() const { return static_cast(Py_REFCNT(derived().ptr())); } - handle get_type() const; -}; - -NAMESPACE_END(detail) - -/// Holds a reference to a Python object (no reference counting) -class handle : public detail::object_api { -public: - handle() = default; - handle(PyObject *ptr) : m_ptr(ptr) { } - - PyObject *ptr() const { return m_ptr; } - PyObject *&ptr() { return m_ptr; } - const handle& inc_ref() const { Py_XINCREF(m_ptr); return *this; } - const handle& dec_ref() const { Py_XDECREF(m_ptr); return *this; } - - template T cast() const; - explicit operator bool() const { return m_ptr != nullptr; } - bool operator==(const handle &h) const { return m_ptr == h.m_ptr; } - bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; } - PYBIND11_DEPRECATED("Use handle::operator bool() instead") - bool check() const { return m_ptr != nullptr; } -protected: - PyObject *m_ptr = nullptr; -}; - -/// Holds a reference to a Python object (with reference counting) -class object : public handle { -public: - object() = default; - PYBIND11_DEPRECATED("Use reinterpret_borrow() or reinterpret_steal()") - object(handle h, bool is_borrowed) : handle(h) { if (is_borrowed) inc_ref(); } - object(const object &o) : handle(o) { inc_ref(); } - object(object &&other) noexcept { m_ptr = other.m_ptr; other.m_ptr = nullptr; } - ~object() { dec_ref(); } - - handle release() { - PyObject *tmp = m_ptr; - m_ptr = nullptr; - return handle(tmp); - } - - object& operator=(const object &other) { - other.inc_ref(); - dec_ref(); - m_ptr = other.m_ptr; - return *this; - } - - object& operator=(object &&other) noexcept { - if (this != &other) { - handle temp(m_ptr); - m_ptr = other.m_ptr; - other.m_ptr = nullptr; - temp.dec_ref(); - } - return *this; - } - - // Calling cast() on an object lvalue just copies (via handle::cast) - template T cast() const &; - // Calling on an object rvalue does a move, if needed and/or possible - template T cast() &&; - -protected: - // Tags for choosing constructors from raw PyObject * - struct borrowed_t { }; static constexpr borrowed_t borrowed{}; - struct stolen_t { }; static constexpr stolen_t stolen{}; - - template friend T reinterpret_borrow(handle); - template friend T reinterpret_steal(handle); - -public: - // Only accessible from derived classes and the reinterpret_* functions - object(handle h, borrowed_t) : handle(h) { inc_ref(); } - object(handle h, stolen_t) : handle(h) { } -}; - -/** The following functions don't do any kind of conversion, they simply declare - that a PyObject is a certain type and borrow or steal the reference. */ -template T reinterpret_borrow(handle h) { return {h, object::borrowed}; } -template T reinterpret_steal(handle h) { return {h, object::stolen}; } - -/// Check if `obj` is an instance of type `T` -template ::value, int> = 0> -bool isinstance(handle obj) { return T::_check(obj); } - -template ::value, int> = 0> -bool isinstance(handle obj) { return detail::isinstance_generic(obj, typeid(T)); } - -template <> inline bool isinstance(handle obj) = delete; -template <> inline bool isinstance(handle obj) { return obj.ptr() != nullptr; } - -inline bool hasattr(handle obj, handle name) { - return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1; -} - -inline bool hasattr(handle obj, const char *name) { - return PyObject_HasAttrString(obj.ptr(), name) == 1; -} - -inline object getattr(handle obj, handle name) { - PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr()); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); -} - -inline object getattr(handle obj, const char *name) { - PyObject *result = PyObject_GetAttrString(obj.ptr(), name); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); -} - -inline object getattr(handle obj, handle name, handle default_) { - if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) { - return reinterpret_steal(result); - } else { - PyErr_Clear(); - return reinterpret_borrow(default_); - } -} - -inline object getattr(handle obj, const char *name, handle default_) { - if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) { - return reinterpret_steal(result); - } else { - PyErr_Clear(); - return reinterpret_borrow(default_); - } -} - -inline void setattr(handle obj, handle name, handle value) { - if (PyObject_SetAttr(obj.ptr(), name.ptr(), value.ptr()) != 0) { throw error_already_set(); } -} - -inline void setattr(handle obj, const char *name, handle value) { - if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) { throw error_already_set(); } -} - -NAMESPACE_BEGIN(detail) -inline handle get_function(handle value) { - if (value) { -#if PY_MAJOR_VERSION >= 3 - if (PyInstanceMethod_Check(value.ptr())) - value = PyInstanceMethod_GET_FUNCTION(value.ptr()); -#endif - if (PyMethod_Check(value.ptr())) - value = PyMethod_GET_FUNCTION(value.ptr()); - } - return value; -} - -template -class accessor : public object_api> { - using key_type = typename Policy::key_type; - -public: - accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) { } - - void operator=(const accessor &a) && { std::move(*this).operator=(handle(a)); } - void operator=(const accessor &a) & { operator=(handle(a)); } - void operator=(const object &o) && { std::move(*this).operator=(handle(o)); } - void operator=(const object &o) & { operator=(handle(o)); } - void operator=(handle value) && { Policy::set(obj, key, value); } - void operator=(handle value) & { get_cache() = reinterpret_borrow(value); } - - template - PYBIND11_DEPRECATED("Use of obj.attr(...) as bool is deprecated in favor of pybind11::hasattr(obj, ...)") - explicit operator enable_if_t::value || - std::is_same::value, bool>() const { - return hasattr(obj, key); - } - template - PYBIND11_DEPRECATED("Use of obj[key] as bool is deprecated in favor of obj.contains(key)") - explicit operator enable_if_t::value, bool>() const { - return obj.contains(key); - } - - operator object() const { return get_cache(); } - PyObject *ptr() const { return get_cache().ptr(); } - template T cast() const { return get_cache().template cast(); } - -private: - object &get_cache() const { - if (!cache) { cache = Policy::get(obj, key); } - return cache; - } - -private: - handle obj; - key_type key; - mutable object cache; -}; - -NAMESPACE_BEGIN(accessor_policies) -struct obj_attr { - using key_type = object; - static object get(handle obj, handle key) { return getattr(obj, key); } - static void set(handle obj, handle key, handle val) { setattr(obj, key, val); } -}; - -struct str_attr { - using key_type = const char *; - static object get(handle obj, const char *key) { return getattr(obj, key); } - static void set(handle obj, const char *key, handle val) { setattr(obj, key, val); } -}; - -struct generic_item { - using key_type = object; - - static object get(handle obj, handle key) { - PyObject *result = PyObject_GetItem(obj.ptr(), key.ptr()); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); - } - - static void set(handle obj, handle key, handle val) { - if (PyObject_SetItem(obj.ptr(), key.ptr(), val.ptr()) != 0) { throw error_already_set(); } - } -}; - -struct sequence_item { - using key_type = size_t; - - static object get(handle obj, size_t index) { - PyObject *result = PySequence_GetItem(obj.ptr(), static_cast(index)); - if (!result) { throw error_already_set(); } - return reinterpret_borrow(result); - } - - static void set(handle obj, size_t index, handle val) { - // PySequence_SetItem does not steal a reference to 'val' - if (PySequence_SetItem(obj.ptr(), static_cast(index), val.ptr()) != 0) { - throw error_already_set(); - } - } -}; - -struct list_item { - using key_type = size_t; - - static object get(handle obj, size_t index) { - PyObject *result = PyList_GetItem(obj.ptr(), static_cast(index)); - if (!result) { throw error_already_set(); } - return reinterpret_borrow(result); - } - - static void set(handle obj, size_t index, handle val) { - // PyList_SetItem steals a reference to 'val' - if (PyList_SetItem(obj.ptr(), static_cast(index), val.inc_ref().ptr()) != 0) { - throw error_already_set(); - } - } -}; - -struct tuple_item { - using key_type = size_t; - - static object get(handle obj, size_t index) { - PyObject *result = PyTuple_GetItem(obj.ptr(), static_cast(index)); - if (!result) { throw error_already_set(); } - return reinterpret_borrow(result); - } - - static void set(handle obj, size_t index, handle val) { - // PyTuple_SetItem steals a reference to 'val' - if (PyTuple_SetItem(obj.ptr(), static_cast(index), val.inc_ref().ptr()) != 0) { - throw error_already_set(); - } - } -}; -NAMESPACE_END(accessor_policies) - -struct dict_iterator { -public: - explicit dict_iterator(handle dict = handle(), ssize_t pos = -1) : dict(dict), pos(pos) { } - dict_iterator& operator++() { - if (!PyDict_Next(dict.ptr(), &pos, &key.ptr(), &value.ptr())) - pos = -1; - return *this; - } - std::pair operator*() const { - return std::make_pair(key, value); - } - bool operator==(const dict_iterator &it) const { return it.pos == pos; } - bool operator!=(const dict_iterator &it) const { return it.pos != pos; } -private: - handle dict, key, value; - ssize_t pos = 0; -}; - -inline bool PyIterable_Check(PyObject *obj) { - PyObject *iter = PyObject_GetIter(obj); - if (iter) { - Py_DECREF(iter); - return true; - } else { - PyErr_Clear(); - return false; - } -} - -inline bool PyNone_Check(PyObject *o) { return o == Py_None; } - -inline bool PyUnicode_Check_Permissive(PyObject *o) { return PyUnicode_Check(o) || PYBIND11_BYTES_CHECK(o); } - -class kwargs_proxy : public handle { -public: - explicit kwargs_proxy(handle h) : handle(h) { } -}; - -class args_proxy : public handle { -public: - explicit args_proxy(handle h) : handle(h) { } - kwargs_proxy operator*() const { return kwargs_proxy(*this); } -}; - -/// Python argument categories (using PEP 448 terms) -template using is_keyword = std::is_base_of; -template using is_s_unpacking = std::is_same; // * unpacking -template using is_ds_unpacking = std::is_same; // ** unpacking -template using is_positional = bool_constant< - !is_keyword::value && !is_s_unpacking::value && !is_ds_unpacking::value ->; -template using is_keyword_or_ds = bool_constant< - is_keyword::value || is_ds_unpacking::value ->; - -// Call argument collector forward declarations -template -class simple_collector; -template -class unpacking_collector; - -NAMESPACE_END(detail) - -// TODO: After the deprecated constructors are removed, this macro can be simplified by -// inheriting ctors: `using Parent::Parent`. It's not an option right now because -// the `using` statement triggers the parent deprecation warning even if the ctor -// isn't even used. -#define PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ - public: \ - PYBIND11_DEPRECATED("Use reinterpret_borrow<"#Name">() or reinterpret_steal<"#Name">()") \ - Name(handle h, bool is_borrowed) : Parent(is_borrowed ? Parent(h, borrowed) : Parent(h, stolen)) { } \ - Name(handle h, borrowed_t) : Parent(h, borrowed) { } \ - Name(handle h, stolen_t) : Parent(h, stolen) { } \ - PYBIND11_DEPRECATED("Use py::isinstance(obj) instead") \ - bool check() const { return m_ptr != nullptr && (bool) CheckFun(m_ptr); } \ - static bool _check(handle h) { return h.ptr() != nullptr && CheckFun(h.ptr()); } - -#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun) \ - PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ - /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \ - Name(const object &o) : Parent(ConvertFun(o.ptr()), stolen) { if (!m_ptr) throw error_already_set(); } - -#define PYBIND11_OBJECT(Name, Parent, CheckFun) \ - PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ - /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \ - Name(const object &o) : Parent(o) { } \ - Name(object &&o) : Parent(std::move(o)) { } - -#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun) \ - PYBIND11_OBJECT(Name, Parent, CheckFun) \ - Name() : Parent() { } - -class iterator : public object { -public: - /** Caveat: copying an iterator does not (and cannot) clone the internal - state of the Python iterable */ - PYBIND11_OBJECT_DEFAULT(iterator, object, PyIter_Check) - - iterator& operator++() { - if (m_ptr) - advance(); - return *this; - } - - /** Caveat: this postincrement operator does not (and cannot) clone the - internal state of the Python iterable. It should only be used to - retrieve the current iterate using operator*() */ - iterator operator++(int) { - iterator rv(*this); - rv.value = value; - if (m_ptr) - advance(); - return rv; - } - - bool operator==(const iterator &it) const { return *it == **this; } - bool operator!=(const iterator &it) const { return *it != **this; } - - handle operator*() const { - if (!ready && m_ptr) { - auto& self = const_cast(*this); - self.advance(); - self.ready = true; - } - return value; - } - -private: - void advance() { value = reinterpret_steal(PyIter_Next(m_ptr)); } - -private: - object value = {}; - bool ready = false; -}; - -class iterable : public object { -public: - PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check) -}; - -class bytes; - -class str : public object { -public: - PYBIND11_OBJECT_CVT(str, object, detail::PyUnicode_Check_Permissive, raw_str) - - str(const char *c, size_t n) - : object(PyUnicode_FromStringAndSize(c, (ssize_t) n), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate string object!"); - } - - // 'explicit' is explicitly omitted from the following constructors to allow implicit conversion to py::str from C++ string-like objects - str(const char *c = "") - : object(PyUnicode_FromString(c), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate string object!"); - } - - str(const std::string &s) : str(s.data(), s.size()) { } - - explicit str(const bytes &b); - - explicit str(handle h) : object(raw_str(h.ptr()), stolen) { } - - operator std::string() const { - object temp = *this; - if (PyUnicode_Check(m_ptr)) { - temp = reinterpret_steal(PyUnicode_AsUTF8String(m_ptr)); - if (!temp) - pybind11_fail("Unable to extract string contents! (encoding issue)"); - } - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) - pybind11_fail("Unable to extract string contents! (invalid type)"); - return std::string(buffer, (size_t) length); - } - - template - str format(Args &&...args) const { - return attr("format")(std::forward(args)...); - } - -private: - /// Return string representation -- always returns a new reference, even if already a str - static PyObject *raw_str(PyObject *op) { - PyObject *str_value = PyObject_Str(op); -#if PY_MAJOR_VERSION < 3 - if (!str_value) throw error_already_set(); - PyObject *unicode = PyUnicode_FromEncodedObject(str_value, "utf-8", nullptr); - Py_XDECREF(str_value); str_value = unicode; -#endif - return str_value; - } -}; - -inline namespace literals { -/// String literal version of str -inline str operator"" _s(const char *s, size_t size) { return {s, size}; } -} - -class bytes : public object { -public: - PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK) - - // Allow implicit conversion: - bytes(const char *c = "") - : object(PYBIND11_BYTES_FROM_STRING(c), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate bytes object!"); - } - - bytes(const char *c, size_t n) - : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(c, (ssize_t) n), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate bytes object!"); - } - - // Allow implicit conversion: - bytes(const std::string &s) : bytes(s.data(), s.size()) { } - - explicit bytes(const pybind11::str &s); - - operator std::string() const { - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) - pybind11_fail("Unable to extract bytes contents!"); - return std::string(buffer, (size_t) length); - } -}; - -inline bytes::bytes(const pybind11::str &s) { - object temp = s; - if (PyUnicode_Check(s.ptr())) { - temp = reinterpret_steal(PyUnicode_AsUTF8String(s.ptr())); - if (!temp) - pybind11_fail("Unable to extract string contents! (encoding issue)"); - } - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) - pybind11_fail("Unable to extract string contents! (invalid type)"); - auto obj = reinterpret_steal(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length)); - if (!obj) - pybind11_fail("Could not allocate bytes object!"); - m_ptr = obj.release().ptr(); -} - -inline str::str(const bytes& b) { - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(b.ptr(), &buffer, &length)) - pybind11_fail("Unable to extract bytes contents!"); - auto obj = reinterpret_steal(PyUnicode_FromStringAndSize(buffer, (ssize_t) length)); - if (!obj) - pybind11_fail("Could not allocate string object!"); - m_ptr = obj.release().ptr(); -} - -class none : public object { -public: - PYBIND11_OBJECT(none, object, detail::PyNone_Check) - none() : object(Py_None, borrowed) { } -}; - -class bool_ : public object { -public: - PYBIND11_OBJECT_CVT(bool_, object, PyBool_Check, raw_bool) - bool_() : object(Py_False, borrowed) { } - // Allow implicit conversion from and to `bool`: - bool_(bool value) : object(value ? Py_True : Py_False, borrowed) { } - operator bool() const { return m_ptr && PyLong_AsLong(m_ptr) != 0; } - -private: - /// Return the truth value of an object -- always returns a new reference - static PyObject *raw_bool(PyObject *op) { - const auto value = PyObject_IsTrue(op); - if (value == -1) return nullptr; - return handle(value ? Py_True : Py_False).inc_ref().ptr(); - } -}; - -class int_ : public object { -public: - PYBIND11_OBJECT_CVT(int_, object, PYBIND11_LONG_CHECK, PyNumber_Long) - int_() : object(PyLong_FromLong(0), stolen) { } - // Allow implicit conversion from C++ integral types: - template ::value, int> = 0> - int_(T value) { - if (sizeof(T) <= sizeof(long)) { - if (std::is_signed::value) - m_ptr = PyLong_FromLong((long) value); - else - m_ptr = PyLong_FromUnsignedLong((unsigned long) value); - } else { - if (std::is_signed::value) - m_ptr = PyLong_FromLongLong((long long) value); - else - m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value); - } - if (!m_ptr) pybind11_fail("Could not allocate int object!"); - } - - template ::value, int> = 0> - operator T() const { - if (sizeof(T) <= sizeof(long)) { - if (std::is_signed::value) - return (T) PyLong_AsLong(m_ptr); - else - return (T) PyLong_AsUnsignedLong(m_ptr); - } else { - if (std::is_signed::value) - return (T) PYBIND11_LONG_AS_LONGLONG(m_ptr); - else - return (T) PYBIND11_LONG_AS_UNSIGNED_LONGLONG(m_ptr); - } - } -}; - -class float_ : public object { -public: - PYBIND11_OBJECT_CVT(float_, object, PyFloat_Check, PyNumber_Float) - // Allow implicit conversion from float/double: - float_(float value) : object(PyFloat_FromDouble((double) value), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate float object!"); - } - float_(double value = .0) : object(PyFloat_FromDouble((double) value), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate float object!"); - } - operator float() const { return (float) PyFloat_AsDouble(m_ptr); } - operator double() const { return (double) PyFloat_AsDouble(m_ptr); } -}; - -class weakref : public object { -public: - PYBIND11_OBJECT_DEFAULT(weakref, object, PyWeakref_Check) - explicit weakref(handle obj, handle callback = {}) - : object(PyWeakref_NewRef(obj.ptr(), callback.ptr()), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate weak reference!"); - } -}; - -class slice : public object { -public: - PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check) - slice(ssize_t start_, ssize_t stop_, ssize_t step_) { - int_ start(start_), stop(stop_), step(step_); - m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr()); - if (!m_ptr) pybind11_fail("Could not allocate slice object!"); - } - bool compute(size_t length, size_t *start, size_t *stop, size_t *step, - size_t *slicelength) const { - return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr, - (ssize_t) length, (ssize_t *) start, - (ssize_t *) stop, (ssize_t *) step, - (ssize_t *) slicelength) == 0; - } -}; - -class capsule : public object { -public: - PYBIND11_OBJECT_DEFAULT(capsule, object, PyCapsule_CheckExact) - PYBIND11_DEPRECATED("Use reinterpret_borrow() or reinterpret_steal()") - capsule(PyObject *ptr, bool is_borrowed) : object(is_borrowed ? object(ptr, borrowed) : object(ptr, stolen)) { } - explicit capsule(const void *value, void (*destruct)(PyObject *) = nullptr) - : object(PyCapsule_New(const_cast(value), nullptr, destruct), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate capsule object!"); - } - template operator T *() const { - T * result = static_cast(PyCapsule_GetPointer(m_ptr, nullptr)); - if (!result) pybind11_fail("Unable to extract capsule contents!"); - return result; - } -}; - -class tuple : public object { -public: - PYBIND11_OBJECT_CVT(tuple, object, PyTuple_Check, PySequence_Tuple) - explicit tuple(size_t size = 0) : object(PyTuple_New((ssize_t) size), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate tuple object!"); - } - size_t size() const { return (size_t) PyTuple_Size(m_ptr); } - detail::tuple_accessor operator[](size_t index) const { return {*this, index}; } -}; - -class dict : public object { -public: - PYBIND11_OBJECT_CVT(dict, object, PyDict_Check, raw_dict) - dict() : object(PyDict_New(), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate dict object!"); - } - template ::value>, - // MSVC workaround: it can't compile an out-of-line definition, so defer the collector - typename collector = detail::deferred_t, Args...>> - explicit dict(Args &&...args) : dict(collector(std::forward(args)...).kwargs()) { } - - size_t size() const { return (size_t) PyDict_Size(m_ptr); } - detail::dict_iterator begin() const { return (++detail::dict_iterator(*this, 0)); } - detail::dict_iterator end() const { return detail::dict_iterator(); } - void clear() const { PyDict_Clear(ptr()); } - bool contains(handle key) const { return PyDict_Contains(ptr(), key.ptr()) == 1; } - bool contains(const char *key) const { return PyDict_Contains(ptr(), pybind11::str(key).ptr()) == 1; } - -private: - /// Call the `dict` Python type -- always returns a new reference - static PyObject *raw_dict(PyObject *op) { - if (PyDict_Check(op)) - return handle(op).inc_ref().ptr(); - return PyObject_CallFunctionObjArgs((PyObject *) &PyDict_Type, op, nullptr); - } -}; - -class sequence : public object { -public: - PYBIND11_OBJECT(sequence, object, PySequence_Check) - size_t size() const { return (size_t) PySequence_Size(m_ptr); } - detail::sequence_accessor operator[](size_t index) const { return {*this, index}; } -}; - -class list : public object { -public: - PYBIND11_OBJECT_CVT(list, object, PyList_Check, PySequence_List) - explicit list(size_t size = 0) : object(PyList_New((ssize_t) size), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate list object!"); - } - size_t size() const { return (size_t) PyList_Size(m_ptr); } - detail::list_accessor operator[](size_t index) const { return {*this, index}; } - void append(handle h) const { PyList_Append(m_ptr, h.ptr()); } -}; - -class args : public tuple { PYBIND11_OBJECT_DEFAULT(args, tuple, PyTuple_Check) }; -class kwargs : public dict { PYBIND11_OBJECT_DEFAULT(kwargs, dict, PyDict_Check) }; - -class set : public object { -public: - PYBIND11_OBJECT_CVT(set, object, PySet_Check, PySet_New) - set() : object(PySet_New(nullptr), stolen) { - if (!m_ptr) pybind11_fail("Could not allocate set object!"); - } - size_t size() const { return (size_t) PySet_Size(m_ptr); } - bool add(const object &object) const { return PySet_Add(m_ptr, object.ptr()) == 0; } - void clear() const { PySet_Clear(m_ptr); } -}; - -class function : public object { -public: - PYBIND11_OBJECT_DEFAULT(function, object, PyCallable_Check) - bool is_cpp_function() const { - handle fun = detail::get_function(m_ptr); - return fun && PyCFunction_Check(fun.ptr()); - } -}; - -class buffer : public object { -public: - PYBIND11_OBJECT_DEFAULT(buffer, object, PyObject_CheckBuffer) - - buffer_info request(bool writable = false) { - int flags = PyBUF_STRIDES | PyBUF_FORMAT; - if (writable) flags |= PyBUF_WRITABLE; - Py_buffer *view = new Py_buffer(); - if (PyObject_GetBuffer(m_ptr, view, flags) != 0) - throw error_already_set(); - return buffer_info(view); - } -}; - -class memoryview : public object { -public: - explicit memoryview(const buffer_info& info) { - static Py_buffer buf { }; - // Py_buffer uses signed sizes, strides and shape!.. - static std::vector py_strides { }; - static std::vector py_shape { }; - buf.buf = info.ptr; - buf.itemsize = (Py_ssize_t) info.itemsize; - buf.format = const_cast(info.format.c_str()); - buf.ndim = (int) info.ndim; - buf.len = (Py_ssize_t) info.size; - py_strides.clear(); - py_shape.clear(); - for (size_t i = 0; i < info.ndim; ++i) { - py_strides.push_back((Py_ssize_t) info.strides[i]); - py_shape.push_back((Py_ssize_t) info.shape[i]); - } - buf.strides = py_strides.data(); - buf.shape = py_shape.data(); - buf.suboffsets = nullptr; - buf.readonly = false; - buf.internal = nullptr; - - m_ptr = PyMemoryView_FromBuffer(&buf); - if (!m_ptr) - pybind11_fail("Unable to create memoryview from buffer descriptor"); - } - - PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject) -}; - -inline size_t len(handle h) { - ssize_t result = PyObject_Length(h.ptr()); - if (result < 0) - pybind11_fail("Unable to compute length of object"); - return (size_t) result; -} - -inline str repr(handle h) { - PyObject *str_value = PyObject_Repr(h.ptr()); - if (!str_value) throw error_already_set(); -#if PY_MAJOR_VERSION < 3 - PyObject *unicode = PyUnicode_FromEncodedObject(str_value, "utf-8", nullptr); - Py_XDECREF(str_value); str_value = unicode; - if (!str_value) throw error_already_set(); -#endif - return reinterpret_steal(str_value); -} - -NAMESPACE_BEGIN(detail) -template iterator object_api::begin() const { - return reinterpret_steal(PyObject_GetIter(derived().ptr())); -} -template iterator object_api::end() const { - return {}; -} -template item_accessor object_api::operator[](handle key) const { - return {derived(), reinterpret_borrow(key)}; -} -template item_accessor object_api::operator[](const char *key) const { - return {derived(), pybind11::str(key)}; -} -template obj_attr_accessor object_api::attr(handle key) const { - return {derived(), reinterpret_borrow(key)}; -} -template str_attr_accessor object_api::attr(const char *key) const { - return {derived(), key}; -} -template args_proxy object_api::operator*() const { - return args_proxy(derived().ptr()); -} -template template bool object_api::contains(T &&key) const { - return attr("__contains__")(std::forward(key)).template cast(); -} - -template -pybind11::str object_api::str() const { return pybind11::str(derived()); } - -template -handle object_api::get_type() const { return (PyObject *) Py_TYPE(derived().ptr()); } - -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/stl.h b/stormpy/resources/pybind11/include/pybind11/stl.h deleted file mode 100644 index c1ed0f979..000000000 --- a/stormpy/resources/pybind11/include/pybind11/stl.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - pybind11/stl.h: Transparent conversion for STL data types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include -#include -#include -#include -#include -#include - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -#endif - -#ifdef __has_include -// std::optional (but including it in c++14 mode isn't allowed) -# if defined(PYBIND11_CPP17) && __has_include() -# include -# define PYBIND11_HAS_OPTIONAL 1 -# endif -// std::experimental::optional (but not allowed in c++11 mode) -# if defined(PYBIND11_CPP14) && __has_include() -# include -# if __cpp_lib_experimental_optional // just in case -# define PYBIND11_HAS_EXP_OPTIONAL 1 -# endif -# endif -#endif - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -template struct set_caster { - using type = Type; - using key_conv = make_caster; - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto s = reinterpret_borrow(src); - value.clear(); - key_conv conv; - for (auto entry : s) { - if (!conv.load(entry, convert)) - return false; - value.insert((Key) conv); - } - return true; - } - - static handle cast(const type &src, return_value_policy policy, handle parent) { - pybind11::set s; - for (auto const &value: src) { - auto value_ = reinterpret_steal(key_conv::cast(value, policy, parent)); - if (!value_ || !s.add(value_)) - return handle(); - } - return s.release(); - } - - PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name() + _("]")); -}; - -template struct map_caster { - using type = Type; - using key_conv = make_caster; - using value_conv = make_caster; - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto d = reinterpret_borrow(src); - key_conv kconv; - value_conv vconv; - value.clear(); - for (auto it : d) { - if (!kconv.load(it.first.ptr(), convert) || - !vconv.load(it.second.ptr(), convert)) - return false; - value.emplace((Key) kconv, (Value) vconv); - } - return true; - } - - static handle cast(const type &src, return_value_policy policy, handle parent) { - dict d; - for (auto const &kv: src) { - auto key = reinterpret_steal(key_conv::cast(kv.first, policy, parent)); - auto value = reinterpret_steal(value_conv::cast(kv.second, policy, parent)); - if (!key || !value) - return handle(); - d[key] = value; - } - return d.release(); - } - - PYBIND11_TYPE_CASTER(type, _("Dict[") + key_conv::name() + _(", ") + value_conv::name() + _("]")); -}; - -template struct list_caster { - using type = Type; - using value_conv = make_caster; - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto s = reinterpret_borrow(src); - value_conv conv; - value.clear(); - reserve_maybe(s, &value); - for (auto it : s) { - if (!conv.load(it, convert)) - return false; - value.push_back((Value) conv); - } - return true; - } - - template ().reserve(0)), void>::value, int> = 0> - void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); } - void reserve_maybe(sequence, void *) { } - - static handle cast(const Type &src, return_value_policy policy, handle parent) { - list l(src.size()); - size_t index = 0; - for (auto const &value: src) { - auto value_ = reinterpret_steal(value_conv::cast(value, policy, parent)); - if (!value_) - return handle(); - PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference - } - return l.release(); - } - - PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name() + _("]")); -}; - -template struct type_caster> - : list_caster, Type> { }; - -template struct type_caster> - : list_caster, Type> { }; - -template struct type_caster> { - using array_type = std::array; - using value_conv = make_caster; - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto l = reinterpret_borrow(src); - if (l.size() != Size) - return false; - value_conv conv; - size_t ctr = 0; - for (auto it : l) { - if (!conv.load(it, convert)) - return false; - value[ctr++] = (Type) conv; - } - return true; - } - - static handle cast(const array_type &src, return_value_policy policy, handle parent) { - list l(Size); - size_t index = 0; - for (auto const &value: src) { - auto value_ = reinterpret_steal(value_conv::cast(value, policy, parent)); - if (!value_) - return handle(); - PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference - } - return l.release(); - } - PYBIND11_TYPE_CASTER(array_type, _("List[") + value_conv::name() + _("[") + _() + _("]]")); -}; - -template struct type_caster> - : set_caster, Key> { }; - -template struct type_caster> - : set_caster, Key> { }; - -template struct type_caster> - : map_caster, Key, Value> { }; - -template struct type_caster> - : map_caster, Key, Value> { }; - -// This type caster is intended to be used for std::optional and std::experimental::optional -template struct optional_caster { - using value_type = typename intrinsic_type::type; - using caster_type = type_caster; - - static handle cast(const T& src, return_value_policy policy, handle parent) { - if (!src) - return none().inc_ref(); - return caster_type::cast(*src, policy, parent); - } - - bool load(handle src, bool convert) { - if (!src) { - return false; - } else if (src.is_none()) { - value = {}; // nullopt - return true; - } else if (!inner.load(src, convert)) { - return false; - } else { - value.emplace(static_cast(inner)); - return true; - } - } - - PYBIND11_TYPE_CASTER(T, _("Optional[") + caster_type::name() + _("]")); - -private: - caster_type inner; -}; - -#if PYBIND11_HAS_OPTIONAL -template struct type_caster> - : public optional_caster> {}; - -template<> struct type_caster - : public void_caster {}; -#endif - -#if PYBIND11_HAS_EXP_OPTIONAL -template struct type_caster> - : public optional_caster> {}; - -template<> struct type_caster - : public void_caster {}; -#endif - -NAMESPACE_END(detail) - -inline std::ostream &operator<<(std::ostream &os, const handle &obj) { - os << (std::string) str(obj); - return os; -} - -NAMESPACE_END(pybind11) - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif diff --git a/stormpy/resources/pybind11/include/pybind11/stl_bind.h b/stormpy/resources/pybind11/include/pybind11/stl_bind.h deleted file mode 100644 index ef9950ebb..000000000 --- a/stormpy/resources/pybind11/include/pybind11/stl_bind.h +++ /dev/null @@ -1,541 +0,0 @@ -/* - pybind11/std_bind.h: Binding generators for STL data types - - Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "common.h" -#include "operators.h" - -#include -#include - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) - -/* SFINAE helper class used by 'is_comparable */ -template struct container_traits { - template static std::true_type test_comparable(decltype(std::declval() == std::declval())*); - template static std::false_type test_comparable(...); - template static std::true_type test_value(typename T2::value_type *); - template static std::false_type test_value(...); - template static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *); - template static std::false_type test_pair(...); - - static constexpr const bool is_comparable = std::is_same(nullptr))>::value; - static constexpr const bool is_pair = std::is_same(nullptr, nullptr))>::value; - static constexpr const bool is_vector = std::is_same(nullptr))>::value; - static constexpr const bool is_element = !is_pair && !is_vector; -}; - -/* Default: is_comparable -> std::false_type */ -template -struct is_comparable : std::false_type { }; - -/* For non-map data structures, check whether operator== can be instantiated */ -template -struct is_comparable< - T, enable_if_t::is_element && - container_traits::is_comparable>> - : std::true_type { }; - -/* For a vector/map data structure, recursively check the value type (which is std::pair for maps) */ -template -struct is_comparable::is_vector>> { - static constexpr const bool value = - is_comparable::value; -}; - -/* For pairs, recursively check the two data types */ -template -struct is_comparable::is_pair>> { - static constexpr const bool value = - is_comparable::value && - is_comparable::value; -}; - -/* Fallback functions */ -template void vector_if_copy_constructible(const Args &...) { } -template void vector_if_equal_operator(const Args &...) { } -template void vector_if_insertion_operator(const Args &...) { } -template void vector_modifiers(const Args &...) { } - -template -void vector_if_copy_constructible(enable_if_t< - std::is_copy_constructible::value && - std::is_copy_constructible::value, Class_> &cl) { - - cl.def(pybind11::init(), "Copy constructor"); -} - -template -void vector_if_equal_operator(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - - cl.def(self == self); - cl.def(self != self); - - cl.def("count", - [](const Vector &v, const T &x) { - return std::count(v.begin(), v.end(), x); - }, - arg("x"), - "Return the number of times ``x`` appears in the list" - ); - - cl.def("remove", [](Vector &v, const T &x) { - auto p = std::find(v.begin(), v.end(), x); - if (p != v.end()) - v.erase(p); - else - throw pybind11::value_error(); - }, - arg("x"), - "Remove the first item from the list whose value is x. " - "It is an error if there is no such item." - ); - - cl.def("__contains__", - [](const Vector &v, const T &x) { - return std::find(v.begin(), v.end(), x) != v.end(); - }, - arg("x"), - "Return true the container contains ``x``" - ); -} - -// Vector modifiers -- requires a copyable vector_type: -// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it seems -// silly to allow deletion but not insertion, so include them here too.) -template -void vector_modifiers(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - using SizeType = typename Vector::size_type; - using DiffType = typename Vector::difference_type; - - cl.def("append", - [](Vector &v, const T &value) { v.push_back(value); }, - arg("x"), - "Add an item to the end of the list"); - - cl.def("__init__", [](Vector &v, iterable it) { - new (&v) Vector(); - try { - v.reserve(len(it)); - for (handle h : it) - v.push_back(h.cast()); - } catch (...) { - v.~Vector(); - throw; - } - }); - - cl.def("extend", - [](Vector &v, const Vector &src) { - v.reserve(v.size() + src.size()); - v.insert(v.end(), src.begin(), src.end()); - }, - arg("L"), - "Extend the list by appending all the items in the given list" - ); - - cl.def("insert", - [](Vector &v, SizeType i, const T &x) { - v.insert(v.begin() + (DiffType) i, x); - }, - arg("i") , arg("x"), - "Insert an item at a given position." - ); - - cl.def("pop", - [](Vector &v) { - if (v.empty()) - throw pybind11::index_error(); - T t = v.back(); - v.pop_back(); - return t; - }, - "Remove and return the last item" - ); - - cl.def("pop", - [](Vector &v, SizeType i) { - if (i >= v.size()) - throw pybind11::index_error(); - T t = v[i]; - v.erase(v.begin() + (DiffType) i); - return t; - }, - arg("i"), - "Remove and return the item at index ``i``" - ); - - cl.def("__setitem__", - [](Vector &v, SizeType i, const T &t) { - if (i >= v.size()) - throw pybind11::index_error(); - v[i] = t; - } - ); - - /// Slicing protocol - cl.def("__getitem__", - [](const Vector &v, slice slice) -> Vector * { - size_t start, stop, step, slicelength; - - if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) - throw pybind11::error_already_set(); - - Vector *seq = new Vector(); - seq->reserve((size_t) slicelength); - - for (size_t i=0; ipush_back(v[start]); - start += step; - } - return seq; - }, - arg("s"), - "Retrieve list elements using a slice object" - ); - - cl.def("__setitem__", - [](Vector &v, slice slice, const Vector &value) { - size_t start, stop, step, slicelength; - if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) - throw pybind11::error_already_set(); - - if (slicelength != value.size()) - throw std::runtime_error("Left and right hand size of slice assignment have different sizes!"); - - for (size_t i=0; i= v.size()) - throw pybind11::index_error(); - v.erase(v.begin() + DiffType(i)); - }, - "Delete the list elements at index ``i``" - ); - - cl.def("__delitem__", - [](Vector &v, slice slice) { - size_t start, stop, step, slicelength; - - if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) - throw pybind11::error_already_set(); - - if (step == 1 && false) { - v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength)); - } else { - for (size_t i = 0; i < slicelength; ++i) { - v.erase(v.begin() + DiffType(start)); - start += step - 1; - } - } - }, - "Delete list elements using a slice object" - ); - -} - -// If the type has an operator[] that doesn't return a reference (most notably std::vector), -// we have to access by copying; otherwise we return by reference. -template using vector_needs_copy = bool_constant< - !std::is_same()[typename Vector::size_type()]), typename Vector::value_type &>::value>; - -// The usual case: access and iterate by reference -template -void vector_accessor(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - using SizeType = typename Vector::size_type; - using ItType = typename Vector::iterator; - - cl.def("__getitem__", - [](Vector &v, SizeType i) -> T & { - if (i >= v.size()) - throw pybind11::index_error(); - return v[i]; - }, - return_value_policy::reference_internal // ref + keepalive - ); - - cl.def("__iter__", - [](Vector &v) { - return pybind11::make_iterator< - return_value_policy::reference_internal, ItType, ItType, T&>( - v.begin(), v.end()); - }, - keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); -} - -// The case for special objects, like std::vector, that have to be returned-by-copy: -template -void vector_accessor(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - using SizeType = typename Vector::size_type; - using ItType = typename Vector::iterator; - cl.def("__getitem__", - [](const Vector &v, SizeType i) -> T { - if (i >= v.size()) - throw pybind11::index_error(); - return v[i]; - } - ); - - cl.def("__iter__", - [](Vector &v) { - return pybind11::make_iterator< - return_value_policy::copy, ItType, ItType, T>( - v.begin(), v.end()); - }, - keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); -} - -template auto vector_if_insertion_operator(Class_ &cl, std::string const &name) - -> decltype(std::declval() << std::declval(), void()) { - using size_type = typename Vector::size_type; - - cl.def("__repr__", - [name](Vector &v) { - std::ostringstream s; - s << name << '['; - for (size_type i=0; i < v.size(); ++i) { - s << v[i]; - if (i != v.size() - 1) - s << ", "; - } - s << ']'; - return s.str(); - }, - "Return the canonical string representation of this list." - ); -} - -NAMESPACE_END(detail) - -// -// std::vector -// -template , typename... Args> -pybind11::class_ bind_vector(pybind11::module &m, std::string const &name, Args&&... args) { - using Class_ = pybind11::class_; - - Class_ cl(m, name.c_str(), std::forward(args)...); - - cl.def(pybind11::init<>()); - - // Register copy constructor (if possible) - detail::vector_if_copy_constructible(cl); - - // Register comparison-related operators and functions (if possible) - detail::vector_if_equal_operator(cl); - - // Register stream insertion operator (if possible) - detail::vector_if_insertion_operator(cl, name); - - // Modifiers require copyable vector value type - detail::vector_modifiers(cl); - - // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive - detail::vector_accessor(cl); - - cl.def("__bool__", - [](const Vector &v) -> bool { - return !v.empty(); - }, - "Check whether the list is nonempty" - ); - - cl.def("__len__", &Vector::size); - - - - -#if 0 - // C++ style functions deprecated, leaving it here as an example - cl.def(pybind11::init()); - - cl.def("resize", - (void (Vector::*) (size_type count)) & Vector::resize, - "changes the number of elements stored"); - - cl.def("erase", - [](Vector &v, SizeType i) { - if (i >= v.size()) - throw pybind11::index_error(); - v.erase(v.begin() + i); - }, "erases element at index ``i``"); - - cl.def("empty", &Vector::empty, "checks whether the container is empty"); - cl.def("size", &Vector::size, "returns the number of elements"); - cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end"); - cl.def("pop_back", &Vector::pop_back, "removes the last element"); - - cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements"); - cl.def("reserve", &Vector::reserve, "reserves storage"); - cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage"); - cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory"); - - cl.def("clear", &Vector::clear, "clears the contents"); - cl.def("swap", &Vector::swap, "swaps the contents"); - - cl.def("front", [](Vector &v) { - if (v.size()) return v.front(); - else throw pybind11::index_error(); - }, "access the first element"); - - cl.def("back", [](Vector &v) { - if (v.size()) return v.back(); - else throw pybind11::index_error(); - }, "access the last element "); - -#endif - - return cl; -} - - - -// -// std::map, std::unordered_map -// - -NAMESPACE_BEGIN(detail) - -/* Fallback functions */ -template void map_if_insertion_operator(const Args &...) { } -template void map_assignment(const Args &...) { } - -// Map assignment when copy-assignable: just copy the value -template -void map_assignment(enable_if_t::value, Class_> &cl) { - using KeyType = typename Map::key_type; - using MappedType = typename Map::mapped_type; - - cl.def("__setitem__", - [](Map &m, const KeyType &k, const MappedType &v) { - auto it = m.find(k); - if (it != m.end()) it->second = v; - else m.emplace(k, v); - } - ); -} - -// Not copy-assignable, but still copy-constructible: we can update the value by erasing and reinserting -template -void map_assignment(enable_if_t< - !std::is_copy_assignable::value && - std::is_copy_constructible::value, - Class_> &cl) { - using KeyType = typename Map::key_type; - using MappedType = typename Map::mapped_type; - - cl.def("__setitem__", - [](Map &m, const KeyType &k, const MappedType &v) { - // We can't use m[k] = v; because value type might not be default constructable - auto r = m.emplace(k, v); - if (!r.second) { - // value type is not copy assignable so the only way to insert it is to erase it first... - m.erase(r.first); - m.emplace(k, v); - } - } - ); -} - - -template auto map_if_insertion_operator(Class_ &cl, std::string const &name) --> decltype(std::declval() << std::declval() << std::declval(), void()) { - - cl.def("__repr__", - [name](Map &m) { - std::ostringstream s; - s << name << '{'; - bool f = false; - for (auto const &kv : m) { - if (f) - s << ", "; - s << kv.first << ": " << kv.second; - f = true; - } - s << '}'; - return s.str(); - }, - "Return the canonical string representation of this map." - ); -} - - -NAMESPACE_END(detail) - -template , typename... Args> -pybind11::class_ bind_map(module &m, const std::string &name, Args&&... args) { - using KeyType = typename Map::key_type; - using MappedType = typename Map::mapped_type; - using Class_ = pybind11::class_; - - Class_ cl(m, name.c_str(), std::forward(args)...); - - cl.def(pybind11::init<>()); - - // Register stream insertion operator (if possible) - detail::map_if_insertion_operator(cl, name); - - cl.def("__bool__", - [](const Map &m) -> bool { return !m.empty(); }, - "Check whether the map is nonempty" - ); - - cl.def("__iter__", - [](Map &m) { return pybind11::make_key_iterator(m.begin(), m.end()); }, - pybind11::keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); - - cl.def("items", - [](Map &m) { return pybind11::make_iterator(m.begin(), m.end()); }, - pybind11::keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); - - cl.def("__getitem__", - [](Map &m, const KeyType &k) -> MappedType & { - auto it = m.find(k); - if (it == m.end()) - throw pybind11::key_error(); - return it->second; - }, - return_value_policy::reference_internal // ref + keepalive - ); - - // Assignment provided only if the type is copyable - detail::map_assignment(cl); - - cl.def("__delitem__", - [](Map &m, const KeyType &k) { - auto it = m.find(k); - if (it == m.end()) - throw pybind11::key_error(); - return m.erase(it); - } - ); - - cl.def("__len__", &Map::size); - - return cl; -} - -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/include/pybind11/typeid.h b/stormpy/resources/pybind11/include/pybind11/typeid.h deleted file mode 100644 index c903fb14c..000000000 --- a/stormpy/resources/pybind11/include/pybind11/typeid.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - pybind11/typeid.h: Compiler-independent access to type identifiers - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include -#include - -#if defined(__GNUG__) -#include -#endif - -NAMESPACE_BEGIN(pybind11) -NAMESPACE_BEGIN(detail) -/// Erase all occurrences of a substring -inline void erase_all(std::string &string, const std::string &search) { - for (size_t pos = 0;;) { - pos = string.find(search, pos); - if (pos == std::string::npos) break; - string.erase(pos, search.length()); - } -} - -PYBIND11_NOINLINE inline void clean_type_id(std::string &name) { -#if defined(__GNUG__) - int status = 0; - std::unique_ptr res { - abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free }; - if (status == 0) - name = res.get(); -#else - detail::erase_all(name, "class "); - detail::erase_all(name, "struct "); - detail::erase_all(name, "enum "); -#endif - detail::erase_all(name, "pybind11::"); -} -NAMESPACE_END(detail) - -/// Return a string representation of a C++ type -template static std::string type_id() { - std::string name(typeid(T).name()); - detail::clean_type_id(name); - return name; -} - -NAMESPACE_END(pybind11) diff --git a/stormpy/resources/pybind11/pybind11/__init__.py b/stormpy/resources/pybind11/pybind11/__init__.py deleted file mode 100644 index a765692fe..000000000 --- a/stormpy/resources/pybind11/pybind11/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from ._version import version_info, __version__ # noqa: F401 imported but unused - - -def get_include(*args, **kwargs): - import os - try: - from pip import locations - return os.path.dirname( - locations.distutils_scheme('pybind11', *args, **kwargs)['headers']) - except ImportError: - return 'include' diff --git a/stormpy/resources/pybind11/pybind11/_version.py b/stormpy/resources/pybind11/pybind11/_version.py deleted file mode 100644 index be66f0732..000000000 --- a/stormpy/resources/pybind11/pybind11/_version.py +++ /dev/null @@ -1,2 +0,0 @@ -version_info = (1, 9, 'dev0') -__version__ = '.'.join(map(str, version_info)) diff --git a/stormpy/resources/pybind11/setup.cfg b/stormpy/resources/pybind11/setup.cfg deleted file mode 100644 index 89347b297..000000000 --- a/stormpy/resources/pybind11/setup.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[bdist_wheel] -universal=1 - -[flake8] -show_source = True -exclude = .git, __pycache__, build, dist, docs, tools, venv -ignore = - # line too long - E501, - # required for pretty matrix formating: multiple spaces after `,` and `[` - E201, E241 diff --git a/stormpy/resources/pybind11/setup.py b/stormpy/resources/pybind11/setup.py deleted file mode 100644 index 425e6c57a..000000000 --- a/stormpy/resources/pybind11/setup.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python - -# Setup script for PyPI; use CMakeFile.txt to build extension modules - -from setuptools import setup -from pybind11 import __version__ - -setup( - name='pybind11', - version=__version__, - description='Seamless operability between C++11 and Python', - author='Wenzel Jakob', - author_email='wenzel.jakob@epfl.ch', - url='https://github.com/wjakob/pybind11', - download_url='https://github.com/wjakob/pybind11/tarball/v' + __version__, - packages=['pybind11'], - license='BSD', - headers=[ - 'include/pybind11/attr.h', - 'include/pybind11/cast.h', - 'include/pybind11/complex.h', - 'include/pybind11/descr.h', - 'include/pybind11/eigen.h', - 'include/pybind11/numpy.h', - 'include/pybind11/pybind11.h', - 'include/pybind11/stl.h', - 'include/pybind11/stl_bind.h', - 'include/pybind11/common.h', - 'include/pybind11/functional.h', - 'include/pybind11/operators.h', - 'include/pybind11/pytypes.h', - 'include/pybind11/typeid.h' - ], - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Utilities', - 'Programming Language :: C++', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'License :: OSI Approved :: BSD License', - ], - keywords='C++11, Python bindings', - long_description="""pybind11 is a lightweight header library that exposes -C++ types in Python and vice versa, mainly to create Python bindings of -existing C++ code. Its goals and syntax are similar to the excellent -Boost.Python library by David Abrahams: to minimize boilerplate code in -traditional extension modules by inferring type information using compile-time -introspection. - -The main issue with Boost.Python-and the reason for creating such a similar -project-is Boost. Boost is an enormously large and complex suite of utility -libraries that works with almost every C++ compiler in existence. This -compatibility has its cost: arcane template tricks and workarounds are -necessary to support the oldest and buggiest of compiler specimens. Now that -C++11-compatible compilers are widely available, this heavy machinery has -become an excessively large and unnecessary dependency. - -Think of this library as a tiny self-contained version of Boost.Python with -everything stripped away that isn't relevant for binding generation. Without -comments, the core header files only require ~2.5K lines of code and depend on -Python (2.7 or 3.x) and the C++ standard library. This compact implementation -was possible thanks to some of the new C++11 language features (specifically: -tuples, lambda functions and variadic templates). Since its creation, this -library has grown beyond Boost.Python in many ways, leading to dramatically -simpler binding code in many common situations.""") diff --git a/stormpy/resources/pybind11/tests/CMakeLists.txt b/stormpy/resources/pybind11/tests/CMakeLists.txt deleted file mode 100755 index cb87fd812..000000000 --- a/stormpy/resources/pybind11/tests/CMakeLists.txt +++ /dev/null @@ -1,111 +0,0 @@ -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting tests build type to MinSizeRel as none was specified") - set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" - "MinSizeRel" "RelWithDebInfo") -endif() - -# Full set of test files (you can override these; see below) -set(PYBIND11_TEST_FILES - test_alias_initialization.cpp - test_buffers.cpp - test_callbacks.cpp - test_chrono.cpp - test_class_args.cpp - test_constants_and_functions.cpp - test_copy_move_policies.cpp - test_docstring_options.cpp - test_eigen.cpp - test_enum.cpp - test_eval.cpp - test_exceptions.cpp - test_inheritance.cpp - test_issues.cpp - test_keep_alive.cpp - test_kwargs_and_defaults.cpp - test_methods_and_attributes.cpp - test_modules.cpp - test_multiple_inheritance.cpp - test_numpy_array.cpp - test_numpy_dtypes.cpp - test_numpy_vectorize.cpp - test_opaque_types.cpp - test_operator_overloading.cpp - test_pickling.cpp - test_python_types.cpp - test_sequences_and_iterators.cpp - test_smart_ptr.cpp - test_stl_binders.cpp - test_virtual_functions.cpp -) - -# Invoking cmake with something like: -# cmake -DPYBIND11_TEST_OVERRIDE="test_issues.cpp;test_picking.cpp" .. -# lets you override the tests that get compiled and run. You can restore to all tests with: -# cmake -DPYBIND11_TEST_OVERRIDE= .. -if (PYBIND11_TEST_OVERRIDE) - set(PYBIND11_TEST_FILES ${PYBIND11_TEST_OVERRIDE}) -endif() - -string(REPLACE ".cpp" ".py" PYBIND11_PYTEST_FILES "${PYBIND11_TEST_FILES}") - -# Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but -# keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed" -# skip message). -list(FIND PYBIND11_TEST_FILES test_eigen.cpp PYBIND11_TEST_FILES_EIGEN_I) -if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1) - find_package(Eigen3 QUIET) - - if(EIGEN3_FOUND) - message(STATUS "Building tests with Eigen v${EIGEN3_VERSION}") - else() - list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I}) - message(STATUS "Building tests WITHOUT Eigen") - endif() -endif() - -# Create the binding library -pybind11_add_module(pybind11_tests pybind11_tests.cpp - ${PYBIND11_TEST_FILES} ${PYBIND11_HEADERS}) - -pybind11_enable_warnings(pybind11_tests) - -if(EIGEN3_FOUND) - target_include_directories(pybind11_tests PRIVATE ${EIGEN3_INCLUDE_DIR}) - target_compile_definitions(pybind11_tests PRIVATE -DPYBIND11_TEST_EIGEN) -endif() - -set(testdir ${PROJECT_SOURCE_DIR}/tests) - -# Always write the output file directly into the 'tests' directory (even on MSVC) -if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) - set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${testdir}) - foreach(config ${CMAKE_CONFIGURATION_TYPES}) - string(TOUPPER ${config} config) - set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config} ${testdir}) - endforeach() -endif() - -# Make sure pytest is found or produce a fatal error -if(NOT PYBIND11_PYTEST_FOUND) - execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pytest --version --noconftest OUTPUT_QUIET ERROR_QUIET - RESULT_VARIABLE PYBIND11_EXEC_PYTHON_ERR) - if(PYBIND11_EXEC_PYTHON_ERR) - message(FATAL_ERROR "Running the tests requires pytest. Please install it manually (try: ${PYTHON_EXECUTABLE} -m pip install pytest)") - endif() - set(PYBIND11_PYTEST_FOUND TRUE CACHE INTERNAL "") -endif() - -# A single command to compile and run the tests -add_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest -rws ${PYBIND11_PYTEST_FILES} - DEPENDS pybind11_tests WORKING_DIRECTORY ${testdir}) - -if(PYBIND11_TEST_OVERRIDE) - add_custom_command(TARGET pytest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E echo "Note: not all tests run: -DPYBIND11_TEST_OVERRIDE is in effect") -endif() - -# And another to show the .so size and, if a previous size, compare it: -add_custom_command(TARGET pybind11_tests POST_BUILD - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/libsize.py - $ ${CMAKE_CURRENT_BINARY_DIR}/sosize-$.txt) diff --git a/stormpy/resources/pybind11/tests/conftest.py b/stormpy/resources/pybind11/tests/conftest.py deleted file mode 100755 index d4335fc6d..000000000 --- a/stormpy/resources/pybind11/tests/conftest.py +++ /dev/null @@ -1,227 +0,0 @@ -"""pytest configuration - -Extends output capture as needed by pybind11: ignore constructors, optional unordered lines. -Adds docstring and exceptions message sanitizers: ignore Python 2 vs 3 differences. -""" - -import pytest -import textwrap -import difflib -import re -import sys -import contextlib - -_unicode_marker = re.compile(r'u(\'[^\']*\')') -_long_marker = re.compile(r'([0-9])L') -_hexadecimal = re.compile(r'0x[0-9a-fA-F]+') - - -def _strip_and_dedent(s): - """For triple-quote strings""" - return textwrap.dedent(s.lstrip('\n').rstrip()) - - -def _split_and_sort(s): - """For output which does not require specific line order""" - return sorted(_strip_and_dedent(s).splitlines()) - - -def _make_explanation(a, b): - """Explanation for a failed assert -- the a and b arguments are List[str]""" - return ["--- actual / +++ expected"] + [line.strip('\n') for line in difflib.ndiff(a, b)] - - -class Output(object): - """Basic output post-processing and comparison""" - def __init__(self, string): - self.string = string - self.explanation = [] - - def __str__(self): - return self.string - - def __eq__(self, other): - # Ignore constructor/destructor output which is prefixed with "###" - a = [line for line in self.string.strip().splitlines() if not line.startswith("###")] - b = _strip_and_dedent(other).splitlines() - if a == b: - return True - else: - self.explanation = _make_explanation(a, b) - return False - - -class Unordered(Output): - """Custom comparison for output without strict line ordering""" - def __eq__(self, other): - a = _split_and_sort(self.string) - b = _split_and_sort(other) - if a == b: - return True - else: - self.explanation = _make_explanation(a, b) - return False - - -class Capture(object): - def __init__(self, capfd): - self.capfd = capfd - self.out = "" - self.err = "" - - def __enter__(self): - self.capfd.readouterr() - return self - - def __exit__(self, *_): - self.out, self.err = self.capfd.readouterr() - - def __eq__(self, other): - a = Output(self.out) - b = other - if a == b: - return True - else: - self.explanation = a.explanation - return False - - def __str__(self): - return self.out - - def __contains__(self, item): - return item in self.out - - @property - def unordered(self): - return Unordered(self.out) - - @property - def stderr(self): - return Output(self.err) - - -@pytest.fixture -def capture(capfd): - """Extended `capfd` with context manager and custom equality operators""" - return Capture(capfd) - - -class SanitizedString(object): - def __init__(self, sanitizer): - self.sanitizer = sanitizer - self.string = "" - self.explanation = [] - - def __call__(self, thing): - self.string = self.sanitizer(thing) - return self - - def __eq__(self, other): - a = self.string - b = _strip_and_dedent(other) - if a == b: - return True - else: - self.explanation = _make_explanation(a.splitlines(), b.splitlines()) - return False - - -def _sanitize_general(s): - s = s.strip() - s = s.replace("pybind11_tests.", "m.") - s = s.replace("unicode", "str") - s = _long_marker.sub(r"\1", s) - s = _unicode_marker.sub(r"\1", s) - return s - - -def _sanitize_docstring(thing): - s = thing.__doc__ - s = _sanitize_general(s) - return s - - -@pytest.fixture -def doc(): - """Sanitize docstrings and add custom failure explanation""" - return SanitizedString(_sanitize_docstring) - - -def _sanitize_message(thing): - s = str(thing) - s = _sanitize_general(s) - s = _hexadecimal.sub("0", s) - return s - - -@pytest.fixture -def msg(): - """Sanitize messages and add custom failure explanation""" - return SanitizedString(_sanitize_message) - - -# noinspection PyUnusedLocal -def pytest_assertrepr_compare(op, left, right): - """Hook to insert custom failure explanation""" - if hasattr(left, 'explanation'): - return left.explanation - - -@contextlib.contextmanager -def suppress(exception): - """Suppress the desired exception""" - try: - yield - except exception: - pass - - -def pytest_namespace(): - """Add import suppression and test requirements to `pytest` namespace""" - try: - import numpy as np - except ImportError: - np = None - try: - import scipy - except ImportError: - scipy = None - try: - from pybind11_tests import have_eigen - except ImportError: - have_eigen = False - - skipif = pytest.mark.skipif - return { - 'suppress': suppress, - 'requires_numpy': skipif(not np, reason="numpy is not installed"), - 'requires_scipy': skipif(not np, reason="scipy is not installed"), - 'requires_eigen_and_numpy': skipif(not have_eigen or not np, - reason="eigen and/or numpy are not installed"), - 'requires_eigen_and_scipy': skipif(not have_eigen or not scipy, - reason="eigen and/or scipy are not installed"), - } - - -def _test_import_pybind11(): - """Early diagnostic for test module initialization errors - - When there is an error during initialization, the first import will report the - real error while all subsequent imports will report nonsense. This import test - is done early (in the pytest configuration file, before any tests) in order to - avoid the noise of having all tests fail with identical error messages. - - Any possible exception is caught here and reported manually *without* the stack - trace. This further reduces noise since the trace would only show pytest internals - which are not useful for debugging pybind11 module issues. - """ - # noinspection PyBroadException - try: - import pybind11_tests # noqa: F401 imported but unused - except Exception as e: - print("Failed to import pybind11_tests from pytest:") - print(" {}: {}".format(type(e).__name__, e)) - sys.exit(1) - - -_test_import_pybind11() diff --git a/stormpy/resources/pybind11/tests/constructor_stats.h b/stormpy/resources/pybind11/tests/constructor_stats.h deleted file mode 100755 index eb3e49cab..000000000 --- a/stormpy/resources/pybind11/tests/constructor_stats.h +++ /dev/null @@ -1,249 +0,0 @@ -#pragma once -/* - tests/constructor_stats.h -- framework for printing and tracking object - instance lifetimes in example/test code. - - Copyright (c) 2016 Jason Rhinelander - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. - -This header provides a few useful tools for writing examples or tests that want to check and/or -display object instance lifetimes. It requires that you include this header and add the following -function calls to constructors: - - class MyClass { - MyClass() { ...; print_default_created(this); } - ~MyClass() { ...; print_destroyed(this); } - MyClass(const MyClass &c) { ...; print_copy_created(this); } - MyClass(MyClass &&c) { ...; print_move_created(this); } - MyClass(int a, int b) { ...; print_created(this, a, b); } - MyClass &operator=(const MyClass &c) { ...; print_copy_assigned(this); } - MyClass &operator=(MyClass &&c) { ...; print_move_assigned(this); } - - ... - } - -You can find various examples of these in several of the existing example .cpp files. (Of course -you don't need to add any of the above constructors/operators that you don't actually have, except -for the destructor). - -Each of these will print an appropriate message such as: - - ### MyClass @ 0x2801910 created via default constructor - ### MyClass @ 0x27fa780 created 100 200 - ### MyClass @ 0x2801910 destroyed - ### MyClass @ 0x27fa780 destroyed - -You can also include extra arguments (such as the 100, 200 in the output above, coming from the -value constructor) for all of the above methods which will be included in the output. - -For testing, each of these also keeps track the created instances and allows you to check how many -of the various constructors have been invoked from the Python side via code such as: - - from example import ConstructorStats - cstats = ConstructorStats.get(MyClass) - print(cstats.alive()) - print(cstats.default_constructions) - -Note that `.alive()` should usually be the first thing you call as it invokes Python's garbage -collector to actually destroy objects that aren't yet referenced. - -For everything except copy and move constructors and destructors, any extra values given to the -print_...() function is stored in a class-specific values list which you can retrieve and inspect -from the ConstructorStats instance `.values()` method. - -In some cases, when you need to track instances of a C++ class not registered with pybind11, you -need to add a function returning the ConstructorStats for the C++ class; this can be done with: - - m.def("get_special_cstats", &ConstructorStats::get, py::return_value_policy::reference) - -Finally, you can suppress the output messages, but keep the constructor tracking (for -inspection/testing in python) by using the functions with `print_` replaced with `track_` (e.g. -`track_copy_created(this)`). - -*/ - -#include "pybind11_tests.h" -#include -#include -#include -#include - -class ConstructorStats { -protected: - std::unordered_map _instances; // Need a map rather than set because members can shared address with parents - std::list _values; // Used to track values (e.g. of value constructors) -public: - int default_constructions = 0; - int copy_constructions = 0; - int move_constructions = 0; - int copy_assignments = 0; - int move_assignments = 0; - - void copy_created(void *inst) { - created(inst); - copy_constructions++; - } - void move_created(void *inst) { - created(inst); - move_constructions++; - } - void default_created(void *inst) { - created(inst); - default_constructions++; - } - void created(void *inst) { - ++_instances[inst]; - }; - void destroyed(void *inst) { - if (--_instances[inst] < 0) - throw std::runtime_error("cstats.destroyed() called with unknown instance; potential double-destruction or a missing cstats.created()"); - } - - int alive() { - // Force garbage collection to ensure any pending destructors are invoked: - py::module::import("gc").attr("collect")(); - int total = 0; - for (const auto &p : _instances) if (p.second > 0) total += p.second; - return total; - } - - void value() {} // Recursion terminator - // Takes one or more values, converts them to strings, then stores them. - template void value(const T &v, Tmore &&...args) { - std::ostringstream oss; - oss << v; - _values.push_back(oss.str()); - value(std::forward(args)...); - } - - // Move out stored values - py::list values() { - py::list l; - for (const auto &v : _values) l.append(py::cast(v)); - _values.clear(); - return l; - } - - // Gets constructor stats from a C++ type index - static ConstructorStats& get(std::type_index type) { - static std::unordered_map all_cstats; - return all_cstats[type]; - } - - // Gets constructor stats from a C++ type - template static ConstructorStats& get() { - return get(typeid(T)); - } - - // Gets constructor stats from a Python class - static ConstructorStats& get(py::object class_) { - auto &internals = py::detail::get_internals(); - const std::type_index *t1 = nullptr, *t2 = nullptr; - try { - auto *type_info = internals.registered_types_py.at(class_.ptr()); - for (auto &p : internals.registered_types_cpp) { - if (p.second == type_info) { - if (t1) { - t2 = &p.first; - break; - } - t1 = &p.first; - } - } - } - catch (std::out_of_range) {} - if (!t1) throw std::runtime_error("Unknown class passed to ConstructorStats::get()"); - auto &cs1 = get(*t1); - // If we have both a t1 and t2 match, one is probably the trampoline class; return whichever - // has more constructions (typically one or the other will be 0) - if (t2) { - auto &cs2 = get(*t2); - int cs1_total = cs1.default_constructions + cs1.copy_constructions + cs1.move_constructions + (int) cs1._values.size(); - int cs2_total = cs2.default_constructions + cs2.copy_constructions + cs2.move_constructions + (int) cs2._values.size(); - if (cs2_total > cs1_total) return cs2; - } - return cs1; - } -}; - -// To track construction/destruction, you need to call these methods from the various -// constructors/operators. The ones that take extra values record the given values in the -// constructor stats values for later inspection. -template void track_copy_created(T *inst) { ConstructorStats::get().copy_created(inst); } -template void track_move_created(T *inst) { ConstructorStats::get().move_created(inst); } -template void track_copy_assigned(T *, Values &&...values) { - auto &cst = ConstructorStats::get(); - cst.copy_assignments++; - cst.value(std::forward(values)...); -} -template void track_move_assigned(T *, Values &&...values) { - auto &cst = ConstructorStats::get(); - cst.move_assignments++; - cst.value(std::forward(values)...); -} -template void track_default_created(T *inst, Values &&...values) { - auto &cst = ConstructorStats::get(); - cst.default_created(inst); - cst.value(std::forward(values)...); -} -template void track_created(T *inst, Values &&...values) { - auto &cst = ConstructorStats::get(); - cst.created(inst); - cst.value(std::forward(values)...); -} -template void track_destroyed(T *inst) { - ConstructorStats::get().destroyed(inst); -} -template void track_values(T *, Values &&...values) { - ConstructorStats::get().value(std::forward(values)...); -} - -/// Don't cast pointers to Python, print them as strings -inline const char *format_ptrs(const char *p) { return p; } -template -py::str format_ptrs(T *p) { return "{:#x}"_s.format(reinterpret_cast(p)); } -template -auto format_ptrs(T &&x) -> decltype(std::forward(x)) { return std::forward(x); } - -template -void print_constr_details(T *inst, const std::string &action, Output &&...output) { - py::print("###", py::type_id(), "@", format_ptrs(inst), action, - format_ptrs(std::forward(output))...); -} - -// Verbose versions of the above: -template void print_copy_created(T *inst, Values &&...values) { // NB: this prints, but doesn't store, given values - print_constr_details(inst, "created via copy constructor", values...); - track_copy_created(inst); -} -template void print_move_created(T *inst, Values &&...values) { // NB: this prints, but doesn't store, given values - print_constr_details(inst, "created via move constructor", values...); - track_move_created(inst); -} -template void print_copy_assigned(T *inst, Values &&...values) { - print_constr_details(inst, "assigned via copy assignment", values...); - track_copy_assigned(inst, values...); -} -template void print_move_assigned(T *inst, Values &&...values) { - print_constr_details(inst, "assigned via move assignment", values...); - track_move_assigned(inst, values...); -} -template void print_default_created(T *inst, Values &&...values) { - print_constr_details(inst, "created via default constructor", values...); - track_default_created(inst, values...); -} -template void print_created(T *inst, Values &&...values) { - print_constr_details(inst, "created", values...); - track_created(inst, values...); -} -template void print_destroyed(T *inst, Values &&...values) { // Prints but doesn't store given values - print_constr_details(inst, "destroyed", values...); - track_destroyed(inst); -} -template void print_values(T *inst, Values &&...values) { - print_constr_details(inst, ":", values...); - track_values(inst, values...); -} - diff --git a/stormpy/resources/pybind11/tests/object.h b/stormpy/resources/pybind11/tests/object.h deleted file mode 100755 index 753f654b2..000000000 --- a/stormpy/resources/pybind11/tests/object.h +++ /dev/null @@ -1,175 +0,0 @@ -#if !defined(__OBJECT_H) -#define __OBJECT_H - -#include -#include "constructor_stats.h" - -/// Reference counted object base class -class Object { -public: - /// Default constructor - Object() { print_default_created(this); } - - /// Copy constructor - Object(const Object &) : m_refCount(0) { print_copy_created(this); } - - /// Return the current reference count - int getRefCount() const { return m_refCount; }; - - /// Increase the object's reference count by one - void incRef() const { ++m_refCount; } - - /** \brief Decrease the reference count of - * the object and possibly deallocate it. - * - * The object will automatically be deallocated once - * the reference count reaches zero. - */ - void decRef(bool dealloc = true) const { - --m_refCount; - if (m_refCount == 0 && dealloc) - delete this; - else if (m_refCount < 0) - throw std::runtime_error("Internal error: reference count < 0!"); - } - - virtual std::string toString() const = 0; -protected: - /** \brief Virtual protected deconstructor. - * (Will only be called by \ref ref) - */ - virtual ~Object() { print_destroyed(this); } -private: - mutable std::atomic m_refCount { 0 }; -}; - -// Tag class used to track constructions of ref objects. When we track constructors, below, we -// track and print out the actual class (e.g. ref), and *also* add a fake tracker for -// ref_tag. This lets us check that the total number of ref constructors/destructors is -// correct without having to check each individual ref type individually. -class ref_tag {}; - -/** - * \brief Reference counting helper - * - * The \a ref refeference template is a simple wrapper to store a - * pointer to an object. It takes care of increasing and decreasing - * the reference count of the object. When the last reference goes - * out of scope, the associated object will be deallocated. - * - * \ingroup libcore - */ -template class ref { -public: - /// Create a nullptr reference - ref() : m_ptr(nullptr) { print_default_created(this); track_default_created((ref_tag*) this); } - - /// Construct a reference from a pointer - ref(T *ptr) : m_ptr(ptr) { - if (m_ptr) ((Object *) m_ptr)->incRef(); - - print_created(this, "from pointer", m_ptr); track_created((ref_tag*) this, "from pointer"); - - } - - /// Copy constructor - ref(const ref &r) : m_ptr(r.m_ptr) { - if (m_ptr) - ((Object *) m_ptr)->incRef(); - - print_copy_created(this, "with pointer", m_ptr); track_copy_created((ref_tag*) this); - } - - /// Move constructor - ref(ref &&r) : m_ptr(r.m_ptr) { - r.m_ptr = nullptr; - - print_move_created(this, "with pointer", m_ptr); track_move_created((ref_tag*) this); - } - - /// Destroy this reference - ~ref() { - if (m_ptr) - ((Object *) m_ptr)->decRef(); - - print_destroyed(this); track_destroyed((ref_tag*) this); - } - - /// Move another reference into the current one - ref& operator=(ref&& r) { - print_move_assigned(this, "pointer", r.m_ptr); track_move_assigned((ref_tag*) this); - - if (*this == r) - return *this; - if (m_ptr) - ((Object *) m_ptr)->decRef(); - m_ptr = r.m_ptr; - r.m_ptr = nullptr; - return *this; - } - - /// Overwrite this reference with another reference - ref& operator=(const ref& r) { - print_copy_assigned(this, "pointer", r.m_ptr); track_copy_assigned((ref_tag*) this); - - if (m_ptr == r.m_ptr) - return *this; - if (m_ptr) - ((Object *) m_ptr)->decRef(); - m_ptr = r.m_ptr; - if (m_ptr) - ((Object *) m_ptr)->incRef(); - return *this; - } - - /// Overwrite this reference with a pointer to another object - ref& operator=(T *ptr) { - print_values(this, "assigned pointer"); track_values((ref_tag*) this, "assigned pointer"); - - if (m_ptr == ptr) - return *this; - if (m_ptr) - ((Object *) m_ptr)->decRef(); - m_ptr = ptr; - if (m_ptr) - ((Object *) m_ptr)->incRef(); - return *this; - } - - /// Compare this reference with another reference - bool operator==(const ref &r) const { return m_ptr == r.m_ptr; } - - /// Compare this reference with another reference - bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; } - - /// Compare this reference with a pointer - bool operator==(const T* ptr) const { return m_ptr == ptr; } - - /// Compare this reference with a pointer - bool operator!=(const T* ptr) const { return m_ptr != ptr; } - - /// Access the object referenced by this reference - T* operator->() { return m_ptr; } - - /// Access the object referenced by this reference - const T* operator->() const { return m_ptr; } - - /// Return a C++ reference to the referenced object - T& operator*() { return *m_ptr; } - - /// Return a const C++ reference to the referenced object - const T& operator*() const { return *m_ptr; } - - /// Return a pointer to the referenced object - operator T* () { return m_ptr; } - - /// Return a const pointer to the referenced object - T* get() { return m_ptr; } - - /// Return a pointer to the referenced object - const T* get() const { return m_ptr; } -private: - T *m_ptr; -}; - -#endif /* __OBJECT_H */ diff --git a/stormpy/resources/pybind11/tests/pybind11_tests.cpp b/stormpy/resources/pybind11/tests/pybind11_tests.cpp deleted file mode 100755 index 35981a0a6..000000000 --- a/stormpy/resources/pybind11/tests/pybind11_tests.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - tests/pybind11_tests.cpp -- pybind example plugin - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" - -std::list> &initializers() { - static std::list> inits; - return inits; -} - -test_initializer::test_initializer(std::function initializer) { - initializers().push_back(std::move(initializer)); -} - -void bind_ConstructorStats(py::module &m) { - py::class_(m, "ConstructorStats") - .def("alive", &ConstructorStats::alive) - .def("values", &ConstructorStats::values) - .def_readwrite("default_constructions", &ConstructorStats::default_constructions) - .def_readwrite("copy_assignments", &ConstructorStats::copy_assignments) - .def_readwrite("move_assignments", &ConstructorStats::move_assignments) - .def_readwrite("copy_constructions", &ConstructorStats::copy_constructions) - .def_readwrite("move_constructions", &ConstructorStats::move_constructions) - .def_static("get", (ConstructorStats &(*)(py::object)) &ConstructorStats::get, py::return_value_policy::reference_internal); -} - -PYBIND11_PLUGIN(pybind11_tests) { - py::module m("pybind11_tests", "pybind example plugin"); - - bind_ConstructorStats(m); - - for (const auto &initializer : initializers()) - initializer(m); - - if (!py::hasattr(m, "have_eigen")) m.attr("have_eigen") = py::cast(false); - - return m.ptr(); -} diff --git a/stormpy/resources/pybind11/tests/pybind11_tests.h b/stormpy/resources/pybind11/tests/pybind11_tests.h deleted file mode 100755 index c11b687b2..000000000 --- a/stormpy/resources/pybind11/tests/pybind11_tests.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include -#include -#include - -namespace py = pybind11; -using namespace pybind11::literals; - -class test_initializer { -public: - test_initializer(std::function initializer); -}; diff --git a/stormpy/resources/pybind11/tests/test_alias_initialization.cpp b/stormpy/resources/pybind11/tests/test_alias_initialization.cpp deleted file mode 100755 index 48e595695..000000000 --- a/stormpy/resources/pybind11/tests/test_alias_initialization.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - tests/test_alias_initialization.cpp -- test cases and example of different trampoline - initialization modes - - Copyright (c) 2016 Wenzel Jakob , Jason Rhinelander - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -test_initializer alias_initialization([](py::module &m) { - // don't invoke Python dispatch classes by default when instantiating C++ classes that were not - // extended on the Python side - struct A { - virtual ~A() {} - virtual void f() { py::print("A.f()"); } - }; - - struct PyA : A { - PyA() { py::print("PyA.PyA()"); } - ~PyA() { py::print("PyA.~PyA()"); } - - void f() override { - py::print("PyA.f()"); - PYBIND11_OVERLOAD(void, A, f); - } - }; - - auto call_f = [](A *a) { a->f(); }; - - py::class_(m, "A") - .def(py::init<>()) - .def("f", &A::f); - - m.def("call_f", call_f); - - - // ... unless we explicitly request it, as in this example: - struct A2 { - virtual ~A2() {} - virtual void f() { py::print("A2.f()"); } - }; - - struct PyA2 : A2 { - PyA2() { py::print("PyA2.PyA2()"); } - ~PyA2() { py::print("PyA2.~PyA2()"); } - void f() override { - py::print("PyA2.f()"); - PYBIND11_OVERLOAD(void, A2, f); - } - }; - - py::class_(m, "A2") - .def(py::init_alias<>()) - .def("f", &A2::f); - - m.def("call_f", [](A2 *a2) { a2->f(); }); - -}); - diff --git a/stormpy/resources/pybind11/tests/test_alias_initialization.py b/stormpy/resources/pybind11/tests/test_alias_initialization.py deleted file mode 100755 index 0ed9d2f79..000000000 --- a/stormpy/resources/pybind11/tests/test_alias_initialization.py +++ /dev/null @@ -1,79 +0,0 @@ -import gc - - -def test_alias_delay_initialization1(capture): - """A only initializes its trampoline class when we inherit from it; if we just - create and use an A instance directly, the trampoline initialization is bypassed - and we only initialize an A() instead (for performance reasons). - """ - from pybind11_tests import A, call_f - - class B(A): - def __init__(self): - super(B, self).__init__() - - def f(self): - print("In python f()") - - # C++ version - with capture: - a = A() - call_f(a) - del a - gc.collect() - assert capture == "A.f()" - - # Python version - with capture: - b = B() - call_f(b) - del b - gc.collect() - assert capture == """ - PyA.PyA() - PyA.f() - In python f() - PyA.~PyA() - """ - - -def test_alias_delay_initialization2(capture): - """A2, unlike the above, is configured to always initialize the alias; while - the extra initialization and extra class layer has small virtual dispatch - performance penalty, it also allows us to do more things with the trampoline - class such as defining local variables and performing construction/destruction. - """ - from pybind11_tests import A2, call_f - - class B2(A2): - def __init__(self): - super(B2, self).__init__() - - def f(self): - print("In python B2.f()") - - # No python subclass version - with capture: - a2 = A2() - call_f(a2) - del a2 - gc.collect() - assert capture == """ - PyA2.PyA2() - PyA2.f() - A2.f() - PyA2.~PyA2() - """ - - # Python subclass version - with capture: - b2 = B2() - call_f(b2) - del b2 - gc.collect() - assert capture == """ - PyA2.PyA2() - PyA2.f() - In python B2.f() - PyA2.~PyA2() - """ diff --git a/stormpy/resources/pybind11/tests/test_buffers.cpp b/stormpy/resources/pybind11/tests/test_buffers.cpp deleted file mode 100755 index c3a7a9e02..000000000 --- a/stormpy/resources/pybind11/tests/test_buffers.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - tests/test_buffers.cpp -- supporting Pythons' buffer protocol - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" - -class Matrix { -public: - Matrix(size_t rows, size_t cols) : m_rows(rows), m_cols(cols) { - print_created(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); - m_data = new float[rows*cols]; - memset(m_data, 0, sizeof(float) * rows * cols); - } - - Matrix(const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) { - print_copy_created(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); - m_data = new float[m_rows * m_cols]; - memcpy(m_data, s.m_data, sizeof(float) * m_rows * m_cols); - } - - Matrix(Matrix &&s) : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) { - print_move_created(this); - s.m_rows = 0; - s.m_cols = 0; - s.m_data = nullptr; - } - - ~Matrix() { - print_destroyed(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); - delete[] m_data; - } - - Matrix &operator=(const Matrix &s) { - print_copy_assigned(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); - delete[] m_data; - m_rows = s.m_rows; - m_cols = s.m_cols; - m_data = new float[m_rows * m_cols]; - memcpy(m_data, s.m_data, sizeof(float) * m_rows * m_cols); - return *this; - } - - Matrix &operator=(Matrix &&s) { - print_move_assigned(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); - if (&s != this) { - delete[] m_data; - m_rows = s.m_rows; m_cols = s.m_cols; m_data = s.m_data; - s.m_rows = 0; s.m_cols = 0; s.m_data = nullptr; - } - return *this; - } - - float operator()(size_t i, size_t j) const { - return m_data[i*m_cols + j]; - } - - float &operator()(size_t i, size_t j) { - return m_data[i*m_cols + j]; - } - - float *data() { return m_data; } - - size_t rows() const { return m_rows; } - size_t cols() const { return m_cols; } -private: - size_t m_rows; - size_t m_cols; - float *m_data; -}; - -test_initializer buffers([](py::module &m) { - py::class_ mtx(m, "Matrix"); - - mtx.def(py::init()) - /// Construct from a buffer - .def("__init__", [](Matrix &v, py::buffer b) { - py::buffer_info info = b.request(); - if (info.format != py::format_descriptor::format() || info.ndim != 2) - throw std::runtime_error("Incompatible buffer format!"); - new (&v) Matrix(info.shape[0], info.shape[1]); - memcpy(v.data(), info.ptr, sizeof(float) * v.rows() * v.cols()); - }) - - .def("rows", &Matrix::rows) - .def("cols", &Matrix::cols) - - /// Bare bones interface - .def("__getitem__", [](const Matrix &m, std::pair i) { - if (i.first >= m.rows() || i.second >= m.cols()) - throw py::index_error(); - return m(i.first, i.second); - }) - .def("__setitem__", [](Matrix &m, std::pair i, float v) { - if (i.first >= m.rows() || i.second >= m.cols()) - throw py::index_error(); - m(i.first, i.second) = v; - }) - /// Provide buffer access - .def_buffer([](Matrix &m) -> py::buffer_info { - return py::buffer_info( - m.data(), /* Pointer to buffer */ - sizeof(float), /* Size of one scalar */ - py::format_descriptor::format(), /* Python struct-style format descriptor */ - 2, /* Number of dimensions */ - { m.rows(), m.cols() }, /* Buffer dimensions */ - { sizeof(float) * m.rows(), /* Strides (in bytes) for each index */ - sizeof(float) } - ); - }) - ; -}); diff --git a/stormpy/resources/pybind11/tests/test_buffers.py b/stormpy/resources/pybind11/tests/test_buffers.py deleted file mode 100755 index f0ea964d9..000000000 --- a/stormpy/resources/pybind11/tests/test_buffers.py +++ /dev/null @@ -1,57 +0,0 @@ -import pytest -from pybind11_tests import Matrix, ConstructorStats - -with pytest.suppress(ImportError): - import numpy as np - - -@pytest.requires_numpy -def test_to_python(): - m = Matrix(5, 5) - - assert m[2, 3] == 0 - m[2, 3] = 4 - assert m[2, 3] == 4 - - m2 = np.array(m, copy=False) - assert m2.shape == (5, 5) - assert abs(m2).sum() == 4 - assert m2[2, 3] == 4 - m2[2, 3] = 5 - assert m2[2, 3] == 5 - - cstats = ConstructorStats.get(Matrix) - assert cstats.alive() == 1 - del m - assert cstats.alive() == 1 - del m2 # holds an m reference - assert cstats.alive() == 0 - assert cstats.values() == ["5x5 matrix"] - assert cstats.copy_constructions == 0 - # assert cstats.move_constructions >= 0 # Don't invoke any - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 - - -@pytest.requires_numpy -def test_from_python(): - with pytest.raises(RuntimeError) as excinfo: - Matrix(np.array([1, 2, 3])) # trying to assign a 1D array - assert str(excinfo.value) == "Incompatible buffer format!" - - m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32) - m4 = Matrix(m3) - - for i in range(m4.rows()): - for j in range(m4.cols()): - assert m3[i, j] == m4[i, j] - - cstats = ConstructorStats.get(Matrix) - assert cstats.alive() == 1 - del m3, m4 - assert cstats.alive() == 0 - assert cstats.values() == ["2x3 matrix"] - assert cstats.copy_constructions == 0 - # assert cstats.move_constructions >= 0 # Don't invoke any - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 diff --git a/stormpy/resources/pybind11/tests/test_callbacks.cpp b/stormpy/resources/pybind11/tests/test_callbacks.cpp deleted file mode 100755 index 31d4e39aa..000000000 --- a/stormpy/resources/pybind11/tests/test_callbacks.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - tests/test_callbacks.cpp -- callbacks - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" -#include - - -py::object test_callback1(py::object func) { - return func(); -} - -py::tuple test_callback2(py::object func) { - return func("Hello", 'x', true, 5); -} - -std::string test_callback3(const std::function &func) { - return "func(43) = " + std::to_string(func(43)); -} - -std::function test_callback4() { - return [](int i) { return i+1; }; -} - -py::cpp_function test_callback5() { - return py::cpp_function([](int i) { return i+1; }, - py::arg("number")); -} - -int dummy_function(int i) { return i + 1; } -int dummy_function2(int i, int j) { return i + j; } -std::function roundtrip(std::function f, bool expect_none = false) { - if (expect_none && f) { - throw std::runtime_error("Expected None to be converted to empty std::function"); - } - return f; -} - -std::string test_dummy_function(const std::function &f) { - using fn_type = int (*)(int); - auto result = f.target(); - if (!result) { - auto r = f(1); - return "can't convert to function pointer: eval(1) = " + std::to_string(r); - } else if (*result == dummy_function) { - auto r = (*result)(1); - return "matches dummy_function: eval(1) = " + std::to_string(r); - } else { - return "argument does NOT match dummy_function. This should never happen!"; - } -} - -struct Payload { - Payload() { - print_default_created(this); - } - ~Payload() { - print_destroyed(this); - } - Payload(const Payload &) { - print_copy_created(this); - } - Payload(Payload &&) { - print_move_created(this); - } -}; - -/// Something to trigger a conversion error -struct Unregistered {}; - -test_initializer callbacks([](py::module &m) { - m.def("test_callback1", &test_callback1); - m.def("test_callback2", &test_callback2); - m.def("test_callback3", &test_callback3); - m.def("test_callback4", &test_callback4); - m.def("test_callback5", &test_callback5); - - // Test keyword args and generalized unpacking - m.def("test_tuple_unpacking", [](py::function f) { - auto t1 = py::make_tuple(2, 3); - auto t2 = py::make_tuple(5, 6); - return f("positional", 1, *t1, 4, *t2); - }); - - m.def("test_dict_unpacking", [](py::function f) { - auto d1 = py::dict("key"_a="value", "a"_a=1); - auto d2 = py::dict(); - auto d3 = py::dict("b"_a=2); - return f("positional", 1, **d1, **d2, **d3); - }); - - m.def("test_keyword_args", [](py::function f) { - return f("x"_a=10, "y"_a=20); - }); - - m.def("test_unpacking_and_keywords1", [](py::function f) { - auto args = py::make_tuple(2); - auto kwargs = py::dict("d"_a=4); - return f(1, *args, "c"_a=3, **kwargs); - }); - - m.def("test_unpacking_and_keywords2", [](py::function f) { - auto kwargs1 = py::dict("a"_a=1); - auto kwargs2 = py::dict("c"_a=3, "d"_a=4); - return f("positional", *py::make_tuple(1), 2, *py::make_tuple(3, 4), 5, - "key"_a="value", **kwargs1, "b"_a=2, **kwargs2, "e"_a=5); - }); - - m.def("test_unpacking_error1", [](py::function f) { - auto kwargs = py::dict("x"_a=3); - return f("x"_a=1, "y"_a=2, **kwargs); // duplicate ** after keyword - }); - - m.def("test_unpacking_error2", [](py::function f) { - auto kwargs = py::dict("x"_a=3); - return f(**kwargs, "x"_a=1); // duplicate keyword after ** - }); - - m.def("test_arg_conversion_error1", [](py::function f) { - f(234, Unregistered(), "kw"_a=567); - }); - - m.def("test_arg_conversion_error2", [](py::function f) { - f(234, "expected_name"_a=Unregistered(), "kw"_a=567); - }); - - /* Test cleanup of lambda closure */ - m.def("test_cleanup", []() -> std::function { - Payload p; - - return [p]() { - /* p should be cleaned up when the returned function is garbage collected */ - }; - }); - - /* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */ - m.def("dummy_function", &dummy_function); - m.def("dummy_function2", &dummy_function2); - m.def("roundtrip", &roundtrip, py::arg("f"), py::arg("expect_none")=false); - m.def("test_dummy_function", &test_dummy_function); - // Export the payload constructor statistics for testing purposes: - m.def("payload_cstats", &ConstructorStats::get); -}); diff --git a/stormpy/resources/pybind11/tests/test_callbacks.py b/stormpy/resources/pybind11/tests/test_callbacks.py deleted file mode 100755 index c2668aa95..000000000 --- a/stormpy/resources/pybind11/tests/test_callbacks.py +++ /dev/null @@ -1,98 +0,0 @@ -import pytest - - -def test_callbacks(): - from functools import partial - from pybind11_tests import (test_callback1, test_callback2, test_callback3, - test_callback4, test_callback5) - - def func1(): - return "func1" - - def func2(a, b, c, d): - return "func2", a, b, c, d - - def func3(a): - return "func3({})".format(a) - - assert test_callback1(func1) == "func1" - assert test_callback2(func2) == ("func2", "Hello", "x", True, 5) - assert test_callback1(partial(func2, 1, 2, 3, 4)) == ("func2", 1, 2, 3, 4) - assert test_callback1(partial(func3, "partial")) == "func3(partial)" - assert test_callback3(lambda i: i + 1) == "func(43) = 44" - - f = test_callback4() - assert f(43) == 44 - f = test_callback5() - assert f(number=43) == 44 - - -def test_keyword_args_and_generalized_unpacking(): - from pybind11_tests import (test_tuple_unpacking, test_dict_unpacking, test_keyword_args, - test_unpacking_and_keywords1, test_unpacking_and_keywords2, - test_unpacking_error1, test_unpacking_error2, - test_arg_conversion_error1, test_arg_conversion_error2) - - def f(*args, **kwargs): - return args, kwargs - - assert test_tuple_unpacking(f) == (("positional", 1, 2, 3, 4, 5, 6), {}) - assert test_dict_unpacking(f) == (("positional", 1), {"key": "value", "a": 1, "b": 2}) - assert test_keyword_args(f) == ((), {"x": 10, "y": 20}) - assert test_unpacking_and_keywords1(f) == ((1, 2), {"c": 3, "d": 4}) - assert test_unpacking_and_keywords2(f) == ( - ("positional", 1, 2, 3, 4, 5), - {"key": "value", "a": 1, "b": 2, "c": 3, "d": 4, "e": 5} - ) - - with pytest.raises(TypeError) as excinfo: - test_unpacking_error1(f) - assert "Got multiple values for keyword argument" in str(excinfo.value) - - with pytest.raises(TypeError) as excinfo: - test_unpacking_error2(f) - assert "Got multiple values for keyword argument" in str(excinfo.value) - - with pytest.raises(RuntimeError) as excinfo: - test_arg_conversion_error1(f) - assert "Unable to convert call argument" in str(excinfo.value) - - with pytest.raises(RuntimeError) as excinfo: - test_arg_conversion_error2(f) - assert "Unable to convert call argument" in str(excinfo.value) - - -def test_lambda_closure_cleanup(): - from pybind11_tests import test_cleanup, payload_cstats - - test_cleanup() - cstats = payload_cstats() - assert cstats.alive() == 0 - assert cstats.copy_constructions == 1 - assert cstats.move_constructions >= 1 - - -def test_cpp_function_roundtrip(): - """Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer""" - from pybind11_tests import dummy_function, dummy_function2, test_dummy_function, roundtrip - - assert test_dummy_function(dummy_function) == "matches dummy_function: eval(1) = 2" - assert test_dummy_function(roundtrip(dummy_function)) == "matches dummy_function: eval(1) = 2" - assert roundtrip(None, expect_none=True) is None - assert test_dummy_function(lambda x: x + 2) == "can't convert to function pointer: eval(1) = 3" - - with pytest.raises(TypeError) as excinfo: - test_dummy_function(dummy_function2) - assert "incompatible function arguments" in str(excinfo.value) - - with pytest.raises(TypeError) as excinfo: - test_dummy_function(lambda x, y: x + y) - assert any(s in str(excinfo.value) for s in ("missing 1 required positional argument", - "takes exactly 2 arguments")) - - -def test_function_signatures(doc): - from pybind11_tests import test_callback3, test_callback4 - - assert doc(test_callback3) == "test_callback3(arg0: Callable[[int], int]) -> str" - assert doc(test_callback4) == "test_callback4() -> Callable[[int], int]" diff --git a/stormpy/resources/pybind11/tests/test_chrono.cpp b/stormpy/resources/pybind11/tests/test_chrono.cpp deleted file mode 100755 index b86f57adf..000000000 --- a/stormpy/resources/pybind11/tests/test_chrono.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - tests/test_chrono.cpp -- test conversions to/from std::chrono types - - Copyright (c) 2016 Trent Houliston and - Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - - -#include "pybind11_tests.h" -#include "constructor_stats.h" -#include - -// Return the current time off the wall clock -std::chrono::system_clock::time_point test_chrono1() { - return std::chrono::system_clock::now(); -} - -// Round trip the passed in system clock time -std::chrono::system_clock::time_point test_chrono2(std::chrono::system_clock::time_point t) { - return t; -} - -// Round trip the passed in duration -std::chrono::system_clock::duration test_chrono3(std::chrono::system_clock::duration d) { - return d; -} - -// Difference between two passed in time_points -std::chrono::system_clock::duration test_chrono4(std::chrono::system_clock::time_point a, std::chrono::system_clock::time_point b) { - return a - b; -} - -// Return the current time off the steady_clock -std::chrono::steady_clock::time_point test_chrono5() { - return std::chrono::steady_clock::now(); -} - -// Round trip a steady clock timepoint -std::chrono::steady_clock::time_point test_chrono6(std::chrono::steady_clock::time_point t) { - return t; -} - -// Roundtrip a duration in microseconds from a float argument -std::chrono::microseconds test_chrono7(std::chrono::microseconds t) { - return t; -} - -test_initializer chrono([] (py::module &m) { - m.def("test_chrono1", &test_chrono1); - m.def("test_chrono2", &test_chrono2); - m.def("test_chrono3", &test_chrono3); - m.def("test_chrono4", &test_chrono4); - m.def("test_chrono5", &test_chrono5); - m.def("test_chrono6", &test_chrono6); - m.def("test_chrono7", &test_chrono7); -}); diff --git a/stormpy/resources/pybind11/tests/test_chrono.py b/stormpy/resources/pybind11/tests/test_chrono.py deleted file mode 100755 index 94ca55c76..000000000 --- a/stormpy/resources/pybind11/tests/test_chrono.py +++ /dev/null @@ -1,116 +0,0 @@ - - -def test_chrono_system_clock(): - from pybind11_tests import test_chrono1 - import datetime - - # Get the time from both c++ and datetime - date1 = test_chrono1() - date2 = datetime.datetime.today() - - # The returned value should be a datetime - assert isinstance(date1, datetime.datetime) - - # The numbers should vary by a very small amount (time it took to execute) - diff = abs(date1 - date2) - - # There should never be a days/seconds difference - assert diff.days == 0 - assert diff.seconds == 0 - - # We test that no more than about 0.5 seconds passes here - # This makes sure that the dates created are very close to the same - # but if the testing system is incredibly overloaded this should still pass - assert diff.microseconds < 500000 - - -def test_chrono_system_clock_roundtrip(): - from pybind11_tests import test_chrono2 - import datetime - - date1 = datetime.datetime.today() - - # Roundtrip the time - date2 = test_chrono2(date1) - - # The returned value should be a datetime - assert isinstance(date2, datetime.datetime) - - # They should be identical (no information lost on roundtrip) - diff = abs(date1 - date2) - assert diff.days == 0 - assert diff.seconds == 0 - assert diff.microseconds == 0 - - -def test_chrono_duration_roundtrip(): - from pybind11_tests import test_chrono3 - import datetime - - # Get the difference between two times (a timedelta) - date1 = datetime.datetime.today() - date2 = datetime.datetime.today() - diff = date2 - date1 - - # Make sure this is a timedelta - assert isinstance(diff, datetime.timedelta) - - cpp_diff = test_chrono3(diff) - - assert cpp_diff.days == diff.days - assert cpp_diff.seconds == diff.seconds - assert cpp_diff.microseconds == diff.microseconds - - -def test_chrono_duration_subtraction_equivalence(): - from pybind11_tests import test_chrono4 - import datetime - - date1 = datetime.datetime.today() - date2 = datetime.datetime.today() - - diff = date2 - date1 - cpp_diff = test_chrono4(date2, date1) - - assert cpp_diff.days == diff.days - assert cpp_diff.seconds == diff.seconds - assert cpp_diff.microseconds == diff.microseconds - - -def test_chrono_steady_clock(): - from pybind11_tests import test_chrono5 - import datetime - - time1 = test_chrono5() - time2 = test_chrono5() - - assert isinstance(time1, datetime.timedelta) - assert isinstance(time2, datetime.timedelta) - - -def test_chrono_steady_clock_roundtrip(): - from pybind11_tests import test_chrono6 - import datetime - - time1 = datetime.timedelta(days=10, seconds=10, microseconds=100) - time2 = test_chrono6(time1) - - assert isinstance(time2, datetime.timedelta) - - # They should be identical (no information lost on roundtrip) - assert time1.days == time2.days - assert time1.seconds == time2.seconds - assert time1.microseconds == time2.microseconds - - -def test_floating_point_duration(): - from pybind11_tests import test_chrono7 - import datetime - - # Test using 35.525123 seconds as an example floating point number in seconds - time = test_chrono7(35.525123) - - assert isinstance(time, datetime.timedelta) - - assert time.seconds == 35 - assert 525122 <= time.microseconds <= 525123 diff --git a/stormpy/resources/pybind11/tests/test_class_args.cpp b/stormpy/resources/pybind11/tests/test_class_args.cpp deleted file mode 100755 index e18b39db2..000000000 --- a/stormpy/resources/pybind11/tests/test_class_args.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - tests/test_class_args.cpp -- tests that various way of defining a class work - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - - -template class BreaksBase {}; -template class BreaksTramp : public BreaksBase {}; -// These should all compile just fine: -typedef py::class_, std::unique_ptr>, BreaksTramp<1>> DoesntBreak1; -typedef py::class_, BreaksTramp<2>, std::unique_ptr>> DoesntBreak2; -typedef py::class_, std::unique_ptr>> DoesntBreak3; -typedef py::class_, BreaksTramp<4>> DoesntBreak4; -typedef py::class_> DoesntBreak5; -typedef py::class_, std::shared_ptr>, BreaksTramp<6>> DoesntBreak6; -typedef py::class_, BreaksTramp<7>, std::shared_ptr>> DoesntBreak7; -typedef py::class_, std::shared_ptr>> DoesntBreak8; -#define CHECK_BASE(N) static_assert(std::is_same>::value, \ - "DoesntBreak" #N " has wrong type!") -CHECK_BASE(1); CHECK_BASE(2); CHECK_BASE(3); CHECK_BASE(4); CHECK_BASE(5); CHECK_BASE(6); CHECK_BASE(7); CHECK_BASE(8); -#define CHECK_ALIAS(N) static_assert(DoesntBreak##N::has_alias && std::is_same>::value, \ - "DoesntBreak" #N " has wrong type_alias!") -#define CHECK_NOALIAS(N) static_assert(!DoesntBreak##N::has_alias && std::is_void::value, \ - "DoesntBreak" #N " has type alias, but shouldn't!") -CHECK_ALIAS(1); CHECK_ALIAS(2); CHECK_NOALIAS(3); CHECK_ALIAS(4); CHECK_NOALIAS(5); CHECK_ALIAS(6); CHECK_ALIAS(7); CHECK_NOALIAS(8); -#define CHECK_HOLDER(N, TYPE) static_assert(std::is_same>>::value, \ - "DoesntBreak" #N " has wrong holder_type!") -CHECK_HOLDER(1, unique); CHECK_HOLDER(2, unique); CHECK_HOLDER(3, unique); CHECK_HOLDER(4, unique); CHECK_HOLDER(5, unique); -CHECK_HOLDER(6, shared); CHECK_HOLDER(7, shared); CHECK_HOLDER(8, shared); - -// There's no nice way to test that these fail because they fail to compile; leave them here, -// though, so that they can be manually tested by uncommenting them (and seeing that compilation -// failures occurs). - -// We have to actually look into the type: the typedef alone isn't enough to instantiate the type: -#define CHECK_BROKEN(N) static_assert(std::is_same>::value, \ - "Breaks1 has wrong type!"); - -//// Two holder classes: -//typedef py::class_, std::unique_ptr>, std::unique_ptr>> Breaks1; -//CHECK_BROKEN(1); -//// Two aliases: -//typedef py::class_, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2; -//CHECK_BROKEN(2); -//// Holder + 2 aliases -//typedef py::class_, std::unique_ptr>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3; -//CHECK_BROKEN(3); -//// Alias + 2 holders -//typedef py::class_, std::unique_ptr>, BreaksTramp<-4>, std::shared_ptr>> Breaks4; -//CHECK_BROKEN(4); -//// Invalid option (not a subclass or holder) -//typedef py::class_, BreaksTramp<-4>> Breaks5; -//CHECK_BROKEN(5); -//// Invalid option: multiple inheritance not supported: -//template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {}; -//typedef py::class_, BreaksBase<-6>, BreaksBase<-7>> Breaks8; -//CHECK_BROKEN(8); - -test_initializer class_args([](py::module &m) { - // Just test that this compiled okay - m.def("class_args_noop", []() {}); -}); diff --git a/stormpy/resources/pybind11/tests/test_class_args.py b/stormpy/resources/pybind11/tests/test_class_args.py deleted file mode 100755 index 91b0320d8..000000000 --- a/stormpy/resources/pybind11/tests/test_class_args.py +++ /dev/null @@ -1,6 +0,0 @@ - - -def test_class_args(): - # There's basically nothing to test here; just make sure the code compiled and declared its definition - from pybind11_tests import class_args_noop - class_args_noop() diff --git a/stormpy/resources/pybind11/tests/test_constants_and_functions.cpp b/stormpy/resources/pybind11/tests/test_constants_and_functions.cpp deleted file mode 100755 index 29a27965a..000000000 --- a/stormpy/resources/pybind11/tests/test_constants_and_functions.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - tests/test_constants_and_functions.cpp -- global constants and functions, enumerations, raw byte strings - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -enum MyEnum { EFirstEntry = 1, ESecondEntry }; - -std::string test_function1() { - return "test_function()"; -} - -std::string test_function2(MyEnum k) { - return "test_function(enum=" + std::to_string(k) + ")"; -} - -std::string test_function3(int i) { - return "test_function(" + std::to_string(i) + ")"; -} - -py::bytes return_bytes() { - const char *data = "\x01\x00\x02\x00"; - return std::string(data, 4); -} - -std::string print_bytes(py::bytes bytes) { - std::string ret = "bytes["; - const auto value = static_cast(bytes); - for (size_t i = 0; i < value.length(); ++i) { - ret += std::to_string(static_cast(value[i])) + " "; - } - ret.back() = ']'; - return ret; -} - -test_initializer constants_and_functions([](py::module &m) { - m.attr("some_constant") = py::int_(14); - - m.def("test_function", &test_function1); - m.def("test_function", &test_function2); - m.def("test_function", &test_function3); - - py::enum_(m, "MyEnum") - .value("EFirstEntry", EFirstEntry) - .value("ESecondEntry", ESecondEntry) - .export_values(); - - m.def("return_bytes", &return_bytes); - m.def("print_bytes", &print_bytes); -}); diff --git a/stormpy/resources/pybind11/tests/test_constants_and_functions.py b/stormpy/resources/pybind11/tests/test_constants_and_functions.py deleted file mode 100755 index 2c6321e05..000000000 --- a/stormpy/resources/pybind11/tests/test_constants_and_functions.py +++ /dev/null @@ -1,21 +0,0 @@ - - -def test_constants(): - from pybind11_tests import some_constant - - assert some_constant == 14 - - -def test_function_overloading(): - from pybind11_tests import MyEnum, test_function - - assert test_function() == "test_function()" - assert test_function(7) == "test_function(7)" - assert test_function(MyEnum.EFirstEntry) == "test_function(enum=1)" - assert test_function(MyEnum.ESecondEntry) == "test_function(enum=2)" - - -def test_bytes(): - from pybind11_tests import return_bytes, print_bytes - - assert print_bytes(return_bytes()) == "bytes[1 0 2 0]" diff --git a/stormpy/resources/pybind11/tests/test_copy_move_policies.cpp b/stormpy/resources/pybind11/tests/test_copy_move_policies.cpp deleted file mode 100755 index 6f7907c1f..000000000 --- a/stormpy/resources/pybind11/tests/test_copy_move_policies.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - tests/test_copy_move_policies.cpp -- 'copy' and 'move' - return value policies - - Copyright (c) 2016 Ben North - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -template -struct empty { - static const derived& get_one() { return instance_; } - static derived instance_; -}; - -struct lacking_copy_ctor : public empty { - lacking_copy_ctor() {} - lacking_copy_ctor(const lacking_copy_ctor& other) = delete; -}; - -template <> lacking_copy_ctor empty::instance_ = {}; - -struct lacking_move_ctor : public empty { - lacking_move_ctor() {} - lacking_move_ctor(const lacking_move_ctor& other) = delete; - lacking_move_ctor(lacking_move_ctor&& other) = delete; -}; - -template <> lacking_move_ctor empty::instance_ = {}; - -test_initializer copy_move_policies([](py::module &m) { - py::class_(m, "lacking_copy_ctor") - .def_static("get_one", &lacking_copy_ctor::get_one, - py::return_value_policy::copy); - py::class_(m, "lacking_move_ctor") - .def_static("get_one", &lacking_move_ctor::get_one, - py::return_value_policy::move); -}); diff --git a/stormpy/resources/pybind11/tests/test_copy_move_policies.py b/stormpy/resources/pybind11/tests/test_copy_move_policies.py deleted file mode 100755 index edcf38075..000000000 --- a/stormpy/resources/pybind11/tests/test_copy_move_policies.py +++ /dev/null @@ -1,15 +0,0 @@ -import pytest - - -def test_lacking_copy_ctor(): - from pybind11_tests import lacking_copy_ctor - with pytest.raises(RuntimeError) as excinfo: - lacking_copy_ctor.get_one() - assert "the object is non-copyable!" in str(excinfo.value) - - -def test_lacking_move_ctor(): - from pybind11_tests import lacking_move_ctor - with pytest.raises(RuntimeError) as excinfo: - lacking_move_ctor.get_one() - assert "the object is neither movable nor copyable!" in str(excinfo.value) diff --git a/stormpy/resources/pybind11/tests/test_docstring_options.cpp b/stormpy/resources/pybind11/tests/test_docstring_options.cpp deleted file mode 100755 index 74178c272..000000000 --- a/stormpy/resources/pybind11/tests/test_docstring_options.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - tests/test_docstring_options.cpp -- generation of docstrings and signatures - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -struct DocstringTestFoo { - int value; - void setValue(int v) { value = v; } - int getValue() const { return value; } -}; - -test_initializer docstring_generation([](py::module &m) { - - { - py::options options; - options.disable_function_signatures(); - - m.def("test_function1", [](int, int) {}, py::arg("a"), py::arg("b")); - m.def("test_function2", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); - - options.enable_function_signatures(); - - m.def("test_function3", [](int, int) {}, py::arg("a"), py::arg("b")); - m.def("test_function4", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); - - options.disable_function_signatures().disable_user_defined_docstrings(); - - m.def("test_function5", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); - - { - py::options nested_options; - nested_options.enable_user_defined_docstrings(); - m.def("test_function6", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); - } - } - - m.def("test_function7", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); - - { - py::options options; - options.disable_user_defined_docstrings(); - - py::class_(m, "DocstringTestFoo", "This is a class docstring") - .def_property("value_prop", &DocstringTestFoo::getValue, &DocstringTestFoo::setValue, "This is a property docstring") - ; - } -}); diff --git a/stormpy/resources/pybind11/tests/test_docstring_options.py b/stormpy/resources/pybind11/tests/test_docstring_options.py deleted file mode 100755 index 66ad6b89f..000000000 --- a/stormpy/resources/pybind11/tests/test_docstring_options.py +++ /dev/null @@ -1,32 +0,0 @@ - - -def test_docstring_options(): - from pybind11_tests import (test_function1, test_function2, test_function3, - test_function4, test_function5, test_function6, - test_function7, DocstringTestFoo) - - # options.disable_function_signatures() - assert not test_function1.__doc__ - - assert test_function2.__doc__ == "A custom docstring" - - # options.enable_function_signatures() - assert test_function3.__doc__ .startswith("test_function3(a: int, b: int) -> None") - - assert test_function4.__doc__ .startswith("test_function4(a: int, b: int) -> None") - assert test_function4.__doc__ .endswith("A custom docstring\n") - - # options.disable_function_signatures() - # options.disable_user_defined_docstrings() - assert not test_function5.__doc__ - - # nested options.enable_user_defined_docstrings() - assert test_function6.__doc__ == "A custom docstring" - - # RAII destructor - assert test_function7.__doc__ .startswith("test_function7(a: int, b: int) -> None") - assert test_function7.__doc__ .endswith("A custom docstring\n") - - # Suppression of user-defined docstrings for non-function objects - assert not DocstringTestFoo.__doc__ - assert not DocstringTestFoo.value_prop.__doc__ diff --git a/stormpy/resources/pybind11/tests/test_eigen.cpp b/stormpy/resources/pybind11/tests/test_eigen.cpp deleted file mode 100755 index a9cb9f21c..000000000 --- a/stormpy/resources/pybind11/tests/test_eigen.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - tests/eigen.cpp -- automatic conversion of Eigen types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include -#include - -Eigen::VectorXf double_col(const Eigen::VectorXf& x) -{ return 2.0f * x; } - -Eigen::RowVectorXf double_row(const Eigen::RowVectorXf& x) -{ return 2.0f * x; } - -Eigen::MatrixXf double_mat_cm(const Eigen::MatrixXf& x) -{ return 2.0f * x; } - -// Different ways of passing via Eigen::Ref; the first and second are the Eigen-recommended -Eigen::MatrixXd cholesky1(Eigen::Ref &x) { return x.llt().matrixL(); } -Eigen::MatrixXd cholesky2(const Eigen::Ref &x) { return x.llt().matrixL(); } -Eigen::MatrixXd cholesky3(const Eigen::Ref &x) { return x.llt().matrixL(); } -Eigen::MatrixXd cholesky4(Eigen::Ref &x) { return x.llt().matrixL(); } -Eigen::MatrixXd cholesky5(Eigen::Ref x) { return x.llt().matrixL(); } -Eigen::MatrixXd cholesky6(Eigen::Ref x) { return x.llt().matrixL(); } - -typedef Eigen::Matrix MatrixXfRowMajor; -MatrixXfRowMajor double_mat_rm(const MatrixXfRowMajor& x) -{ return 2.0f * x; } - -test_initializer eigen([](py::module &m) { - typedef Eigen::Matrix FixedMatrixR; - typedef Eigen::Matrix FixedMatrixC; - typedef Eigen::Matrix DenseMatrixR; - typedef Eigen::Matrix DenseMatrixC; - typedef Eigen::SparseMatrix SparseMatrixR; - typedef Eigen::SparseMatrix SparseMatrixC; - - m.attr("have_eigen") = py::cast(true); - - // Non-symmetric matrix with zero elements - Eigen::MatrixXf mat(5, 6); - mat << 0, 3, 0, 0, 0, 11, 22, 0, 0, 0, 17, 11, 7, 5, 0, 1, 0, 11, 0, - 0, 0, 0, 0, 11, 0, 0, 14, 0, 8, 11; - - m.def("double_col", &double_col); - m.def("double_row", &double_row); - m.def("double_mat_cm", &double_mat_cm); - m.def("double_mat_rm", &double_mat_rm); - m.def("cholesky1", &cholesky1); - m.def("cholesky2", &cholesky2); - m.def("cholesky3", &cholesky3); - m.def("cholesky4", &cholesky4); - m.def("cholesky5", &cholesky5); - m.def("cholesky6", &cholesky6); - - // Returns diagonals: a vector-like object with an inner stride != 1 - m.def("diagonal", [](const Eigen::Ref &x) { return x.diagonal(); }); - m.def("diagonal_1", [](const Eigen::Ref &x) { return x.diagonal<1>(); }); - m.def("diagonal_n", [](const Eigen::Ref &x, int index) { return x.diagonal(index); }); - - // Return a block of a matrix (gives non-standard strides) - m.def("block", [](const Eigen::Ref &x, int start_row, int start_col, int block_rows, int block_cols) { - return x.block(start_row, start_col, block_rows, block_cols); - }); - - // Returns a DiagonalMatrix with diagonal (1,2,3,...) - m.def("incr_diag", [](int k) { - Eigen::DiagonalMatrix m(k); - for (int i = 0; i < k; i++) m.diagonal()[i] = i+1; - return m; - }); - - // Returns a SelfAdjointView referencing the lower triangle of m - m.def("symmetric_lower", [](const Eigen::MatrixXi &m) { - return m.selfadjointView(); - }); - // Returns a SelfAdjointView referencing the lower triangle of m - m.def("symmetric_upper", [](const Eigen::MatrixXi &m) { - return m.selfadjointView(); - }); - - m.def("fixed_r", [mat]() -> FixedMatrixR { - return FixedMatrixR(mat); - }); - - m.def("fixed_c", [mat]() -> FixedMatrixC { - return FixedMatrixC(mat); - }); - - m.def("fixed_passthrough_r", [](const FixedMatrixR &m) -> FixedMatrixR { - return m; - }); - - m.def("fixed_passthrough_c", [](const FixedMatrixC &m) -> FixedMatrixC { - return m; - }); - - m.def("dense_r", [mat]() -> DenseMatrixR { - return DenseMatrixR(mat); - }); - - m.def("dense_c", [mat]() -> DenseMatrixC { - return DenseMatrixC(mat); - }); - - m.def("dense_passthrough_r", [](const DenseMatrixR &m) -> DenseMatrixR { - return m; - }); - - m.def("dense_passthrough_c", [](const DenseMatrixC &m) -> DenseMatrixC { - return m; - }); - - m.def("sparse_r", [mat]() -> SparseMatrixR { - return Eigen::SparseView(mat); - }); - - m.def("sparse_c", [mat]() -> SparseMatrixC { - return Eigen::SparseView(mat); - }); - - m.def("sparse_passthrough_r", [](const SparseMatrixR &m) -> SparseMatrixR { - return m; - }); - - m.def("sparse_passthrough_c", [](const SparseMatrixC &m) -> SparseMatrixC { - return m; - }); -}); diff --git a/stormpy/resources/pybind11/tests/test_eigen.py b/stormpy/resources/pybind11/tests/test_eigen.py deleted file mode 100755 index 2a58f8c40..000000000 --- a/stormpy/resources/pybind11/tests/test_eigen.py +++ /dev/null @@ -1,135 +0,0 @@ -import pytest - -with pytest.suppress(ImportError): - import numpy as np - - ref = np.array([[ 0, 3, 0, 0, 0, 11], - [22, 0, 0, 0, 17, 11], - [ 7, 5, 0, 1, 0, 11], - [ 0, 0, 0, 0, 0, 11], - [ 0, 0, 14, 0, 8, 11]]) - - -def assert_equal_ref(mat): - np.testing.assert_array_equal(mat, ref) - - -def assert_sparse_equal_ref(sparse_mat): - assert_equal_ref(sparse_mat.todense()) - - -@pytest.requires_eigen_and_numpy -def test_fixed(): - from pybind11_tests import fixed_r, fixed_c, fixed_passthrough_r, fixed_passthrough_c - - assert_equal_ref(fixed_c()) - assert_equal_ref(fixed_r()) - assert_equal_ref(fixed_passthrough_r(fixed_r())) - assert_equal_ref(fixed_passthrough_c(fixed_c())) - assert_equal_ref(fixed_passthrough_r(fixed_c())) - assert_equal_ref(fixed_passthrough_c(fixed_r())) - - -@pytest.requires_eigen_and_numpy -def test_dense(): - from pybind11_tests import dense_r, dense_c, dense_passthrough_r, dense_passthrough_c - - assert_equal_ref(dense_r()) - assert_equal_ref(dense_c()) - assert_equal_ref(dense_passthrough_r(dense_r())) - assert_equal_ref(dense_passthrough_c(dense_c())) - assert_equal_ref(dense_passthrough_r(dense_c())) - assert_equal_ref(dense_passthrough_c(dense_r())) - - -@pytest.requires_eigen_and_numpy -def test_nonunit_stride_from_python(): - from pybind11_tests import double_row, double_col, double_mat_cm, double_mat_rm - - counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3)) - first_row = counting_mat[0, :] - first_col = counting_mat[:, 0] - assert np.array_equal(double_row(first_row), 2.0 * first_row) - assert np.array_equal(double_col(first_row), 2.0 * first_row) - assert np.array_equal(double_row(first_col), 2.0 * first_col) - assert np.array_equal(double_col(first_col), 2.0 * first_col) - - counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3)) - slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]] - for slice_idx, ref_mat in enumerate(slices): - assert np.array_equal(double_mat_cm(ref_mat), 2.0 * ref_mat) - assert np.array_equal(double_mat_rm(ref_mat), 2.0 * ref_mat) - - -@pytest.requires_eigen_and_numpy -def test_nonunit_stride_to_python(): - from pybind11_tests import diagonal, diagonal_1, diagonal_n, block - - assert np.all(diagonal(ref) == ref.diagonal()) - assert np.all(diagonal_1(ref) == ref.diagonal(1)) - for i in range(-5, 7): - assert np.all(diagonal_n(ref, i) == ref.diagonal(i)), "diagonal_n({})".format(i) - - assert np.all(block(ref, 2, 1, 3, 3) == ref[2:5, 1:4]) - assert np.all(block(ref, 1, 4, 4, 2) == ref[1:, 4:]) - assert np.all(block(ref, 1, 4, 3, 2) == ref[1:4, 4:]) - - -@pytest.requires_eigen_and_numpy -def test_eigen_ref_to_python(): - from pybind11_tests import cholesky1, cholesky2, cholesky3, cholesky4, cholesky5, cholesky6 - - chols = [cholesky1, cholesky2, cholesky3, cholesky4, cholesky5, cholesky6] - for i, chol in enumerate(chols, start=1): - mymat = chol(np.array([[1, 2, 4], [2, 13, 23], [4, 23, 77]])) - assert np.all(mymat == np.array([[1, 0, 0], [2, 3, 0], [4, 5, 6]])), "cholesky{}".format(i) - - -@pytest.requires_eigen_and_numpy -def test_special_matrix_objects(): - from pybind11_tests import incr_diag, symmetric_upper, symmetric_lower - - assert np.all(incr_diag(7) == np.diag([1, 2, 3, 4, 5, 6, 7])) - - asymm = np.array([[ 1, 2, 3, 4], - [ 5, 6, 7, 8], - [ 9, 10, 11, 12], - [13, 14, 15, 16]]) - symm_lower = np.array(asymm) - symm_upper = np.array(asymm) - for i in range(4): - for j in range(i + 1, 4): - symm_lower[i, j] = symm_lower[j, i] - symm_upper[j, i] = symm_upper[i, j] - - assert np.all(symmetric_lower(asymm) == symm_lower) - assert np.all(symmetric_upper(asymm) == symm_upper) - - -@pytest.requires_eigen_and_numpy -def test_dense_signature(doc): - from pybind11_tests import double_col, double_row, double_mat_rm - - assert doc(double_col) == "double_col(arg0: numpy.ndarray[float32[m, 1]]) -> numpy.ndarray[float32[m, 1]]" - assert doc(double_row) == "double_row(arg0: numpy.ndarray[float32[1, n]]) -> numpy.ndarray[float32[1, n]]" - assert doc(double_mat_rm) == "double_mat_rm(arg0: numpy.ndarray[float32[m, n]]) -> numpy.ndarray[float32[m, n]]" - - -@pytest.requires_eigen_and_scipy -def test_sparse(): - from pybind11_tests import sparse_r, sparse_c, sparse_passthrough_r, sparse_passthrough_c - - assert_sparse_equal_ref(sparse_r()) - assert_sparse_equal_ref(sparse_c()) - assert_sparse_equal_ref(sparse_passthrough_r(sparse_r())) - assert_sparse_equal_ref(sparse_passthrough_c(sparse_c())) - assert_sparse_equal_ref(sparse_passthrough_r(sparse_c())) - assert_sparse_equal_ref(sparse_passthrough_c(sparse_r())) - - -@pytest.requires_eigen_and_scipy -def test_sparse_signature(doc): - from pybind11_tests import sparse_passthrough_r, sparse_passthrough_c - - assert doc(sparse_passthrough_r) == "sparse_passthrough_r(arg0: scipy.sparse.csr_matrix[float32]) -> scipy.sparse.csr_matrix[float32]" - assert doc(sparse_passthrough_c) == "sparse_passthrough_c(arg0: scipy.sparse.csc_matrix[float32]) -> scipy.sparse.csc_matrix[float32]" diff --git a/stormpy/resources/pybind11/tests/test_enum.cpp b/stormpy/resources/pybind11/tests/test_enum.cpp deleted file mode 100755 index 09f334cdb..000000000 --- a/stormpy/resources/pybind11/tests/test_enum.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - tests/test_enums.cpp -- enumerations - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -enum UnscopedEnum { - EOne = 1, - ETwo -}; - -enum class ScopedEnum { - Two = 2, - Three -}; - -enum Flags { - Read = 4, - Write = 2, - Execute = 1 -}; - -class ClassWithUnscopedEnum { -public: - enum EMode { - EFirstMode = 1, - ESecondMode - }; - - static EMode test_function(EMode mode) { - return mode; - } -}; - -std::string test_scoped_enum(ScopedEnum z) { - return "ScopedEnum::" + std::string(z == ScopedEnum::Two ? "Two" : "Three"); -} - -test_initializer enums([](py::module &m) { - m.def("test_scoped_enum", &test_scoped_enum); - - py::enum_(m, "UnscopedEnum", py::arithmetic()) - .value("EOne", EOne) - .value("ETwo", ETwo) - .export_values(); - - py::enum_(m, "ScopedEnum", py::arithmetic()) - .value("Two", ScopedEnum::Two) - .value("Three", ScopedEnum::Three); - - py::enum_(m, "Flags", py::arithmetic()) - .value("Read", Flags::Read) - .value("Write", Flags::Write) - .value("Execute", Flags::Execute) - .export_values(); - - py::class_ exenum_class(m, "ClassWithUnscopedEnum"); - exenum_class.def_static("test_function", &ClassWithUnscopedEnum::test_function); - py::enum_(exenum_class, "EMode") - .value("EFirstMode", ClassWithUnscopedEnum::EFirstMode) - .value("ESecondMode", ClassWithUnscopedEnum::ESecondMode) - .export_values(); -}); diff --git a/stormpy/resources/pybind11/tests/test_enum.py b/stormpy/resources/pybind11/tests/test_enum.py deleted file mode 100755 index de5f3c6f6..000000000 --- a/stormpy/resources/pybind11/tests/test_enum.py +++ /dev/null @@ -1,108 +0,0 @@ -import pytest - - -def test_unscoped_enum(): - from pybind11_tests import UnscopedEnum, EOne - - assert str(UnscopedEnum.EOne) == "UnscopedEnum.EOne" - assert str(UnscopedEnum.ETwo) == "UnscopedEnum.ETwo" - assert str(EOne) == "UnscopedEnum.EOne" - - # no TypeError exception for unscoped enum ==/!= int comparisons - y = UnscopedEnum.ETwo - assert y == 2 - assert y != 3 - - assert int(UnscopedEnum.ETwo) == 2 - assert str(UnscopedEnum(2)) == "UnscopedEnum.ETwo" - - # order - assert UnscopedEnum.EOne < UnscopedEnum.ETwo - assert UnscopedEnum.EOne < 2 - assert UnscopedEnum.ETwo > UnscopedEnum.EOne - assert UnscopedEnum.ETwo > 1 - assert UnscopedEnum.ETwo <= 2 - assert UnscopedEnum.ETwo >= 2 - assert UnscopedEnum.EOne <= UnscopedEnum.ETwo - assert UnscopedEnum.EOne <= 2 - assert UnscopedEnum.ETwo >= UnscopedEnum.EOne - assert UnscopedEnum.ETwo >= 1 - assert not (UnscopedEnum.ETwo < UnscopedEnum.EOne) - assert not (2 < UnscopedEnum.EOne) - - -def test_scoped_enum(): - from pybind11_tests import ScopedEnum, test_scoped_enum - - assert test_scoped_enum(ScopedEnum.Three) == "ScopedEnum::Three" - z = ScopedEnum.Two - assert test_scoped_enum(z) == "ScopedEnum::Two" - - # expected TypeError exceptions for scoped enum ==/!= int comparisons - with pytest.raises(TypeError): - assert z == 2 - with pytest.raises(TypeError): - assert z != 3 - - # order - assert ScopedEnum.Two < ScopedEnum.Three - assert ScopedEnum.Three > ScopedEnum.Two - assert ScopedEnum.Two <= ScopedEnum.Three - assert ScopedEnum.Two <= ScopedEnum.Two - assert ScopedEnum.Two >= ScopedEnum.Two - assert ScopedEnum.Three >= ScopedEnum.Two - - -def test_implicit_conversion(): - from pybind11_tests import ClassWithUnscopedEnum - - assert str(ClassWithUnscopedEnum.EMode.EFirstMode) == "EMode.EFirstMode" - assert str(ClassWithUnscopedEnum.EFirstMode) == "EMode.EFirstMode" - - f = ClassWithUnscopedEnum.test_function - first = ClassWithUnscopedEnum.EFirstMode - second = ClassWithUnscopedEnum.ESecondMode - - assert f(first) == 1 - - assert f(first) == f(first) - assert not f(first) != f(first) - - assert f(first) != f(second) - assert not f(first) == f(second) - - assert f(first) == int(f(first)) - assert not f(first) != int(f(first)) - - assert f(first) != int(f(second)) - assert not f(first) == int(f(second)) - - # noinspection PyDictCreation - x = {f(first): 1, f(second): 2} - x[f(first)] = 3 - x[f(second)] = 4 - # Hashing test - assert str(x) == "{EMode.EFirstMode: 3, EMode.ESecondMode: 4}" - - -def test_binary_operators(): - from pybind11_tests import Flags - - assert int(Flags.Read) == 4 - assert int(Flags.Write) == 2 - assert int(Flags.Execute) == 1 - assert int(Flags.Read | Flags.Write | Flags.Execute) == 7 - assert int(Flags.Read | Flags.Write) == 6 - assert int(Flags.Read | Flags.Execute) == 5 - assert int(Flags.Write | Flags.Execute) == 3 - assert int(Flags.Write | 1) == 3 - - state = Flags.Read | Flags.Write - assert (state & Flags.Read) != 0 - assert (state & Flags.Write) != 0 - assert (state & Flags.Execute) == 0 - assert (state & 1) == 0 - - state2 = ~state - assert state2 == -7 - assert int(state ^ state2) == -1 diff --git a/stormpy/resources/pybind11/tests/test_eval.cpp b/stormpy/resources/pybind11/tests/test_eval.cpp deleted file mode 100755 index ed4c226fe..000000000 --- a/stormpy/resources/pybind11/tests/test_eval.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - tests/test_eval.cpp -- Usage of eval() and eval_file() - - Copyright (c) 2016 Klemens D. Morgenstern - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - - -#include -#include "pybind11_tests.h" - -test_initializer eval([](py::module &m) { - auto global = py::dict(py::module::import("__main__").attr("__dict__")); - - m.def("test_eval_statements", [global]() { - auto local = py::dict(); - local["call_test"] = py::cpp_function([&]() -> int { - return 42; - }); - - auto result = py::eval( - "print('Hello World!');\n" - "x = call_test();", - global, local - ); - auto x = local["x"].cast(); - - return result == py::none() && x == 42; - }); - - m.def("test_eval", [global]() { - auto local = py::dict(); - local["x"] = py::int_(42); - auto x = py::eval("x", global, local); - return x.cast() == 42; - }); - - m.def("test_eval_single_statement", []() { - auto local = py::dict(); - local["call_test"] = py::cpp_function([&]() -> int { - return 42; - }); - - auto result = py::eval("x = call_test()", py::dict(), local); - auto x = local["x"].cast(); - return result == py::none() && x == 42; - }); - - m.def("test_eval_file", [global](py::str filename) { - auto local = py::dict(); - local["y"] = py::int_(43); - - int val_out; - local["call_test2"] = py::cpp_function([&](int value) { val_out = value; }); - - auto result = py::eval_file(filename, global, local); - return val_out == 43 && result == py::none(); - }); - - m.def("test_eval_failure", []() { - try { - py::eval("nonsense code ..."); - } catch (py::error_already_set &) { - return true; - } - return false; - }); - - m.def("test_eval_file_failure", []() { - try { - py::eval_file("non-existing file"); - } catch (std::exception &) { - return true; - } - return false; - }); -}); diff --git a/stormpy/resources/pybind11/tests/test_eval.py b/stormpy/resources/pybind11/tests/test_eval.py deleted file mode 100755 index 8715dbadb..000000000 --- a/stormpy/resources/pybind11/tests/test_eval.py +++ /dev/null @@ -1,19 +0,0 @@ -import os - - -def test_evals(capture): - from pybind11_tests import (test_eval_statements, test_eval, test_eval_single_statement, - test_eval_file, test_eval_failure, test_eval_file_failure) - - with capture: - assert test_eval_statements() - assert capture == "Hello World!" - - assert test_eval() - assert test_eval_single_statement() - - filename = os.path.join(os.path.dirname(__file__), "test_eval_call.py") - assert test_eval_file(filename) - - assert test_eval_failure() - assert test_eval_file_failure() diff --git a/stormpy/resources/pybind11/tests/test_eval_call.py b/stormpy/resources/pybind11/tests/test_eval_call.py deleted file mode 100755 index 53c7e721f..000000000 --- a/stormpy/resources/pybind11/tests/test_eval_call.py +++ /dev/null @@ -1,4 +0,0 @@ -# This file is called from 'test_eval.py' - -if 'call_test2' in locals(): - call_test2(y) # noqa: F821 undefined name diff --git a/stormpy/resources/pybind11/tests/test_exceptions.cpp b/stormpy/resources/pybind11/tests/test_exceptions.cpp deleted file mode 100755 index ca2afa642..000000000 --- a/stormpy/resources/pybind11/tests/test_exceptions.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - tests/test_custom-exceptions.cpp -- exception translation - - Copyright (c) 2016 Pim Schellart - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -// A type that should be raised as an exeption in Python -class MyException : public std::exception { -public: - explicit MyException(const char * m) : message{m} {} - virtual const char * what() const noexcept override {return message.c_str();} -private: - std::string message = ""; -}; - -// A type that should be translated to a standard Python exception -class MyException2 : public std::exception { -public: - explicit MyException2(const char * m) : message{m} {} - virtual const char * what() const noexcept override {return message.c_str();} -private: - std::string message = ""; -}; - -// A type that is not derived from std::exception (and is thus unknown) -class MyException3 { -public: - explicit MyException3(const char * m) : message{m} {} - virtual const char * what() const noexcept {return message.c_str();} -private: - std::string message = ""; -}; - -// A type that should be translated to MyException -// and delegated to its exception translator -class MyException4 : public std::exception { -public: - explicit MyException4(const char * m) : message{m} {} - virtual const char * what() const noexcept override {return message.c_str();} -private: - std::string message = ""; -}; - - -// Like the above, but declared via the helper function -class MyException5 : public std::logic_error { -public: - explicit MyException5(const std::string &what) : std::logic_error(what) {} -}; - -// Inherits from MyException5 -class MyException5_1 : public MyException5 { - using MyException5::MyException5; -}; - -void throws1() { - throw MyException("this error should go to a custom type"); -} - -void throws2() { - throw MyException2("this error should go to a standard Python exception"); -} - -void throws3() { - throw MyException3("this error cannot be translated"); -} - -void throws4() { - throw MyException4("this error is rethrown"); -} - -void throws5() { - throw MyException5("this is a helper-defined translated exception"); -} - -void throws5_1() { - throw MyException5_1("MyException5 subclass"); -} - -void throws_logic_error() { - throw std::logic_error("this error should fall through to the standard handler"); -} - -struct PythonCallInDestructor { - PythonCallInDestructor(const py::dict &d) : d(d) {} - ~PythonCallInDestructor() { d["good"] = py::cast(true); } - - py::dict d; -}; - -test_initializer custom_exceptions([](py::module &m) { - // make a new custom exception and use it as a translation target - static py::exception ex(m, "MyException"); - py::register_exception_translator([](std::exception_ptr p) { - try { - if (p) std::rethrow_exception(p); - } catch (const MyException &e) { - // Set MyException as the active python error - ex(e.what()); - } - }); - - // register new translator for MyException2 - // no need to store anything here because this type will - // never by visible from Python - py::register_exception_translator([](std::exception_ptr p) { - try { - if (p) std::rethrow_exception(p); - } catch (const MyException2 &e) { - // Translate this exception to a standard RuntimeError - PyErr_SetString(PyExc_RuntimeError, e.what()); - } - }); - - // register new translator for MyException4 - // which will catch it and delegate to the previously registered - // translator for MyException by throwing a new exception - py::register_exception_translator([](std::exception_ptr p) { - try { - if (p) std::rethrow_exception(p); - } catch (const MyException4 &e) { - throw MyException(e.what()); - } - }); - - // A simple exception translation: - auto ex5 = py::register_exception(m, "MyException5"); - // A slightly more complicated one that declares MyException5_1 as a subclass of MyException5 - py::register_exception(m, "MyException5_1", ex5.ptr()); - - m.def("throws1", &throws1); - m.def("throws2", &throws2); - m.def("throws3", &throws3); - m.def("throws4", &throws4); - m.def("throws5", &throws5); - m.def("throws5_1", &throws5_1); - m.def("throws_logic_error", &throws_logic_error); - - m.def("throw_already_set", [](bool err) { - if (err) - PyErr_SetString(PyExc_ValueError, "foo"); - try { - throw py::error_already_set(); - } catch (const std::runtime_error& e) { - if ((err && e.what() != std::string("ValueError: foo")) || - (!err && e.what() != std::string("Unknown internal error occurred"))) - { - PyErr_Clear(); - throw std::runtime_error("error message mismatch"); - } - } - PyErr_Clear(); - if (err) - PyErr_SetString(PyExc_ValueError, "foo"); - throw py::error_already_set(); - }); - - m.def("python_call_in_destructor", [](py::dict d) { - try { - PythonCallInDestructor set_dict_in_destructor(d); - PyErr_SetString(PyExc_ValueError, "foo"); - throw py::error_already_set(); - } catch (const py::error_already_set&) { - return true; - } - return false; - }); -}); diff --git a/stormpy/resources/pybind11/tests/test_exceptions.py b/stormpy/resources/pybind11/tests/test_exceptions.py deleted file mode 100755 index 0025e4eb6..000000000 --- a/stormpy/resources/pybind11/tests/test_exceptions.py +++ /dev/null @@ -1,74 +0,0 @@ -import pytest - - -def test_error_already_set(msg): - from pybind11_tests import throw_already_set - - with pytest.raises(RuntimeError) as excinfo: - throw_already_set(False) - assert msg(excinfo.value) == "Unknown internal error occurred" - - with pytest.raises(ValueError) as excinfo: - throw_already_set(True) - assert msg(excinfo.value) == "foo" - - -def test_python_call_in_catch(): - from pybind11_tests import python_call_in_destructor - - d = {} - assert python_call_in_destructor(d) is True - assert d["good"] is True - - -def test_custom(msg): - from pybind11_tests import (MyException, MyException5, MyException5_1, - throws1, throws2, throws3, throws4, throws5, throws5_1, - throws_logic_error) - - # Can we catch a MyException?" - with pytest.raises(MyException) as excinfo: - throws1() - assert msg(excinfo.value) == "this error should go to a custom type" - - # Can we translate to standard Python exceptions? - with pytest.raises(RuntimeError) as excinfo: - throws2() - assert msg(excinfo.value) == "this error should go to a standard Python exception" - - # Can we handle unknown exceptions? - with pytest.raises(RuntimeError) as excinfo: - throws3() - assert msg(excinfo.value) == "Caught an unknown exception!" - - # Can we delegate to another handler by rethrowing? - with pytest.raises(MyException) as excinfo: - throws4() - assert msg(excinfo.value) == "this error is rethrown" - - # "Can we fall-through to the default handler?" - with pytest.raises(RuntimeError) as excinfo: - throws_logic_error() - assert msg(excinfo.value) == "this error should fall through to the standard handler" - - # Can we handle a helper-declared exception? - with pytest.raises(MyException5) as excinfo: - throws5() - assert msg(excinfo.value) == "this is a helper-defined translated exception" - - # Exception subclassing: - with pytest.raises(MyException5) as excinfo: - throws5_1() - assert msg(excinfo.value) == "MyException5 subclass" - assert isinstance(excinfo.value, MyException5_1) - - with pytest.raises(MyException5_1) as excinfo: - throws5_1() - assert msg(excinfo.value) == "MyException5 subclass" - - with pytest.raises(MyException5) as excinfo: - try: - throws5() - except MyException5_1: - raise RuntimeError("Exception error: caught child from parent") - assert msg(excinfo.value) == "this is a helper-defined translated exception" diff --git a/stormpy/resources/pybind11/tests/test_inheritance.cpp b/stormpy/resources/pybind11/tests/test_inheritance.cpp deleted file mode 100755 index 2ec0b4a7a..000000000 --- a/stormpy/resources/pybind11/tests/test_inheritance.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - tests/test_inheritance.cpp -- inheritance, automatic upcasting for polymorphic types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -class Pet { -public: - Pet(const std::string &name, const std::string &species) - : m_name(name), m_species(species) {} - std::string name() const { return m_name; } - std::string species() const { return m_species; } -private: - std::string m_name; - std::string m_species; -}; - -class Dog : public Pet { -public: - Dog(const std::string &name) : Pet(name, "dog") {} - std::string bark() const { return "Woof!"; } -}; - -class Rabbit : public Pet { -public: - Rabbit(const std::string &name) : Pet(name, "parrot") {} -}; - -class Hamster : public Pet { -public: - Hamster(const std::string &name) : Pet(name, "rodent") {} -}; - -std::string pet_name_species(const Pet &pet) { - return pet.name() + " is a " + pet.species(); -} - -std::string dog_bark(const Dog &dog) { - return dog.bark(); -} - - -struct BaseClass { virtual ~BaseClass() {} }; -struct DerivedClass1 : BaseClass { }; -struct DerivedClass2 : BaseClass { }; - -test_initializer inheritance([](py::module &m) { - py::class_ pet_class(m, "Pet"); - pet_class - .def(py::init()) - .def("name", &Pet::name) - .def("species", &Pet::species); - - /* One way of declaring a subclass relationship: reference parent's class_ object */ - py::class_(m, "Dog", pet_class) - .def(py::init()); - - /* Another way of declaring a subclass relationship: reference parent's C++ type */ - py::class_(m, "Rabbit") - .def(py::init()); - - /* And another: list parent in class template arguments */ - py::class_(m, "Hamster") - .def(py::init()); - - m.def("pet_name_species", pet_name_species); - m.def("dog_bark", dog_bark); - - py::class_(m, "BaseClass").def(py::init<>()); - py::class_(m, "DerivedClass1").def(py::init<>()); - py::class_(m, "DerivedClass2").def(py::init<>()); - - m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); }); - m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); }); - m.def("return_class_n", [](int n) -> BaseClass* { - if (n == 1) return new DerivedClass1(); - if (n == 2) return new DerivedClass2(); - return new BaseClass(); - }); - m.def("return_none", []() -> BaseClass* { return nullptr; }); - - m.def("test_isinstance", [](py::list l) { - struct Unregistered { }; // checks missing type_info code path - - return py::make_tuple( - py::isinstance(l[0]), - py::isinstance(l[1]), - py::isinstance(l[2]), - py::isinstance(l[3]), - py::isinstance(l[4]), - py::isinstance(l[5]), - py::isinstance(l[6]) - ); - }); -}); diff --git a/stormpy/resources/pybind11/tests/test_inheritance.py b/stormpy/resources/pybind11/tests/test_inheritance.py deleted file mode 100755 index 7bb52be02..000000000 --- a/stormpy/resources/pybind11/tests/test_inheritance.py +++ /dev/null @@ -1,55 +0,0 @@ -import pytest - - -def test_inheritance(msg): - from pybind11_tests import Pet, Dog, Rabbit, Hamster, dog_bark, pet_name_species - - roger = Rabbit('Rabbit') - assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot" - assert pet_name_species(roger) == "Rabbit is a parrot" - - polly = Pet('Polly', 'parrot') - assert polly.name() + " is a " + polly.species() == "Polly is a parrot" - assert pet_name_species(polly) == "Polly is a parrot" - - molly = Dog('Molly') - assert molly.name() + " is a " + molly.species() == "Molly is a dog" - assert pet_name_species(molly) == "Molly is a dog" - - fred = Hamster('Fred') - assert fred.name() + " is a " + fred.species() == "Fred is a rodent" - - assert dog_bark(molly) == "Woof!" - - with pytest.raises(TypeError) as excinfo: - dog_bark(polly) - assert msg(excinfo.value) == """ - dog_bark(): incompatible function arguments. The following argument types are supported: - 1. (arg0: m.Dog) -> str - - Invoked with: - """ - - -def test_automatic_upcasting(): - from pybind11_tests import return_class_1, return_class_2, return_class_n, return_none - - assert type(return_class_1()).__name__ == "DerivedClass1" - assert type(return_class_2()).__name__ == "DerivedClass2" - assert type(return_none()).__name__ == "NoneType" - # Repeat these a few times in a random order to ensure no invalid caching is applied - assert type(return_class_n(1)).__name__ == "DerivedClass1" - assert type(return_class_n(2)).__name__ == "DerivedClass2" - assert type(return_class_n(0)).__name__ == "BaseClass" - assert type(return_class_n(2)).__name__ == "DerivedClass2" - assert type(return_class_n(2)).__name__ == "DerivedClass2" - assert type(return_class_n(0)).__name__ == "BaseClass" - assert type(return_class_n(1)).__name__ == "DerivedClass1" - - -def test_isinstance(): - from pybind11_tests import test_isinstance, Pet, Dog - - objects = [tuple(), dict(), Pet("Polly", "parrot")] + [Dog("Molly")] * 4 - expected = (True, True, True, True, True, False, False) - assert test_isinstance(objects) == expected diff --git a/stormpy/resources/pybind11/tests/test_issues.cpp b/stormpy/resources/pybind11/tests/test_issues.cpp deleted file mode 100755 index 33f8a43af..000000000 --- a/stormpy/resources/pybind11/tests/test_issues.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - tests/test_issues.cpp -- collection of testcases for miscellaneous issues - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" -#include -#include -#include - -#define TRACKERS(CLASS) CLASS() { print_default_created(this); } ~CLASS() { print_destroyed(this); } -struct NestABase { int value = -2; TRACKERS(NestABase) }; -struct NestA : NestABase { int value = 3; NestA& operator+=(int i) { value += i; return *this; } TRACKERS(NestA) }; -struct NestB { NestA a; int value = 4; NestB& operator-=(int i) { value -= i; return *this; } TRACKERS(NestB) }; -struct NestC { NestB b; int value = 5; NestC& operator*=(int i) { value *= i; return *this; } TRACKERS(NestC) }; - -/// #393 -class OpTest1 {}; -class OpTest2 {}; - -OpTest1 operator+(const OpTest1 &, const OpTest1 &) { - py::print("Add OpTest1 with OpTest1"); - return OpTest1(); -} -OpTest2 operator+(const OpTest2 &, const OpTest2 &) { - py::print("Add OpTest2 with OpTest2"); - return OpTest2(); -} -OpTest2 operator+(const OpTest2 &, const OpTest1 &) { - py::print("Add OpTest2 with OpTest1"); - return OpTest2(); -} - -// #461 -class Dupe1 { -public: - Dupe1(int v) : v_{v} {} - int get_value() const { return v_; } -private: - int v_; -}; -class Dupe2 {}; -class Dupe3 {}; -class DupeException : public std::runtime_error {}; - -// #478 -template class custom_unique_ptr { -public: - custom_unique_ptr() { print_default_created(this); } - custom_unique_ptr(T *ptr) : _ptr{ptr} { print_created(this, ptr); } - custom_unique_ptr(custom_unique_ptr &&move) : _ptr{move._ptr} { move._ptr = nullptr; print_move_created(this); } - custom_unique_ptr &operator=(custom_unique_ptr &&move) { print_move_assigned(this); if (_ptr) destruct_ptr(); _ptr = move._ptr; move._ptr = nullptr; return *this; } - custom_unique_ptr(const custom_unique_ptr &) = delete; - void operator=(const custom_unique_ptr ©) = delete; - ~custom_unique_ptr() { print_destroyed(this); if (_ptr) destruct_ptr(); } -private: - T *_ptr = nullptr; - void destruct_ptr() { delete _ptr; } -}; -PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr); - - - -void init_issues(py::module &m) { - py::module m2 = m.def_submodule("issues"); - -#if !defined(_MSC_VER) - // Visual Studio 2015 currently cannot compile this test - // (see the comment in type_caster_base::make_copy_constructor) - // #70 compilation issue if operator new is not public - class NonConstructible { private: void *operator new(size_t bytes) throw(); }; - py::class_(m, "Foo"); - m2.def("getstmt", []() -> NonConstructible * { return nullptr; }, - py::return_value_policy::reference); -#endif - - // #137: const char* isn't handled properly - m2.def("print_cchar", [](const char *s) { return std::string(s); }); - - // #150: char bindings broken - m2.def("print_char", [](char c) { return std::string(1, c); }); - - // #159: virtual function dispatch has problems with similar-named functions - struct Base { virtual std::string dispatch() const { - /* for some reason MSVC2015 can't compile this if the function is pure virtual */ - return {}; - }; }; - - struct DispatchIssue : Base { - virtual std::string dispatch() const { - PYBIND11_OVERLOAD_PURE(std::string, Base, dispatch, /* no arguments */); - } - }; - - py::class_(m2, "DispatchIssue") - .def(py::init<>()) - .def("dispatch", &Base::dispatch); - - m2.def("dispatch_issue_go", [](const Base * b) { return b->dispatch(); }); - - struct Placeholder { int i; Placeholder(int i) : i(i) { } }; - - py::class_(m2, "Placeholder") - .def(py::init()) - .def("__repr__", [](const Placeholder &p) { return "Placeholder[" + std::to_string(p.i) + "]"; }); - - // #171: Can't return reference wrappers (or STL datastructures containing them) - m2.def("return_vec_of_reference_wrapper", [](std::reference_wrapper p4) { - Placeholder *p1 = new Placeholder{1}; - Placeholder *p2 = new Placeholder{2}; - Placeholder *p3 = new Placeholder{3}; - std::vector> v; - v.push_back(std::ref(*p1)); - v.push_back(std::ref(*p2)); - v.push_back(std::ref(*p3)); - v.push_back(p4); - return v; - }); - - // #181: iterator passthrough did not compile - m2.def("iterator_passthrough", [](py::iterator s) -> py::iterator { - return py::make_iterator(std::begin(s), std::end(s)); - }); - - // #187: issue involving std::shared_ptr<> return value policy & garbage collection - struct ElementBase { virtual void foo() { } /* Force creation of virtual table */ }; - struct ElementA : ElementBase { - ElementA(int v) : v(v) { } - int value() { return v; } - int v; - }; - - struct ElementList { - void add(std::shared_ptr e) { l.push_back(e); } - std::vector> l; - }; - - py::class_> (m2, "ElementBase"); - - py::class_>(m2, "ElementA") - .def(py::init()) - .def("value", &ElementA::value); - - py::class_>(m2, "ElementList") - .def(py::init<>()) - .def("add", &ElementList::add) - .def("get", [](ElementList &el) { - py::list list; - for (auto &e : el.l) - list.append(py::cast(e)); - return list; - }); - - // (no id): should not be able to pass 'None' to a reference argument - m2.def("get_element", [](ElementA &el) { return el.value(); }); - - // (no id): don't cast doubles to ints - m2.def("expect_float", [](float f) { return f; }); - m2.def("expect_int", [](int i) { return i; }); - - try { - py::class_(m2, "Placeholder"); - throw std::logic_error("Expected an exception!"); - } catch (std::runtime_error &) { - /* All good */ - } - - // Issue #283: __str__ called on uninitialized instance when constructor arguments invalid - class StrIssue { - public: - StrIssue(int i) : val{i} {} - StrIssue() : StrIssue(-1) {} - int value() const { return val; } - private: - int val; - }; - py::class_ si(m2, "StrIssue"); - si .def(py::init()) - .def(py::init<>()) - .def("__str__", [](const StrIssue &si) { return "StrIssue[" + std::to_string(si.value()) + "]"; }) - ; - - // Issue #328: first member in a class can't be used in operators - py::class_(m2, "NestABase").def(py::init<>()).def_readwrite("value", &NestABase::value); - py::class_(m2, "NestA").def(py::init<>()).def(py::self += int()) - .def("as_base", [](NestA &a) -> NestABase& { return (NestABase&) a; }, py::return_value_policy::reference_internal); - py::class_(m2, "NestB").def(py::init<>()).def(py::self -= int()).def_readwrite("a", &NestB::a); - py::class_(m2, "NestC").def(py::init<>()).def(py::self *= int()).def_readwrite("b", &NestC::b); - m2.def("get_NestA", [](const NestA &a) { return a.value; }); - m2.def("get_NestB", [](const NestB &b) { return b.value; }); - m2.def("get_NestC", [](const NestC &c) { return c.value; }); - - // Issue 389: r_v_p::move should fall-through to copy on non-movable objects - class MoveIssue1 { - public: - MoveIssue1(int v) : v{v} {} - MoveIssue1(const MoveIssue1 &c) { v = c.v; } - MoveIssue1(MoveIssue1 &&) = delete; - int v; - }; - class MoveIssue2 { - public: - MoveIssue2(int v) : v{v} {} - MoveIssue2(MoveIssue2 &&) = default; - int v; - }; - py::class_(m2, "MoveIssue1").def(py::init()).def_readwrite("value", &MoveIssue1::v); - py::class_(m2, "MoveIssue2").def(py::init()).def_readwrite("value", &MoveIssue2::v); - m2.def("get_moveissue1", [](int i) -> MoveIssue1 * { return new MoveIssue1(i); }, py::return_value_policy::move); - m2.def("get_moveissue2", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move); - - // Issues 392/397: overridding reference-returning functions - class OverrideTest { - public: - struct A { std::string value = "hi"; }; - std::string v; - A a; - explicit OverrideTest(const std::string &v) : v{v} {} - virtual std::string str_value() { return v; } - virtual std::string &str_ref() { return v; } - virtual A A_value() { return a; } - virtual A &A_ref() { return a; } - }; - class PyOverrideTest : public OverrideTest { - public: - using OverrideTest::OverrideTest; - std::string str_value() override { PYBIND11_OVERLOAD(std::string, OverrideTest, str_value); } - // Not allowed (uncommenting should hit a static_assert failure): we can't get a reference - // to a python numeric value, since we only copy values in the numeric type caster: -// std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); } - // But we can work around it like this: - private: - std::string _tmp; - std::string str_ref_helper() { PYBIND11_OVERLOAD(std::string, OverrideTest, str_ref); } - public: - std::string &str_ref() override { return _tmp = str_ref_helper(); } - - A A_value() override { PYBIND11_OVERLOAD(A, OverrideTest, A_value); } - A &A_ref() override { PYBIND11_OVERLOAD(A &, OverrideTest, A_ref); } - }; - py::class_(m2, "OverrideTest_A") - .def_readwrite("value", &OverrideTest::A::value); - py::class_(m2, "OverrideTest") - .def(py::init()) - .def("str_value", &OverrideTest::str_value) -// .def("str_ref", &OverrideTest::str_ref) - .def("A_value", &OverrideTest::A_value) - .def("A_ref", &OverrideTest::A_ref); - - /// Issue 393: need to return NotSupported to ensure correct arithmetic operator behavior - py::class_(m2, "OpTest1") - .def(py::init<>()) - .def(py::self + py::self); - - py::class_(m2, "OpTest2") - .def(py::init<>()) - .def(py::self + py::self) - .def("__add__", [](const OpTest2& c2, const OpTest1& c1) { return c2 + c1; }) - .def("__radd__", [](const OpTest2& c2, const OpTest1& c1) { return c2 + c1; }); - - // Issue 388: Can't make iterators via make_iterator() with different r/v policies - static std::vector list = { 1, 2, 3 }; - m2.def("make_iterator_1", []() { return py::make_iterator(list); }); - m2.def("make_iterator_2", []() { return py::make_iterator(list); }); - - static std::vector nothrows; - // Issue 461: registering two things with the same name: - py::class_(m2, "Dupe1") - .def("get_value", &Dupe1::get_value) - ; - m2.def("dupe1_factory", [](int v) { return new Dupe1(v); }); - - py::class_(m2, "Dupe2"); - py::exception(m2, "DupeException"); - - try { - m2.def("Dupe1", [](int v) { return new Dupe1(v); }); - nothrows.emplace_back("Dupe1"); - } - catch (std::runtime_error &) {} - try { - py::class_(m2, "dupe1_factory"); - nothrows.emplace_back("dupe1_factory"); - } - catch (std::runtime_error &) {} - try { - py::exception(m2, "Dupe2"); - nothrows.emplace_back("Dupe2"); - } - catch (std::runtime_error &) {} - try { - m2.def("DupeException", []() { return 30; }); - nothrows.emplace_back("DupeException1"); - } - catch (std::runtime_error &) {} - try { - py::class_(m2, "DupeException"); - nothrows.emplace_back("DupeException2"); - } - catch (std::runtime_error &) {} - m2.def("dupe_exception_failures", []() { - py::list l; - for (auto &e : nothrows) l.append(py::cast(e)); - return l; - }); - - /// Issue #471: shared pointer instance not dellocated - class SharedChild : public std::enable_shared_from_this { - public: - SharedChild() { print_created(this); } - ~SharedChild() { print_destroyed(this); } - }; - - class SharedParent { - public: - SharedParent() : child(std::make_shared()) { } - const SharedChild &get_child() const { return *child; } - - private: - std::shared_ptr child; - }; - - py::class_>(m, "SharedChild"); - py::class_>(m, "SharedParent") - .def(py::init<>()) - .def("get_child", &SharedParent::get_child, py::return_value_policy::reference); - - /// Issue/PR #478: unique ptrs constructed and freed without destruction - class SpecialHolderObj { - public: - int val = 0; - SpecialHolderObj *ch = nullptr; - SpecialHolderObj(int v, bool make_child = true) : val{v}, ch{make_child ? new SpecialHolderObj(val+1, false) : nullptr} - { print_created(this, val); } - ~SpecialHolderObj() { delete ch; print_destroyed(this); } - SpecialHolderObj *child() { return ch; } - }; - - py::class_>(m, "SpecialHolderObj") - .def(py::init()) - .def("child", &SpecialHolderObj::child, pybind11::return_value_policy::reference_internal) - .def_readwrite("val", &SpecialHolderObj::val) - .def_static("holder_cstats", &ConstructorStats::get>, - py::return_value_policy::reference); - - /// Issue #484: number conversion generates unhandled exceptions - m2.def("test_complex", [](float x) { py::print("{}"_s.format(x)); }); - m2.def("test_complex", [](std::complex x) { py::print("({}, {})"_s.format(x.real(), x.imag())); }); - - /// Issue #511: problem with inheritance + overwritten def_static - struct MyBase { - static std::unique_ptr make() { - return std::unique_ptr(new MyBase()); - } - }; - - struct MyDerived : MyBase { - static std::unique_ptr make() { - return std::unique_ptr(new MyDerived()); - } - }; - - py::class_(m2, "MyBase") - .def_static("make", &MyBase::make); - - py::class_(m2, "MyDerived") - .def_static("make", &MyDerived::make) - .def_static("make2", &MyDerived::make); -} - -// MSVC workaround: trying to use a lambda here crashes MSCV -test_initializer issues(&init_issues); diff --git a/stormpy/resources/pybind11/tests/test_issues.py b/stormpy/resources/pybind11/tests/test_issues.py deleted file mode 100755 index 2098ff8a3..000000000 --- a/stormpy/resources/pybind11/tests/test_issues.py +++ /dev/null @@ -1,252 +0,0 @@ -import pytest -import gc -from pybind11_tests import ConstructorStats - - -def test_regressions(): - from pybind11_tests.issues import print_cchar, print_char - - # #137: const char* isn't handled properly - assert print_cchar("const char *") == "const char *" - # #150: char bindings broken - assert print_char("c") == "c" - - -def test_dispatch_issue(msg): - """#159: virtual function dispatch has problems with similar-named functions""" - from pybind11_tests.issues import DispatchIssue, dispatch_issue_go - - class PyClass1(DispatchIssue): - def dispatch(self): - return "Yay.." - - class PyClass2(DispatchIssue): - def dispatch(self): - with pytest.raises(RuntimeError) as excinfo: - super(PyClass2, self).dispatch() - assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"' - - p = PyClass1() - return dispatch_issue_go(p) - - b = PyClass2() - assert dispatch_issue_go(b) == "Yay.." - - -def test_reference_wrapper(): - """#171: Can't return reference wrappers (or STL data structures containing them)""" - from pybind11_tests.issues import Placeholder, return_vec_of_reference_wrapper - - assert str(return_vec_of_reference_wrapper(Placeholder(4))) == \ - "[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]" - - -def test_iterator_passthrough(): - """#181: iterator passthrough did not compile""" - from pybind11_tests.issues import iterator_passthrough - - assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15] - - -def test_shared_ptr_gc(): - """// #187: issue involving std::shared_ptr<> return value policy & garbage collection""" - from pybind11_tests.issues import ElementList, ElementA - - el = ElementList() - for i in range(10): - el.add(ElementA(i)) - gc.collect() - for i, v in enumerate(el.get()): - assert i == v.value() - - -def test_no_id(msg): - from pybind11_tests.issues import get_element, expect_float, expect_int - - with pytest.raises(TypeError) as excinfo: - get_element(None) - assert msg(excinfo.value) == """ - get_element(): incompatible function arguments. The following argument types are supported: - 1. (arg0: m.issues.ElementA) -> int - - Invoked with: None - """ - - with pytest.raises(TypeError) as excinfo: - expect_int(5.2) - assert msg(excinfo.value) == """ - expect_int(): incompatible function arguments. The following argument types are supported: - 1. (arg0: int) -> int - - Invoked with: 5.2 - """ - assert expect_float(12) == 12 - - -def test_str_issue(msg): - """Issue #283: __str__ called on uninitialized instance when constructor arguments invalid""" - from pybind11_tests.issues import StrIssue - - assert str(StrIssue(3)) == "StrIssue[3]" - - with pytest.raises(TypeError) as excinfo: - str(StrIssue("no", "such", "constructor")) - assert msg(excinfo.value) == """ - __init__(): incompatible constructor arguments. The following argument types are supported: - 1. m.issues.StrIssue(arg0: int) - 2. m.issues.StrIssue() - - Invoked with: 'no', 'such', 'constructor' - """ - - -def test_nested(): - """ #328: first member in a class can't be used in operators""" - from pybind11_tests.issues import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC - - a = NestA() - b = NestB() - c = NestC() - - a += 10 - assert get_NestA(a) == 13 - b.a += 100 - assert get_NestA(b.a) == 103 - c.b.a += 1000 - assert get_NestA(c.b.a) == 1003 - b -= 1 - assert get_NestB(b) == 3 - c.b -= 3 - assert get_NestB(c.b) == 1 - c *= 7 - assert get_NestC(c) == 35 - - abase = a.as_base() - assert abase.value == -2 - a.as_base().value += 44 - assert abase.value == 42 - assert c.b.a.as_base().value == -2 - c.b.a.as_base().value += 44 - assert c.b.a.as_base().value == 42 - - del c - gc.collect() - del a # Should't delete while abase is still alive - gc.collect() - - assert abase.value == 42 - del abase, b - gc.collect() - - -def test_move_fallback(): - from pybind11_tests.issues import get_moveissue1, get_moveissue2 - m2 = get_moveissue2(2) - assert m2.value == 2 - m1 = get_moveissue1(1) - assert m1.value == 1 - - -def test_override_ref(): - from pybind11_tests.issues import OverrideTest - o = OverrideTest("asdf") - - # Not allowed (see associated .cpp comment) - # i = o.str_ref() - # assert o.str_ref() == "asdf" - assert o.str_value() == "asdf" - - assert o.A_value().value == "hi" - a = o.A_ref() - assert a.value == "hi" - a.value = "bye" - assert a.value == "bye" - - -def test_operators_notimplemented(capture): - from pybind11_tests.issues import OpTest1, OpTest2 - with capture: - c1, c2 = OpTest1(), OpTest2() - c1 + c1 - c2 + c2 - c2 + c1 - c1 + c2 - assert capture == """ - Add OpTest1 with OpTest1 - Add OpTest2 with OpTest2 - Add OpTest2 with OpTest1 - Add OpTest2 with OpTest1 - """ - - -def test_iterator_rvpolicy(): - """ Issue 388: Can't make iterators via make_iterator() with different r/v policies """ - from pybind11_tests.issues import make_iterator_1 - from pybind11_tests.issues import make_iterator_2 - - assert list(make_iterator_1()) == [1, 2, 3] - assert list(make_iterator_2()) == [1, 2, 3] - assert not isinstance(make_iterator_1(), type(make_iterator_2())) - - -def test_dupe_assignment(): - """ Issue 461: overwriting a class with a function """ - from pybind11_tests.issues import dupe_exception_failures - assert dupe_exception_failures() == [] - - -def test_enable_shared_from_this_with_reference_rvp(): - """ Issue #471: shared pointer instance not dellocated """ - from pybind11_tests import SharedParent, SharedChild - - parent = SharedParent() - child = parent.get_child() - - cstats = ConstructorStats.get(SharedChild) - assert cstats.alive() == 1 - del child, parent - assert cstats.alive() == 0 - - -def test_non_destructed_holders(): - """ Issue #478: unique ptrs constructed and freed without destruction """ - from pybind11_tests import SpecialHolderObj - - a = SpecialHolderObj(123) - b = a.child() - - assert a.val == 123 - assert b.val == 124 - - cstats = SpecialHolderObj.holder_cstats() - assert cstats.alive() == 1 - del b - assert cstats.alive() == 1 - del a - assert cstats.alive() == 0 - - -def test_complex_cast(capture): - """ Issue #484: number conversion generates unhandled exceptions """ - from pybind11_tests.issues import test_complex - - with capture: - test_complex(1) - test_complex(2j) - - assert capture == """ - 1.0 - (0.0, 2.0) - """ - - -def test_inheritance_override_def_static(): - from pybind11_tests.issues import MyBase, MyDerived - - b = MyBase.make() - d1 = MyDerived.make2() - d2 = MyDerived.make() - - assert isinstance(b, MyBase) - assert isinstance(d1, MyDerived) - assert isinstance(d2, MyDerived) diff --git a/stormpy/resources/pybind11/tests/test_keep_alive.cpp b/stormpy/resources/pybind11/tests/test_keep_alive.cpp deleted file mode 100755 index cd62a02e8..000000000 --- a/stormpy/resources/pybind11/tests/test_keep_alive.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - tests/test_keep_alive.cpp -- keep_alive modifier (pybind11's version - of Boost.Python's with_custodian_and_ward / with_custodian_and_ward_postcall) - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -class Child { -public: - Child() { py::print("Allocating child."); } - ~Child() { py::print("Releasing child."); } -}; - -class Parent { -public: - Parent() { py::print("Allocating parent."); } - ~Parent() { py::print("Releasing parent."); } - void addChild(Child *) { } - Child *returnChild() { return new Child(); } - Child *returnNullChild() { return nullptr; } -}; - -test_initializer keep_alive([](py::module &m) { - py::class_(m, "Parent") - .def(py::init<>()) - .def("addChild", &Parent::addChild) - .def("addChildKeepAlive", &Parent::addChild, py::keep_alive<1, 2>()) - .def("returnChild", &Parent::returnChild) - .def("returnChildKeepAlive", &Parent::returnChild, py::keep_alive<1, 0>()) - .def("returnNullChildKeepAliveChild", &Parent::returnNullChild, py::keep_alive<1, 0>()) - .def("returnNullChildKeepAliveParent", &Parent::returnNullChild, py::keep_alive<0, 1>()); - - py::class_(m, "Child") - .def(py::init<>()); -}); diff --git a/stormpy/resources/pybind11/tests/test_keep_alive.py b/stormpy/resources/pybind11/tests/test_keep_alive.py deleted file mode 100755 index 0cef34658..000000000 --- a/stormpy/resources/pybind11/tests/test_keep_alive.py +++ /dev/null @@ -1,97 +0,0 @@ -import gc - - -def test_keep_alive_argument(capture): - from pybind11_tests import Parent, Child - - with capture: - p = Parent() - assert capture == "Allocating parent." - with capture: - p.addChild(Child()) - gc.collect() - assert capture == """ - Allocating child. - Releasing child. - """ - with capture: - del p - gc.collect() - assert capture == "Releasing parent." - - with capture: - p = Parent() - assert capture == "Allocating parent." - with capture: - p.addChildKeepAlive(Child()) - gc.collect() - assert capture == "Allocating child." - with capture: - del p - gc.collect() - assert capture == """ - Releasing parent. - Releasing child. - """ - - -def test_keep_alive_return_value(capture): - from pybind11_tests import Parent - - with capture: - p = Parent() - assert capture == "Allocating parent." - with capture: - p.returnChild() - gc.collect() - assert capture == """ - Allocating child. - Releasing child. - """ - with capture: - del p - gc.collect() - assert capture == "Releasing parent." - - with capture: - p = Parent() - assert capture == "Allocating parent." - with capture: - p.returnChildKeepAlive() - gc.collect() - assert capture == "Allocating child." - with capture: - del p - gc.collect() - assert capture == """ - Releasing parent. - Releasing child. - """ - - -def test_return_none(capture): - from pybind11_tests import Parent - - with capture: - p = Parent() - assert capture == "Allocating parent." - with capture: - p.returnNullChildKeepAliveChild() - gc.collect() - assert capture == "" - with capture: - del p - gc.collect() - assert capture == "Releasing parent." - - with capture: - p = Parent() - assert capture == "Allocating parent." - with capture: - p.returnNullChildKeepAliveParent() - gc.collect() - assert capture == "" - with capture: - del p - gc.collect() - assert capture == "Releasing parent." diff --git a/stormpy/resources/pybind11/tests/test_kwargs_and_defaults.cpp b/stormpy/resources/pybind11/tests/test_kwargs_and_defaults.cpp deleted file mode 100755 index 24fc0cd5b..000000000 --- a/stormpy/resources/pybind11/tests/test_kwargs_and_defaults.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - tests/test_kwargs_and_defaults.cpp -- keyword arguments and default values - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include - -std::string kw_func(int x, int y) { return "x=" + std::to_string(x) + ", y=" + std::to_string(y); } - -std::string kw_func4(const std::vector &entries) { - std::string ret = "{"; - for (int i : entries) - ret += std::to_string(i) + " "; - ret.back() = '}'; - return ret; -} - -py::tuple args_function(py::args args) { - return args; -} - -py::tuple args_kwargs_function(py::args args, py::kwargs kwargs) { - return py::make_tuple(args, kwargs); -} - -struct KWClass { - void foo(int, float) {} -}; - -test_initializer arg_keywords_and_defaults([](py::module &m) { - m.def("kw_func0", &kw_func); - m.def("kw_func1", &kw_func, py::arg("x"), py::arg("y")); - m.def("kw_func2", &kw_func, py::arg("x") = 100, py::arg("y") = 200); - m.def("kw_func3", [](const char *) { }, py::arg("data") = std::string("Hello world!")); - - /* A fancier default argument */ - std::vector list; - list.push_back(13); - list.push_back(17); - m.def("kw_func4", &kw_func4, py::arg("myList") = list); - - m.def("args_function", &args_function); - m.def("args_kwargs_function", &args_kwargs_function); - - m.def("kw_func_udl", &kw_func, "x"_a, "y"_a=300); - m.def("kw_func_udl_z", &kw_func, "x"_a, "y"_a=0); - - py::class_(m, "KWClass") - .def("foo0", &KWClass::foo) - .def("foo1", &KWClass::foo, "x"_a, "y"_a); -}); diff --git a/stormpy/resources/pybind11/tests/test_kwargs_and_defaults.py b/stormpy/resources/pybind11/tests/test_kwargs_and_defaults.py deleted file mode 100755 index 852d03c6e..000000000 --- a/stormpy/resources/pybind11/tests/test_kwargs_and_defaults.py +++ /dev/null @@ -1,57 +0,0 @@ -import pytest -from pybind11_tests import (kw_func0, kw_func1, kw_func2, kw_func3, kw_func4, args_function, - args_kwargs_function, kw_func_udl, kw_func_udl_z, KWClass) - - -def test_function_signatures(doc): - assert doc(kw_func0) == "kw_func0(arg0: int, arg1: int) -> str" - assert doc(kw_func1) == "kw_func1(x: int, y: int) -> str" - assert doc(kw_func2) == "kw_func2(x: int=100, y: int=200) -> str" - assert doc(kw_func3) == "kw_func3(data: str='Hello world!') -> None" - assert doc(kw_func4) == "kw_func4(myList: List[int]=[13, 17]) -> str" - assert doc(kw_func_udl) == "kw_func_udl(x: int, y: int=300) -> str" - assert doc(kw_func_udl_z) == "kw_func_udl_z(x: int, y: int=0) -> str" - assert doc(args_function) == "args_function(*args) -> tuple" - assert doc(args_kwargs_function) == "args_kwargs_function(*args, **kwargs) -> tuple" - assert doc(KWClass.foo0) == "foo0(self: m.KWClass, arg0: int, arg1: float) -> None" - assert doc(KWClass.foo1) == "foo1(self: m.KWClass, x: int, y: float) -> None" - - -def test_named_arguments(msg): - assert kw_func0(5, 10) == "x=5, y=10" - - assert kw_func1(5, 10) == "x=5, y=10" - assert kw_func1(5, y=10) == "x=5, y=10" - assert kw_func1(y=10, x=5) == "x=5, y=10" - - assert kw_func2() == "x=100, y=200" - assert kw_func2(5) == "x=5, y=200" - assert kw_func2(x=5) == "x=5, y=200" - assert kw_func2(y=10) == "x=100, y=10" - assert kw_func2(5, 10) == "x=5, y=10" - assert kw_func2(x=5, y=10) == "x=5, y=10" - - with pytest.raises(TypeError) as excinfo: - # noinspection PyArgumentList - kw_func2(x=5, y=10, z=12) - assert msg(excinfo.value) == """ - kw_func2(): incompatible function arguments. The following argument types are supported: - 1. (x: int=100, y: int=200) -> str - - Invoked with: - """ - - assert kw_func4() == "{13 17}" - assert kw_func4(myList=[1, 2, 3]) == "{1 2 3}" - - assert kw_func_udl(x=5, y=10) == "x=5, y=10" - assert kw_func_udl_z(x=5) == "x=5, y=0" - - -def test_arg_and_kwargs(): - args = 'arg1_value', 'arg2_value', 3 - assert args_function(*args) == args - - args = 'a1', 'a2' - kwargs = dict(arg3='a3', arg4=4) - assert args_kwargs_function(*args, **kwargs) == (args, kwargs) diff --git a/stormpy/resources/pybind11/tests/test_methods_and_attributes.cpp b/stormpy/resources/pybind11/tests/test_methods_and_attributes.cpp deleted file mode 100755 index ab59d8c21..000000000 --- a/stormpy/resources/pybind11/tests/test_methods_and_attributes.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - tests/test_methods_and_attributes.cpp -- constructors, deconstructors, attribute access, - __str__, argument and return value conventions - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" - -class ExampleMandA { -public: - ExampleMandA() { print_default_created(this); } - ExampleMandA(int value) : value(value) { print_created(this, value); } - ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); } - ExampleMandA(ExampleMandA &&e) : value(e.value) { print_move_created(this); } - ~ExampleMandA() { print_destroyed(this); } - - std::string toString() { - return "ExampleMandA[value=" + std::to_string(value) + "]"; - } - - void operator=(const ExampleMandA &e) { print_copy_assigned(this); value = e.value; } - void operator=(ExampleMandA &&e) { print_move_assigned(this); value = e.value; } - - void add1(ExampleMandA other) { value += other.value; } // passing by value - void add2(ExampleMandA &other) { value += other.value; } // passing by reference - void add3(const ExampleMandA &other) { value += other.value; } // passing by const reference - void add4(ExampleMandA *other) { value += other->value; } // passing by pointer - void add5(const ExampleMandA *other) { value += other->value; } // passing by const pointer - - void add6(int other) { value += other; } // passing by value - void add7(int &other) { value += other; } // passing by reference - void add8(const int &other) { value += other; } // passing by const reference - void add9(int *other) { value += *other; } // passing by pointer - void add10(const int *other) { value += *other; } // passing by const pointer - - ExampleMandA self1() { return *this; } // return by value - ExampleMandA &self2() { return *this; } // return by reference - const ExampleMandA &self3() { return *this; } // return by const reference - ExampleMandA *self4() { return this; } // return by pointer - const ExampleMandA *self5() { return this; } // return by const pointer - - int internal1() { return value; } // return by value - int &internal2() { return value; } // return by reference - const int &internal3() { return value; } // return by const reference - int *internal4() { return &value; } // return by pointer - const int *internal5() { return &value; } // return by const pointer - - int value = 0; -}; - -struct TestProperties { - int value = 1; - static int static_value; - - int get() const { return value; } - void set(int v) { value = v; } - - static int static_get() { return static_value; } - static void static_set(int v) { static_value = v; } -}; - -int TestProperties::static_value = 1; - -struct SimpleValue { int value = 1; }; - -struct TestPropRVP { - SimpleValue v1; - SimpleValue v2; - static SimpleValue sv1; - static SimpleValue sv2; - - const SimpleValue &get1() const { return v1; } - const SimpleValue &get2() const { return v2; } - SimpleValue get_rvalue() const { return v2; } - void set1(int v) { v1.value = v; } - void set2(int v) { v2.value = v; } -}; - -SimpleValue TestPropRVP::sv1{}; -SimpleValue TestPropRVP::sv2{}; - -class DynamicClass { -public: - DynamicClass() { print_default_created(this); } - ~DynamicClass() { print_destroyed(this); } -}; - -class CppDerivedDynamicClass : public DynamicClass { }; - -test_initializer methods_and_attributes([](py::module &m) { - py::class_(m, "ExampleMandA") - .def(py::init<>()) - .def(py::init()) - .def(py::init()) - .def("add1", &ExampleMandA::add1) - .def("add2", &ExampleMandA::add2) - .def("add3", &ExampleMandA::add3) - .def("add4", &ExampleMandA::add4) - .def("add5", &ExampleMandA::add5) - .def("add6", &ExampleMandA::add6) - .def("add7", &ExampleMandA::add7) - .def("add8", &ExampleMandA::add8) - .def("add9", &ExampleMandA::add9) - .def("add10", &ExampleMandA::add10) - .def("self1", &ExampleMandA::self1) - .def("self2", &ExampleMandA::self2) - .def("self3", &ExampleMandA::self3) - .def("self4", &ExampleMandA::self4) - .def("self5", &ExampleMandA::self5) - .def("internal1", &ExampleMandA::internal1) - .def("internal2", &ExampleMandA::internal2) - .def("internal3", &ExampleMandA::internal3) - .def("internal4", &ExampleMandA::internal4) - .def("internal5", &ExampleMandA::internal5) - .def("__str__", &ExampleMandA::toString) - .def_readwrite("value", &ExampleMandA::value) - ; - - py::class_(m, "TestProperties") - .def(py::init<>()) - .def_readonly("def_readonly", &TestProperties::value) - .def_readwrite("def_readwrite", &TestProperties::value) - .def_property_readonly("def_property_readonly", &TestProperties::get) - .def_property("def_property", &TestProperties::get, &TestProperties::set) - .def_readonly_static("def_readonly_static", &TestProperties::static_value) - .def_readwrite_static("def_readwrite_static", &TestProperties::static_value) - .def_property_readonly_static("def_property_readonly_static", - [](py::object) { return TestProperties::static_get(); }) - .def_property_static("def_property_static", - [](py::object) { return TestProperties::static_get(); }, - [](py::object, int v) { return TestProperties::static_set(v); }); - - py::class_(m, "SimpleValue") - .def_readwrite("value", &SimpleValue::value); - - auto static_get1 = [](py::object) -> const SimpleValue & { return TestPropRVP::sv1; }; - auto static_get2 = [](py::object) -> const SimpleValue & { return TestPropRVP::sv2; }; - auto static_set1 = [](py::object, int v) { TestPropRVP::sv1.value = v; }; - auto static_set2 = [](py::object, int v) { TestPropRVP::sv2.value = v; }; - auto rvp_copy = py::return_value_policy::copy; - - py::class_(m, "TestPropRVP") - .def(py::init<>()) - .def_property_readonly("ro_ref", &TestPropRVP::get1) - .def_property_readonly("ro_copy", &TestPropRVP::get2, rvp_copy) - .def_property_readonly("ro_func", py::cpp_function(&TestPropRVP::get2, rvp_copy)) - .def_property("rw_ref", &TestPropRVP::get1, &TestPropRVP::set1) - .def_property("rw_copy", &TestPropRVP::get2, &TestPropRVP::set2, rvp_copy) - .def_property("rw_func", py::cpp_function(&TestPropRVP::get2, rvp_copy), &TestPropRVP::set2) - .def_property_readonly_static("static_ro_ref", static_get1) - .def_property_readonly_static("static_ro_copy", static_get2, rvp_copy) - .def_property_readonly_static("static_ro_func", py::cpp_function(static_get2, rvp_copy)) - .def_property_static("static_rw_ref", static_get1, static_set1) - .def_property_static("static_rw_copy", static_get2, static_set2, rvp_copy) - .def_property_static("static_rw_func", py::cpp_function(static_get2, rvp_copy), static_set2) - .def_property_readonly("rvalue", &TestPropRVP::get_rvalue) - .def_property_readonly_static("static_rvalue", [](py::object) { return SimpleValue(); }); - - py::class_(m, "DynamicClass", py::dynamic_attr()) - .def(py::init()); - - py::class_(m, "CppDerivedDynamicClass") - .def(py::init()); -}); diff --git a/stormpy/resources/pybind11/tests/test_methods_and_attributes.py b/stormpy/resources/pybind11/tests/test_methods_and_attributes.py deleted file mode 100755 index 28c0de538..000000000 --- a/stormpy/resources/pybind11/tests/test_methods_and_attributes.py +++ /dev/null @@ -1,189 +0,0 @@ -import pytest -from pybind11_tests import ExampleMandA, ConstructorStats - - -def test_methods_and_attributes(): - instance1 = ExampleMandA() - instance2 = ExampleMandA(32) - - instance1.add1(instance2) - instance1.add2(instance2) - instance1.add3(instance2) - instance1.add4(instance2) - instance1.add5(instance2) - instance1.add6(32) - instance1.add7(32) - instance1.add8(32) - instance1.add9(32) - instance1.add10(32) - - assert str(instance1) == "ExampleMandA[value=320]" - assert str(instance2) == "ExampleMandA[value=32]" - assert str(instance1.self1()) == "ExampleMandA[value=320]" - assert str(instance1.self2()) == "ExampleMandA[value=320]" - assert str(instance1.self3()) == "ExampleMandA[value=320]" - assert str(instance1.self4()) == "ExampleMandA[value=320]" - assert str(instance1.self5()) == "ExampleMandA[value=320]" - - assert instance1.internal1() == 320 - assert instance1.internal2() == 320 - assert instance1.internal3() == 320 - assert instance1.internal4() == 320 - assert instance1.internal5() == 320 - - assert instance1.value == 320 - instance1.value = 100 - assert str(instance1) == "ExampleMandA[value=100]" - - cstats = ConstructorStats.get(ExampleMandA) - assert cstats.alive() == 2 - del instance1, instance2 - assert cstats.alive() == 0 - assert cstats.values() == ["32"] - assert cstats.default_constructions == 1 - assert cstats.copy_constructions == 3 - assert cstats.move_constructions >= 1 - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 - - -def test_properties(): - from pybind11_tests import TestProperties - - instance = TestProperties() - - assert instance.def_readonly == 1 - with pytest.raises(AttributeError): - instance.def_readonly = 2 - - instance.def_readwrite = 2 - assert instance.def_readwrite == 2 - - assert instance.def_property_readonly == 2 - with pytest.raises(AttributeError): - instance.def_property_readonly = 3 - - instance.def_property = 3 - assert instance.def_property == 3 - - -def test_static_properties(): - from pybind11_tests import TestProperties as Type - - assert Type.def_readonly_static == 1 - with pytest.raises(AttributeError): - Type.def_readonly_static = 2 - - Type.def_readwrite_static = 2 - assert Type.def_readwrite_static == 2 - - assert Type.def_property_readonly_static == 2 - with pytest.raises(AttributeError): - Type.def_property_readonly_static = 3 - - Type.def_property_static = 3 - assert Type.def_property_static == 3 - - -@pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"]) -def test_property_return_value_policies(access): - from pybind11_tests import TestPropRVP - - if not access.startswith("static"): - obj = TestPropRVP() - else: - obj = TestPropRVP - - ref = getattr(obj, access + "_ref") - assert ref.value == 1 - ref.value = 2 - assert getattr(obj, access + "_ref").value == 2 - ref.value = 1 # restore original value for static properties - - copy = getattr(obj, access + "_copy") - assert copy.value == 1 - copy.value = 2 - assert getattr(obj, access + "_copy").value == 1 - - copy = getattr(obj, access + "_func") - assert copy.value == 1 - copy.value = 2 - assert getattr(obj, access + "_func").value == 1 - - -def test_property_rvalue_policy(): - """When returning an rvalue, the return value policy is automatically changed from - `reference(_internal)` to `move`. The following would not work otherwise. - """ - from pybind11_tests import TestPropRVP - - instance = TestPropRVP() - o = instance.rvalue - assert o.value == 1 - o = TestPropRVP.static_rvalue - assert o.value == 1 - - -def test_dynamic_attributes(): - from pybind11_tests import DynamicClass, CppDerivedDynamicClass - - instance = DynamicClass() - assert not hasattr(instance, "foo") - assert "foo" not in dir(instance) - - # Dynamically add attribute - instance.foo = 42 - assert hasattr(instance, "foo") - assert instance.foo == 42 - assert "foo" in dir(instance) - - # __dict__ should be accessible and replaceable - assert "foo" in instance.__dict__ - instance.__dict__ = {"bar": True} - assert not hasattr(instance, "foo") - assert hasattr(instance, "bar") - - with pytest.raises(TypeError) as excinfo: - instance.__dict__ = [] - assert str(excinfo.value) == "__dict__ must be set to a dictionary, not a 'list'" - - cstats = ConstructorStats.get(DynamicClass) - assert cstats.alive() == 1 - del instance - assert cstats.alive() == 0 - - # Derived classes should work as well - class PythonDerivedDynamicClass(DynamicClass): - pass - - for cls in CppDerivedDynamicClass, PythonDerivedDynamicClass: - derived = cls() - derived.foobar = 100 - assert derived.foobar == 100 - - assert cstats.alive() == 1 - del derived - assert cstats.alive() == 0 - - -def test_cyclic_gc(): - from pybind11_tests import DynamicClass - - # One object references itself - instance = DynamicClass() - instance.circular_reference = instance - - cstats = ConstructorStats.get(DynamicClass) - assert cstats.alive() == 1 - del instance - assert cstats.alive() == 0 - - # Two object reference each other - i1 = DynamicClass() - i2 = DynamicClass() - i1.cycle = i2 - i2.cycle = i1 - - assert cstats.alive() == 2 - del i1, i2 - assert cstats.alive() == 0 diff --git a/stormpy/resources/pybind11/tests/test_modules.cpp b/stormpy/resources/pybind11/tests/test_modules.cpp deleted file mode 100755 index 50c7d8412..000000000 --- a/stormpy/resources/pybind11/tests/test_modules.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - tests/test_modules.cpp -- nested modules, importing modules, and - internal references - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" - -std::string submodule_func() { - return "submodule_func()"; -} - -class A { -public: - A(int v) : v(v) { print_created(this, v); } - ~A() { print_destroyed(this); } - A(const A&) { print_copy_created(this); } - A& operator=(const A ©) { print_copy_assigned(this); v = copy.v; return *this; } - std::string toString() { return "A[" + std::to_string(v) + "]"; } -private: - int v; -}; - -class B { -public: - B() { print_default_created(this); } - ~B() { print_destroyed(this); } - B(const B&) { print_copy_created(this); } - B& operator=(const B ©) { print_copy_assigned(this); a1 = copy.a1; a2 = copy.a2; return *this; } - A &get_a1() { return a1; } - A &get_a2() { return a2; } - - A a1{1}; - A a2{2}; -}; - -test_initializer modules([](py::module &m) { - py::module m_sub = m.def_submodule("submodule"); - m_sub.def("submodule_func", &submodule_func); - - py::class_(m_sub, "A") - .def(py::init()) - .def("__repr__", &A::toString); - - py::class_(m_sub, "B") - .def(py::init<>()) - .def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal) - .def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal) - .def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default - .def_readwrite("a2", &B::a2); - - m.attr("OD") = py::module::import("collections").attr("OrderedDict"); -}); diff --git a/stormpy/resources/pybind11/tests/test_modules.py b/stormpy/resources/pybind11/tests/test_modules.py deleted file mode 100755 index fe72f190a..000000000 --- a/stormpy/resources/pybind11/tests/test_modules.py +++ /dev/null @@ -1,54 +0,0 @@ - -def test_nested_modules(): - import pybind11_tests - from pybind11_tests.submodule import submodule_func - - assert pybind11_tests.__name__ == "pybind11_tests" - assert pybind11_tests.submodule.__name__ == "pybind11_tests.submodule" - - assert submodule_func() == "submodule_func()" - - -def test_reference_internal(): - from pybind11_tests import ConstructorStats - from pybind11_tests.submodule import A, B - - b = B() - assert str(b.get_a1()) == "A[1]" - assert str(b.a1) == "A[1]" - assert str(b.get_a2()) == "A[2]" - assert str(b.a2) == "A[2]" - - b.a1 = A(42) - b.a2 = A(43) - assert str(b.get_a1()) == "A[42]" - assert str(b.a1) == "A[42]" - assert str(b.get_a2()) == "A[43]" - assert str(b.a2) == "A[43]" - - astats, bstats = ConstructorStats.get(A), ConstructorStats.get(B) - assert astats.alive() == 2 - assert bstats.alive() == 1 - del b - assert astats.alive() == 0 - assert bstats.alive() == 0 - assert astats.values() == ['1', '2', '42', '43'] - assert bstats.values() == [] - assert astats.default_constructions == 0 - assert bstats.default_constructions == 1 - assert astats.copy_constructions == 0 - assert bstats.copy_constructions == 0 - # assert astats.move_constructions >= 0 # Don't invoke any - # assert bstats.move_constructions >= 0 # Don't invoke any - assert astats.copy_assignments == 2 - assert bstats.copy_assignments == 0 - assert astats.move_assignments == 0 - assert bstats.move_assignments == 0 - - -def test_importing(): - from pybind11_tests import OD - from collections import OrderedDict - - assert OD is OrderedDict - assert str(OD([(1, 'a'), (2, 'b')])) == "OrderedDict([(1, 'a'), (2, 'b')])" diff --git a/stormpy/resources/pybind11/tests/test_multiple_inheritance.cpp b/stormpy/resources/pybind11/tests/test_multiple_inheritance.cpp deleted file mode 100755 index 3cb12b68d..000000000 --- a/stormpy/resources/pybind11/tests/test_multiple_inheritance.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - tests/test_multiple_inheritance.cpp -- multiple inheritance, - implicit MI casts - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - - -struct Base1 { - Base1(int i) : i(i) { } - int foo() { return i; } - int i; -}; - -struct Base2 { - Base2(int i) : i(i) { } - int bar() { return i; } - int i; -}; - -struct Base12 : Base1, Base2 { - Base12(int i, int j) : Base1(i), Base2(j) { } -}; - -struct MIType : Base12 { - MIType(int i, int j) : Base12(i, j) { } -}; - -test_initializer multiple_inheritance([](py::module &m) { - py::class_(m, "Base1") - .def(py::init()) - .def("foo", &Base1::foo); - - py::class_(m, "Base2") - .def(py::init()) - .def("bar", &Base2::bar); - - py::class_(m, "Base12"); - - py::class_(m, "MIType") - .def(py::init()); -}); - -/* Test the case where not all base classes are specified, - and where pybind11 requires the py::multiple_inheritance - flag to perform proper casting between types */ - -struct Base1a { - Base1a(int i) : i(i) { } - int foo() { return i; } - int i; -}; - -struct Base2a { - Base2a(int i) : i(i) { } - int bar() { return i; } - int i; -}; - -struct Base12a : Base1a, Base2a { - Base12a(int i, int j) : Base1a(i), Base2a(j) { } -}; - -test_initializer multiple_inheritance_nonexplicit([](py::module &m) { - py::class_>(m, "Base1a") - .def(py::init()) - .def("foo", &Base1a::foo); - - py::class_>(m, "Base2a") - .def(py::init()) - .def("bar", &Base2a::bar); - - py::class_>(m, "Base12a", py::multiple_inheritance()) - .def(py::init()); - - m.def("bar_base2a", [](Base2a *b) { return b->bar(); }); - m.def("bar_base2a_sharedptr", [](std::shared_ptr b) { return b->bar(); }); -}); diff --git a/stormpy/resources/pybind11/tests/test_multiple_inheritance.py b/stormpy/resources/pybind11/tests/test_multiple_inheritance.py deleted file mode 100755 index 581cf5687..000000000 --- a/stormpy/resources/pybind11/tests/test_multiple_inheritance.py +++ /dev/null @@ -1,64 +0,0 @@ - - -def test_multiple_inheritance_cpp(): - from pybind11_tests import MIType - - mt = MIType(3, 4) - - assert mt.foo() == 3 - assert mt.bar() == 4 - - -def test_multiple_inheritance_mix1(): - from pybind11_tests import Base2 - - class Base1: - def __init__(self, i): - self.i = i - - def foo(self): - return self.i - - class MITypePy(Base1, Base2): - def __init__(self, i, j): - Base1.__init__(self, i) - Base2.__init__(self, j) - - mt = MITypePy(3, 4) - - assert mt.foo() == 3 - assert mt.bar() == 4 - - -def test_multiple_inheritance_mix2(): - from pybind11_tests import Base1 - - class Base2: - def __init__(self, i): - self.i = i - - def bar(self): - return self.i - - class MITypePy(Base1, Base2): - def __init__(self, i, j): - Base1.__init__(self, i) - Base2.__init__(self, j) - - mt = MITypePy(3, 4) - - assert mt.foo() == 3 - assert mt.bar() == 4 - - -def test_multiple_inheritance_virtbase(): - from pybind11_tests import Base12a, bar_base2a, bar_base2a_sharedptr - - class MITypePy(Base12a): - def __init__(self, i, j): - Base12a.__init__(self, i, j) - - mt = MITypePy(3, 4) - assert mt.bar() == 4 - assert bar_base2a(mt) == 4 - assert bar_base2a_sharedptr(mt) == 4 diff --git a/stormpy/resources/pybind11/tests/test_numpy_array.cpp b/stormpy/resources/pybind11/tests/test_numpy_array.cpp deleted file mode 100755 index 14c4c2999..000000000 --- a/stormpy/resources/pybind11/tests/test_numpy_array.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - tests/test_numpy_array.cpp -- test core array functionality - - Copyright (c) 2016 Ivan Smirnov - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -#include -#include - -#include -#include - -using arr = py::array; -using arr_t = py::array_t; - -template arr data(const arr& a, Ix... index) { - return arr(a.nbytes() - a.offset_at(index...), (const uint8_t *) a.data(index...)); -} - -template arr data_t(const arr_t& a, Ix... index) { - return arr(a.size() - a.index_at(index...), a.data(index...)); -} - -arr& mutate_data(arr& a) { - auto ptr = (uint8_t *) a.mutable_data(); - for (size_t i = 0; i < a.nbytes(); i++) - ptr[i] = (uint8_t) (ptr[i] * 2); - return a; -} - -arr_t& mutate_data_t(arr_t& a) { - auto ptr = a.mutable_data(); - for (size_t i = 0; i < a.size(); i++) - ptr[i]++; - return a; -} - -template arr& mutate_data(arr& a, Ix... index) { - auto ptr = (uint8_t *) a.mutable_data(index...); - for (size_t i = 0; i < a.nbytes() - a.offset_at(index...); i++) - ptr[i] = (uint8_t) (ptr[i] * 2); - return a; -} - -template arr_t& mutate_data_t(arr_t& a, Ix... index) { - auto ptr = a.mutable_data(index...); - for (size_t i = 0; i < a.size() - a.index_at(index...); i++) - ptr[i]++; - return a; -} - -template size_t index_at(const arr& a, Ix... idx) { return a.index_at(idx...); } -template size_t index_at_t(const arr_t& a, Ix... idx) { return a.index_at(idx...); } -template size_t offset_at(const arr& a, Ix... idx) { return a.offset_at(idx...); } -template size_t offset_at_t(const arr_t& a, Ix... idx) { return a.offset_at(idx...); } -template size_t at_t(const arr_t& a, Ix... idx) { return a.at(idx...); } -template arr_t& mutate_at_t(arr_t& a, Ix... idx) { a.mutable_at(idx...)++; return a; } - -#define def_index_fn(name, type) \ - sm.def(#name, [](type a) { return name(a); }); \ - sm.def(#name, [](type a, int i) { return name(a, i); }); \ - sm.def(#name, [](type a, int i, int j) { return name(a, i, j); }); \ - sm.def(#name, [](type a, int i, int j, int k) { return name(a, i, j, k); }); - -test_initializer numpy_array([](py::module &m) { - auto sm = m.def_submodule("array"); - - sm.def("ndim", [](const arr& a) { return a.ndim(); }); - sm.def("shape", [](const arr& a) { return arr(a.ndim(), a.shape()); }); - sm.def("shape", [](const arr& a, size_t dim) { return a.shape(dim); }); - sm.def("strides", [](const arr& a) { return arr(a.ndim(), a.strides()); }); - sm.def("strides", [](const arr& a, size_t dim) { return a.strides(dim); }); - sm.def("writeable", [](const arr& a) { return a.writeable(); }); - sm.def("size", [](const arr& a) { return a.size(); }); - sm.def("itemsize", [](const arr& a) { return a.itemsize(); }); - sm.def("nbytes", [](const arr& a) { return a.nbytes(); }); - sm.def("owndata", [](const arr& a) { return a.owndata(); }); - - def_index_fn(data, const arr&); - def_index_fn(data_t, const arr_t&); - def_index_fn(index_at, const arr&); - def_index_fn(index_at_t, const arr_t&); - def_index_fn(offset_at, const arr&); - def_index_fn(offset_at_t, const arr_t&); - def_index_fn(mutate_data, arr&); - def_index_fn(mutate_data_t, arr_t&); - def_index_fn(at_t, const arr_t&); - def_index_fn(mutate_at_t, arr_t&); - - sm.def("make_f_array", [] { - return py::array_t({ 2, 2 }, { 4, 8 }); - }); - - sm.def("make_c_array", [] { - return py::array_t({ 2, 2 }, { 8, 4 }); - }); - - sm.def("wrap", [](py::array a) { - return py::array( - a.dtype(), - std::vector(a.shape(), a.shape() + a.ndim()), - std::vector(a.strides(), a.strides() + a.ndim()), - a.data(), - a - ); - }); - - struct ArrayClass { - int data[2] = { 1, 2 }; - ArrayClass() { py::print("ArrayClass()"); } - ~ArrayClass() { py::print("~ArrayClass()"); } - }; - - py::class_(sm, "ArrayClass") - .def(py::init<>()) - .def("numpy_view", [](py::object &obj) { - py::print("ArrayClass::numpy_view()"); - ArrayClass &a = obj.cast(); - return py::array_t({2}, {4}, a.data, obj); - } - ); - - sm.def("function_taking_uint64", [](uint64_t) { }); - - sm.def("isinstance_untyped", [](py::object yes, py::object no) { - return py::isinstance(yes) && !py::isinstance(no); - }); - - sm.def("isinstance_typed", [](py::object o) { - return py::isinstance>(o) && !py::isinstance>(o); - }); - - sm.def("default_constructors", []() { - return py::dict( - "array"_a=py::array(), - "array_t"_a=py::array_t(), - "array_t"_a=py::array_t() - ); - }); - - sm.def("converting_constructors", [](py::object o) { - return py::dict( - "array"_a=py::array(o), - "array_t"_a=py::array_t(o), - "array_t"_a=py::array_t(o) - ); - }); -}); diff --git a/stormpy/resources/pybind11/tests/test_numpy_array.py b/stormpy/resources/pybind11/tests/test_numpy_array.py deleted file mode 100755 index 1c218a10b..000000000 --- a/stormpy/resources/pybind11/tests/test_numpy_array.py +++ /dev/null @@ -1,273 +0,0 @@ -import pytest -import gc - -with pytest.suppress(ImportError): - import numpy as np - - -@pytest.fixture(scope='function') -def arr(): - return np.array([[1, 2, 3], [4, 5, 6]], '"].dtype == np.int32 - assert defaults["array_t"].dtype == np.float64 - - results = converting_constructors([1, 2, 3]) - for a in results.values(): - np.testing.assert_array_equal(a, [1, 2, 3]) - assert results["array"].dtype == np.int_ - assert results["array_t"].dtype == np.int32 - assert results["array_t"].dtype == np.float64 diff --git a/stormpy/resources/pybind11/tests/test_numpy_dtypes.cpp b/stormpy/resources/pybind11/tests/test_numpy_dtypes.cpp deleted file mode 100755 index 3894f6a30..000000000 --- a/stormpy/resources/pybind11/tests/test_numpy_dtypes.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/* - tests/test_numpy_dtypes.cpp -- Structured and compound NumPy dtypes - - Copyright (c) 2016 Ivan Smirnov - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include - -#ifdef __GNUC__ -#define PYBIND11_PACKED(cls) cls __attribute__((__packed__)) -#else -#define PYBIND11_PACKED(cls) __pragma(pack(push, 1)) cls __pragma(pack(pop)) -#endif - -namespace py = pybind11; - -struct SimpleStruct { - bool x; - uint32_t y; - float z; -}; - -std::ostream& operator<<(std::ostream& os, const SimpleStruct& v) { - return os << "s:" << v.x << "," << v.y << "," << v.z; -} - -PYBIND11_PACKED(struct PackedStruct { - bool x; - uint32_t y; - float z; -}); - -std::ostream& operator<<(std::ostream& os, const PackedStruct& v) { - return os << "p:" << v.x << "," << v.y << "," << v.z; -} - -PYBIND11_PACKED(struct NestedStruct { - SimpleStruct a; - PackedStruct b; -}); - -std::ostream& operator<<(std::ostream& os, const NestedStruct& v) { - return os << "n:a=" << v.a << ";b=" << v.b; -} - -struct PartialStruct { - bool x; - uint32_t y; - float z; - uint64_t dummy2; -}; - -struct PartialNestedStruct { - uint64_t dummy1; - PartialStruct a; - uint64_t dummy2; -}; - -struct UnboundStruct { }; - -struct StringStruct { - char a[3]; - std::array b; -}; - -PYBIND11_PACKED(struct StructWithUglyNames { - int8_t __x__; - uint64_t __y__; -}); - -enum class E1 : int64_t { A = -1, B = 1 }; -enum E2 : uint8_t { X = 1, Y = 2 }; - -PYBIND11_PACKED(struct EnumStruct { - E1 e1; - E2 e2; -}); - -std::ostream& operator<<(std::ostream& os, const StringStruct& v) { - os << "a='"; - for (size_t i = 0; i < 3 && v.a[i]; i++) os << v.a[i]; - os << "',b='"; - for (size_t i = 0; i < 3 && v.b[i]; i++) os << v.b[i]; - return os << "'"; -} - -std::ostream& operator<<(std::ostream& os, const EnumStruct& v) { - return os << "e1=" << (v.e1 == E1::A ? "A" : "B") << ",e2=" << (v.e2 == E2::X ? "X" : "Y"); -} - -template -py::array mkarray_via_buffer(size_t n) { - return py::array(py::buffer_info(nullptr, sizeof(T), - py::format_descriptor::format(), - 1, { n }, { sizeof(T) })); -} - -template -py::array_t create_recarray(size_t n) { - auto arr = mkarray_via_buffer(n); - auto req = arr.request(); - auto ptr = static_cast(req.ptr); - for (size_t i = 0; i < n; i++) { - ptr[i].x = i % 2 != 0; ptr[i].y = (uint32_t) i; ptr[i].z = (float) i * 1.5f; - } - return arr; -} - -std::string get_format_unbound() { - return py::format_descriptor::format(); -} - -py::array_t create_nested(size_t n) { - auto arr = mkarray_via_buffer(n); - auto req = arr.request(); - auto ptr = static_cast(req.ptr); - for (size_t i = 0; i < n; i++) { - ptr[i].a.x = i % 2 != 0; ptr[i].a.y = (uint32_t) i; ptr[i].a.z = (float) i * 1.5f; - ptr[i].b.x = (i + 1) % 2 != 0; ptr[i].b.y = (uint32_t) (i + 1); ptr[i].b.z = (float) (i + 1) * 1.5f; - } - return arr; -} - -py::array_t create_partial_nested(size_t n) { - auto arr = mkarray_via_buffer(n); - auto req = arr.request(); - auto ptr = static_cast(req.ptr); - for (size_t i = 0; i < n; i++) { - ptr[i].a.x = i % 2 != 0; ptr[i].a.y = (uint32_t) i; ptr[i].a.z = (float) i * 1.5f; - } - return arr; -} - -py::array_t create_string_array(bool non_empty) { - auto arr = mkarray_via_buffer(non_empty ? 4 : 0); - if (non_empty) { - auto req = arr.request(); - auto ptr = static_cast(req.ptr); - for (size_t i = 0; i < req.size * req.itemsize; i++) - static_cast(req.ptr)[i] = 0; - ptr[1].a[0] = 'a'; ptr[1].b[0] = 'a'; - ptr[2].a[0] = 'a'; ptr[2].b[0] = 'a'; - ptr[3].a[0] = 'a'; ptr[3].b[0] = 'a'; - - ptr[2].a[1] = 'b'; ptr[2].b[1] = 'b'; - ptr[3].a[1] = 'b'; ptr[3].b[1] = 'b'; - - ptr[3].a[2] = 'c'; ptr[3].b[2] = 'c'; - } - return arr; -} - -py::array_t create_enum_array(size_t n) { - auto arr = mkarray_via_buffer(n); - auto ptr = (EnumStruct *) arr.mutable_data(); - for (size_t i = 0; i < n; i++) { - ptr[i].e1 = static_cast(-1 + ((int) i % 2) * 2); - ptr[i].e2 = static_cast(1 + (i % 2)); - } - return arr; -} - -template -py::list print_recarray(py::array_t arr) { - const auto req = arr.request(); - const auto ptr = static_cast(req.ptr); - auto l = py::list(); - for (size_t i = 0; i < req.size; i++) { - std::stringstream ss; - ss << ptr[i]; - l.append(py::str(ss.str())); - } - return l; -} - -py::list print_format_descriptors() { - const auto fmts = { - py::format_descriptor::format(), - py::format_descriptor::format(), - py::format_descriptor::format(), - py::format_descriptor::format(), - py::format_descriptor::format(), - py::format_descriptor::format(), - py::format_descriptor::format() - }; - auto l = py::list(); - for (const auto &fmt : fmts) { - l.append(py::cast(fmt)); - } - return l; -} - -py::list print_dtypes() { - const auto dtypes = { - py::str(py::dtype::of()), - py::str(py::dtype::of()), - py::str(py::dtype::of()), - py::str(py::dtype::of()), - py::str(py::dtype::of()), - py::str(py::dtype::of()), - py::str(py::dtype::of()), - py::str(py::dtype::of()) - }; - auto l = py::list(); - for (const auto &s : dtypes) { - l.append(s); - } - return l; -} - -py::array_t test_array_ctors(int i) { - using arr_t = py::array_t; - - std::vector data { 1, 2, 3, 4, 5, 6 }; - std::vector shape { 3, 2 }; - std::vector strides { 8, 4 }; - - auto ptr = data.data(); - auto vptr = (void *) ptr; - auto dtype = py::dtype("int32"); - - py::buffer_info buf_ndim1(vptr, 4, "i", 6); - py::buffer_info buf_ndim1_null(nullptr, 4, "i", 6); - py::buffer_info buf_ndim2(vptr, 4, "i", 2, shape, strides); - py::buffer_info buf_ndim2_null(nullptr, 4, "i", 2, shape, strides); - - auto fill = [](py::array arr) { - auto req = arr.request(); - for (int i = 0; i < 6; i++) ((int32_t *) req.ptr)[i] = i + 1; - return arr; - }; - - switch (i) { - // shape: (3, 2) - case 10: return arr_t(shape, strides, ptr); - case 11: return py::array(shape, strides, ptr); - case 12: return py::array(dtype, shape, strides, vptr); - case 13: return arr_t(shape, ptr); - case 14: return py::array(shape, ptr); - case 15: return py::array(dtype, shape, vptr); - case 16: return arr_t(buf_ndim2); - case 17: return py::array(buf_ndim2); - // shape: (3, 2) - post-fill - case 20: return fill(arr_t(shape, strides)); - case 21: return py::array(shape, strides, ptr); // can't have nullptr due to templated ctor - case 22: return fill(py::array(dtype, shape, strides)); - case 23: return fill(arr_t(shape)); - case 24: return py::array(shape, ptr); // can't have nullptr due to templated ctor - case 25: return fill(py::array(dtype, shape)); - case 26: return fill(arr_t(buf_ndim2_null)); - case 27: return fill(py::array(buf_ndim2_null)); - // shape: (6, ) - case 30: return arr_t(6, ptr); - case 31: return py::array(6, ptr); - case 32: return py::array(dtype, 6, vptr); - case 33: return arr_t(buf_ndim1); - case 34: return py::array(buf_ndim1); - // shape: (6, ) - case 40: return fill(arr_t(6)); - case 41: return py::array(6, ptr); // can't have nullptr due to templated ctor - case 42: return fill(py::array(dtype, 6)); - case 43: return fill(arr_t(buf_ndim1_null)); - case 44: return fill(py::array(buf_ndim1_null)); - } - return arr_t(); -} - -py::list test_dtype_ctors() { - py::list list; - list.append(py::dtype("int32")); - list.append(py::dtype(std::string("float64"))); - list.append(py::dtype::from_args(py::str("bool"))); - py::list names, offsets, formats; - py::dict dict; - names.append(py::str("a")); names.append(py::str("b")); dict["names"] = names; - offsets.append(py::int_(1)); offsets.append(py::int_(10)); dict["offsets"] = offsets; - formats.append(py::dtype("int32")); formats.append(py::dtype("float64")); dict["formats"] = formats; - dict["itemsize"] = py::int_(20); - list.append(py::dtype::from_args(dict)); - list.append(py::dtype(names, formats, offsets, 20)); - list.append(py::dtype(py::buffer_info((void *) 0, sizeof(unsigned int), "I", 1))); - list.append(py::dtype(py::buffer_info((void *) 0, 0, "T{i:a:f:b:}", 1))); - return list; -} - -struct TrailingPaddingStruct { - int32_t a; - char b; -}; - -py::dtype trailing_padding_dtype() { - return py::dtype::of(); -} - -py::dtype buffer_to_dtype(py::buffer& buf) { - return py::dtype(buf.request()); -} - -py::list test_dtype_methods() { - py::list list; - auto dt1 = py::dtype::of(); - auto dt2 = py::dtype::of(); - list.append(dt1); list.append(dt2); - list.append(py::bool_(dt1.has_fields())); list.append(py::bool_(dt2.has_fields())); - list.append(py::int_(dt1.itemsize())); list.append(py::int_(dt2.itemsize())); - return list; -} - -test_initializer numpy_dtypes([](py::module &m) { - try { - py::module::import("numpy"); - } catch (...) { - return; - } - - // typeinfo may be registered before the dtype descriptor for scalar casts to work... - py::class_(m, "SimpleStruct"); - - PYBIND11_NUMPY_DTYPE(SimpleStruct, x, y, z); - PYBIND11_NUMPY_DTYPE(PackedStruct, x, y, z); - PYBIND11_NUMPY_DTYPE(NestedStruct, a, b); - PYBIND11_NUMPY_DTYPE(PartialStruct, x, y, z); - PYBIND11_NUMPY_DTYPE(PartialNestedStruct, a); - PYBIND11_NUMPY_DTYPE(StringStruct, a, b); - PYBIND11_NUMPY_DTYPE(EnumStruct, e1, e2); - PYBIND11_NUMPY_DTYPE(TrailingPaddingStruct, a, b); - - // ... or after - py::class_(m, "PackedStruct"); - - PYBIND11_NUMPY_DTYPE_EX(StructWithUglyNames, __x__, "x", __y__, "y"); - - m.def("create_rec_simple", &create_recarray); - m.def("create_rec_packed", &create_recarray); - m.def("create_rec_nested", &create_nested); - m.def("create_rec_partial", &create_recarray); - m.def("create_rec_partial_nested", &create_partial_nested); - m.def("print_format_descriptors", &print_format_descriptors); - m.def("print_rec_simple", &print_recarray); - m.def("print_rec_packed", &print_recarray); - m.def("print_rec_nested", &print_recarray); - m.def("print_dtypes", &print_dtypes); - m.def("get_format_unbound", &get_format_unbound); - m.def("create_string_array", &create_string_array); - m.def("print_string_array", &print_recarray); - m.def("create_enum_array", &create_enum_array); - m.def("print_enum_array", &print_recarray); - m.def("test_array_ctors", &test_array_ctors); - m.def("test_dtype_ctors", &test_dtype_ctors); - m.def("test_dtype_methods", &test_dtype_methods); - m.def("trailing_padding_dtype", &trailing_padding_dtype); - m.def("buffer_to_dtype", &buffer_to_dtype); - m.def("f_simple", [](SimpleStruct s) { return s.y * 10; }); - m.def("f_packed", [](PackedStruct s) { return s.y * 10; }); - m.def("f_nested", [](NestedStruct s) { return s.a.y * 10; }); - m.def("register_dtype", []() { PYBIND11_NUMPY_DTYPE(SimpleStruct, x, y, z); }); -}); - -#undef PYBIND11_PACKED diff --git a/stormpy/resources/pybind11/tests/test_numpy_dtypes.py b/stormpy/resources/pybind11/tests/test_numpy_dtypes.py deleted file mode 100755 index 48b2ff6bc..000000000 --- a/stormpy/resources/pybind11/tests/test_numpy_dtypes.py +++ /dev/null @@ -1,219 +0,0 @@ -import re -import pytest - -with pytest.suppress(ImportError): - import numpy as np - - -@pytest.fixture(scope='module') -def simple_dtype(): - return np.dtype({'names': ['x', 'y', 'z'], - 'formats': ['?', 'u4', 'f4'], - 'offsets': [0, 4, 8]}) - - -@pytest.fixture(scope='module') -def packed_dtype(): - return np.dtype([('x', '?'), ('y', 'u4'), ('z', 'f4')]) - - -def assert_equal(actual, expected_data, expected_dtype): - np.testing.assert_equal(actual, np.array(expected_data, dtype=expected_dtype)) - - -@pytest.requires_numpy -def test_format_descriptors(): - from pybind11_tests import get_format_unbound, print_format_descriptors - - with pytest.raises(RuntimeError) as excinfo: - get_format_unbound() - assert re.match('^NumPy type info missing for .*UnboundStruct.*$', str(excinfo.value)) - - assert print_format_descriptors() == [ - "T{?:x:3xI:y:f:z:}", - "T{?:x:=I:y:=f:z:}", - "T{T{?:x:3xI:y:f:z:}:a:T{?:x:=I:y:=f:z:}:b:}", - "T{?:x:3xI:y:f:z:12x}", - "T{8xT{?:x:3xI:y:f:z:12x}:a:8x}", - "T{3s:a:3s:b:}", - 'T{q:e1:B:e2:}' - ] - - -@pytest.requires_numpy -def test_dtype(simple_dtype): - from pybind11_tests import print_dtypes, test_dtype_ctors, test_dtype_methods, trailing_padding_dtype, buffer_to_dtype - - assert print_dtypes() == [ - "{'names':['x','y','z'], 'formats':['?',' simple_dtype.itemsize - assert_equal(arr, elements, simple_dtype) - assert_equal(arr, elements, packed_dtype) - - arr = create_rec_partial_nested(3) - assert str(arr.dtype) == "{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?',' partial_dtype.itemsize - np.testing.assert_equal(arr['a'], create_rec_partial(3)) - - -@pytest.requires_numpy -def test_array_constructors(): - from pybind11_tests import test_array_ctors - - data = np.arange(1, 7, dtype='int32') - for i in range(8): - np.testing.assert_array_equal(test_array_ctors(10 + i), data.reshape((3, 2))) - np.testing.assert_array_equal(test_array_ctors(20 + i), data.reshape((3, 2))) - for i in range(5): - np.testing.assert_array_equal(test_array_ctors(30 + i), data) - np.testing.assert_array_equal(test_array_ctors(40 + i), data) - - -@pytest.requires_numpy -def test_string_array(): - from pybind11_tests import create_string_array, print_string_array - - arr = create_string_array(True) - assert str(arr.dtype) == "[('a', 'S3'), ('b', 'S3')]" - assert print_string_array(arr) == [ - "a='',b=''", - "a='a',b='a'", - "a='ab',b='ab'", - "a='abc',b='abc'" - ] - dtype = arr.dtype - assert arr['a'].tolist() == [b'', b'a', b'ab', b'abc'] - assert arr['b'].tolist() == [b'', b'a', b'ab', b'abc'] - arr = create_string_array(False) - assert dtype == arr.dtype - - -@pytest.requires_numpy -def test_enum_array(): - from pybind11_tests import create_enum_array, print_enum_array - - arr = create_enum_array(3) - dtype = arr.dtype - assert dtype == np.dtype([('e1', ' numpy.ndarray[NestedStruct]" - - -@pytest.requires_numpy -def test_scalar_conversion(): - from pybind11_tests import (create_rec_simple, f_simple, - create_rec_packed, f_packed, - create_rec_nested, f_nested, - create_enum_array) - - n = 3 - arrays = [create_rec_simple(n), create_rec_packed(n), - create_rec_nested(n), create_enum_array(n)] - funcs = [f_simple, f_packed, f_nested] - - for i, func in enumerate(funcs): - for j, arr in enumerate(arrays): - if i == j and i < 2: - assert [func(arr[k]) for k in range(n)] == [k * 10 for k in range(n)] - else: - with pytest.raises(TypeError) as excinfo: - func(arr[0]) - assert 'incompatible function arguments' in str(excinfo.value) - - -@pytest.requires_numpy -def test_register_dtype(): - from pybind11_tests import register_dtype - - with pytest.raises(RuntimeError) as excinfo: - register_dtype() - assert 'dtype is already registered' in str(excinfo.value) diff --git a/stormpy/resources/pybind11/tests/test_numpy_vectorize.cpp b/stormpy/resources/pybind11/tests/test_numpy_vectorize.cpp deleted file mode 100755 index 6d94db2a1..000000000 --- a/stormpy/resources/pybind11/tests/test_numpy_vectorize.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - tests/test_numpy_vectorize.cpp -- auto-vectorize functions over NumPy array - arguments - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include - -double my_func(int x, float y, double z) { - py::print("my_func(x:int={}, y:float={:.0f}, z:float={:.0f})"_s.format(x, y, z)); - return (float) x*y*z; -} - -std::complex my_func3(std::complex c) { - return c * std::complex(2.f); -} - -test_initializer numpy_vectorize([](py::module &m) { - // Vectorize all arguments of a function (though non-vector arguments are also allowed) - m.def("vectorized_func", py::vectorize(my_func)); - - // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the vectorization) - m.def("vectorized_func2", - [](py::array_t x, py::array_t y, float z) { - return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(x, y); - } - ); - - // Vectorize a complex-valued function - m.def("vectorized_func3", py::vectorize(my_func3)); - - /// Numpy function which only accepts specific data types - m.def("selective_func", [](py::array_t) { return "Int branch taken."; }); - m.def("selective_func", [](py::array_t) { return "Float branch taken."; }); - m.def("selective_func", [](py::array_t, py::array::c_style>) { return "Complex float branch taken."; }); -}); diff --git a/stormpy/resources/pybind11/tests/test_numpy_vectorize.py b/stormpy/resources/pybind11/tests/test_numpy_vectorize.py deleted file mode 100755 index 73da819a4..000000000 --- a/stormpy/resources/pybind11/tests/test_numpy_vectorize.py +++ /dev/null @@ -1,74 +0,0 @@ -import pytest - -with pytest.suppress(ImportError): - import numpy as np - - -@pytest.requires_numpy -def test_vectorize(capture): - from pybind11_tests import vectorized_func, vectorized_func2, vectorized_func3 - - assert np.isclose(vectorized_func3(np.array(3 + 7j)), [6 + 14j]) - - for f in [vectorized_func, vectorized_func2]: - with capture: - assert np.isclose(f(1, 2, 3), 6) - assert capture == "my_func(x:int=1, y:float=2, z:float=3)" - with capture: - assert np.isclose(f(np.array(1), np.array(2), 3), 6) - assert capture == "my_func(x:int=1, y:float=2, z:float=3)" - with capture: - assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36]) - assert capture == """ - my_func(x:int=1, y:float=2, z:float=3) - my_func(x:int=3, y:float=4, z:float=3) - """ - with capture: - a, b, c = np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3 - assert np.allclose(f(a, b, c), a * b * c) - assert capture == """ - my_func(x:int=1, y:float=2, z:float=3) - my_func(x:int=3, y:float=4, z:float=3) - my_func(x:int=5, y:float=6, z:float=3) - my_func(x:int=7, y:float=8, z:float=3) - my_func(x:int=9, y:float=10, z:float=3) - my_func(x:int=11, y:float=12, z:float=3) - """ - with capture: - a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2 - assert np.allclose(f(a, b, c), a * b * c) - assert capture == """ - my_func(x:int=1, y:float=2, z:float=2) - my_func(x:int=2, y:float=3, z:float=2) - my_func(x:int=3, y:float=4, z:float=2) - my_func(x:int=4, y:float=2, z:float=2) - my_func(x:int=5, y:float=3, z:float=2) - my_func(x:int=6, y:float=4, z:float=2) - """ - with capture: - a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2 - assert np.allclose(f(a, b, c), a * b * c) - assert capture == """ - my_func(x:int=1, y:float=2, z:float=2) - my_func(x:int=2, y:float=2, z:float=2) - my_func(x:int=3, y:float=2, z:float=2) - my_func(x:int=4, y:float=3, z:float=2) - my_func(x:int=5, y:float=3, z:float=2) - my_func(x:int=6, y:float=3, z:float=2) - """ - - -@pytest.requires_numpy -def test_type_selection(): - from pybind11_tests import selective_func - - assert selective_func(np.array([1], dtype=np.int32)) == "Int branch taken." - assert selective_func(np.array([1.0], dtype=np.float32)) == "Float branch taken." - assert selective_func(np.array([1.0j], dtype=np.complex64)) == "Complex float branch taken." - - -@pytest.requires_numpy -def test_docs(doc): - from pybind11_tests import vectorized_func - - assert doc(vectorized_func) == "vectorized_func(arg0: numpy.ndarray[int], arg1: numpy.ndarray[float], arg2: numpy.ndarray[float]) -> object" diff --git a/stormpy/resources/pybind11/tests/test_opaque_types.cpp b/stormpy/resources/pybind11/tests/test_opaque_types.cpp deleted file mode 100755 index 54f4dc7a5..000000000 --- a/stormpy/resources/pybind11/tests/test_opaque_types.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - tests/test_opaque_types.cpp -- opaque types, passing void pointers - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include -#include - -typedef std::vector StringList; - -class ClassWithSTLVecProperty { -public: - StringList stringList; -}; - -/* IMPORTANT: Disable internal pybind11 translation mechanisms for STL data structures */ -PYBIND11_MAKE_OPAQUE(StringList); - -test_initializer opaque_types([](py::module &m) { - py::class_(m, "StringList") - .def(py::init<>()) - .def("pop_back", &StringList::pop_back) - /* There are multiple versions of push_back(), etc. Select the right ones. */ - .def("push_back", (void (StringList::*)(const std::string &)) &StringList::push_back) - .def("back", (std::string &(StringList::*)()) &StringList::back) - .def("__len__", [](const StringList &v) { return v.size(); }) - .def("__iter__", [](StringList &v) { - return py::make_iterator(v.begin(), v.end()); - }, py::keep_alive<0, 1>()); - - py::class_(m, "ClassWithSTLVecProperty") - .def(py::init<>()) - .def_readwrite("stringList", &ClassWithSTLVecProperty::stringList); - - m.def("print_opaque_list", [](const StringList &l) { - std::string ret = "Opaque list: ["; - bool first = true; - for (auto entry : l) { - if (!first) - ret += ", "; - ret += entry; - first = false; - } - return ret + "]"; - }); - - m.def("return_void_ptr", []() { return (void *) 0x1234; }); - m.def("get_void_ptr_value", [](void *ptr) { return reinterpret_cast(ptr); }); - m.def("return_null_str", []() { return (char *) nullptr; }); - m.def("get_null_str_value", [](char *ptr) { return reinterpret_cast(ptr); }); - - m.def("return_unique_ptr", []() -> std::unique_ptr { - StringList *result = new StringList(); - result->push_back("some value"); - return std::unique_ptr(result); - }); -}); diff --git a/stormpy/resources/pybind11/tests/test_opaque_types.py b/stormpy/resources/pybind11/tests/test_opaque_types.py deleted file mode 100755 index 8a6a4c3f3..000000000 --- a/stormpy/resources/pybind11/tests/test_opaque_types.py +++ /dev/null @@ -1,49 +0,0 @@ -import pytest - - -def test_string_list(): - from pybind11_tests import StringList, ClassWithSTLVecProperty, print_opaque_list - - l = StringList() - l.push_back("Element 1") - l.push_back("Element 2") - assert print_opaque_list(l) == "Opaque list: [Element 1, Element 2]" - assert l.back() == "Element 2" - - for i, k in enumerate(l, start=1): - assert k == "Element {}".format(i) - l.pop_back() - assert print_opaque_list(l) == "Opaque list: [Element 1]" - - cvp = ClassWithSTLVecProperty() - assert print_opaque_list(cvp.stringList) == "Opaque list: []" - - cvp.stringList = l - cvp.stringList.push_back("Element 3") - assert print_opaque_list(cvp.stringList) == "Opaque list: [Element 1, Element 3]" - - -def test_pointers(msg): - from pybind11_tests import (return_void_ptr, get_void_ptr_value, ExampleMandA, - print_opaque_list, return_null_str, get_null_str_value, - return_unique_ptr, ConstructorStats) - - assert get_void_ptr_value(return_void_ptr()) == 0x1234 - assert get_void_ptr_value(ExampleMandA()) # Should also work for other C++ types - assert ConstructorStats.get(ExampleMandA).alive() == 0 - - with pytest.raises(TypeError) as excinfo: - get_void_ptr_value([1, 2, 3]) # This should not work - assert msg(excinfo.value) == """ - get_void_ptr_value(): incompatible function arguments. The following argument types are supported: - 1. (arg0: capsule) -> int - - Invoked with: [1, 2, 3] - """ - - assert return_null_str() is None - assert get_null_str_value(return_null_str()) is not None - - ptr = return_unique_ptr() - assert "StringList" in repr(ptr) - assert print_opaque_list(ptr) == "Opaque list: [some value]" diff --git a/stormpy/resources/pybind11/tests/test_operator_overloading.cpp b/stormpy/resources/pybind11/tests/test_operator_overloading.cpp deleted file mode 100755 index 93aea8010..000000000 --- a/stormpy/resources/pybind11/tests/test_operator_overloading.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - tests/test_operator_overloading.cpp -- operator overloading - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" -#include - -class Vector2 { -public: - Vector2(float x, float y) : x(x), y(y) { print_created(this, toString()); } - Vector2(const Vector2 &v) : x(v.x), y(v.y) { print_copy_created(this); } - Vector2(Vector2 &&v) : x(v.x), y(v.y) { print_move_created(this); v.x = v.y = 0; } - ~Vector2() { print_destroyed(this); } - - std::string toString() const { - return "[" + std::to_string(x) + ", " + std::to_string(y) + "]"; - } - - void operator=(const Vector2 &v) { - print_copy_assigned(this); - x = v.x; - y = v.y; - } - - void operator=(Vector2 &&v) { - print_move_assigned(this); - x = v.x; y = v.y; v.x = v.y = 0; - } - - Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); } - Vector2 operator-(const Vector2 &v) const { return Vector2(x - v.x, y - v.y); } - Vector2 operator-(float value) const { return Vector2(x - value, y - value); } - Vector2 operator+(float value) const { return Vector2(x + value, y + value); } - Vector2 operator*(float value) const { return Vector2(x * value, y * value); } - Vector2 operator/(float value) const { return Vector2(x / value, y / value); } - Vector2& operator+=(const Vector2 &v) { x += v.x; y += v.y; return *this; } - Vector2& operator-=(const Vector2 &v) { x -= v.x; y -= v.y; return *this; } - Vector2& operator*=(float v) { x *= v; y *= v; return *this; } - Vector2& operator/=(float v) { x /= v; y /= v; return *this; } - - friend Vector2 operator+(float f, const Vector2 &v) { return Vector2(f + v.x, f + v.y); } - friend Vector2 operator-(float f, const Vector2 &v) { return Vector2(f - v.x, f - v.y); } - friend Vector2 operator*(float f, const Vector2 &v) { return Vector2(f * v.x, f * v.y); } - friend Vector2 operator/(float f, const Vector2 &v) { return Vector2(f / v.x, f / v.y); } -private: - float x, y; -}; - -test_initializer operator_overloading([](py::module &m) { - py::class_(m, "Vector2") - .def(py::init()) - .def(py::self + py::self) - .def(py::self + float()) - .def(py::self - py::self) - .def(py::self - float()) - .def(py::self * float()) - .def(py::self / float()) - .def(py::self += py::self) - .def(py::self -= py::self) - .def(py::self *= float()) - .def(py::self /= float()) - .def(float() + py::self) - .def(float() - py::self) - .def(float() * py::self) - .def(float() / py::self) - .def("__str__", &Vector2::toString) - ; - - m.attr("Vector") = m.attr("Vector2"); -}); diff --git a/stormpy/resources/pybind11/tests/test_operator_overloading.py b/stormpy/resources/pybind11/tests/test_operator_overloading.py deleted file mode 100755 index e0d42391e..000000000 --- a/stormpy/resources/pybind11/tests/test_operator_overloading.py +++ /dev/null @@ -1,41 +0,0 @@ - -def test_operator_overloading(): - from pybind11_tests import Vector2, Vector, ConstructorStats - - v1 = Vector2(1, 2) - v2 = Vector(3, -1) - assert str(v1) == "[1.000000, 2.000000]" - assert str(v2) == "[3.000000, -1.000000]" - - assert str(v1 + v2) == "[4.000000, 1.000000]" - assert str(v1 - v2) == "[-2.000000, 3.000000]" - assert str(v1 - 8) == "[-7.000000, -6.000000]" - assert str(v1 + 8) == "[9.000000, 10.000000]" - assert str(v1 * 8) == "[8.000000, 16.000000]" - assert str(v1 / 8) == "[0.125000, 0.250000]" - assert str(8 - v1) == "[7.000000, 6.000000]" - assert str(8 + v1) == "[9.000000, 10.000000]" - assert str(8 * v1) == "[8.000000, 16.000000]" - assert str(8 / v1) == "[8.000000, 4.000000]" - - v1 += v2 - v1 *= 2 - assert str(v1) == "[8.000000, 2.000000]" - - cstats = ConstructorStats.get(Vector2) - assert cstats.alive() == 2 - del v1 - assert cstats.alive() == 1 - del v2 - assert cstats.alive() == 0 - assert cstats.values() == ['[1.000000, 2.000000]', '[3.000000, -1.000000]', - '[4.000000, 1.000000]', '[-2.000000, 3.000000]', - '[-7.000000, -6.000000]', '[9.000000, 10.000000]', - '[8.000000, 16.000000]', '[0.125000, 0.250000]', - '[7.000000, 6.000000]', '[9.000000, 10.000000]', - '[8.000000, 16.000000]', '[8.000000, 4.000000]'] - assert cstats.default_constructions == 0 - assert cstats.copy_constructions == 0 - assert cstats.move_constructions >= 10 - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 diff --git a/stormpy/resources/pybind11/tests/test_pickling.cpp b/stormpy/resources/pybind11/tests/test_pickling.cpp deleted file mode 100755 index 3941dc593..000000000 --- a/stormpy/resources/pybind11/tests/test_pickling.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - tests/test_pickling.cpp -- pickle support - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -class Pickleable { -public: - Pickleable(const std::string &value) : m_value(value) { } - const std::string &value() const { return m_value; } - - void setExtra1(int extra1) { m_extra1 = extra1; } - void setExtra2(int extra2) { m_extra2 = extra2; } - int extra1() const { return m_extra1; } - int extra2() const { return m_extra2; } -private: - std::string m_value; - int m_extra1 = 0; - int m_extra2 = 0; -}; - -class PickleableWithDict { -public: - PickleableWithDict(const std::string &value) : value(value) { } - - std::string value; - int extra; -}; - -test_initializer pickling([](py::module &m) { - py::class_(m, "Pickleable") - .def(py::init()) - .def("value", &Pickleable::value) - .def("extra1", &Pickleable::extra1) - .def("extra2", &Pickleable::extra2) - .def("setExtra1", &Pickleable::setExtra1) - .def("setExtra2", &Pickleable::setExtra2) - // For details on the methods below, refer to - // http://docs.python.org/3/library/pickle.html#pickling-class-instances - .def("__getstate__", [](const Pickleable &p) { - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(p.value(), p.extra1(), p.extra2()); - }) - .def("__setstate__", [](Pickleable &p, py::tuple t) { - if (t.size() != 3) - throw std::runtime_error("Invalid state!"); - /* Invoke the constructor (need to use in-place version) */ - new (&p) Pickleable(t[0].cast()); - - /* Assign any additional state */ - p.setExtra1(t[1].cast()); - p.setExtra2(t[2].cast()); - }); - - py::class_(m, "PickleableWithDict", py::dynamic_attr()) - .def(py::init()) - .def_readwrite("value", &PickleableWithDict::value) - .def_readwrite("extra", &PickleableWithDict::extra) - .def("__getstate__", [](py::object self) { - /* Also include __dict__ in state */ - return py::make_tuple(self.attr("value"), self.attr("extra"), self.attr("__dict__")); - }) - .def("__setstate__", [](py::object self, py::tuple t) { - if (t.size() != 3) - throw std::runtime_error("Invalid state!"); - /* Cast and construct */ - auto& p = self.cast(); - new (&p) Pickleable(t[0].cast()); - - /* Assign C++ state */ - p.extra = t[1].cast(); - - /* Assign Python state */ - self.attr("__dict__") = t[2]; - }); -}); diff --git a/stormpy/resources/pybind11/tests/test_pickling.py b/stormpy/resources/pybind11/tests/test_pickling.py deleted file mode 100755 index 5e62e1fcc..000000000 --- a/stormpy/resources/pybind11/tests/test_pickling.py +++ /dev/null @@ -1,32 +0,0 @@ -try: - import cPickle as pickle # Use cPickle on Python 2.7 -except ImportError: - import pickle - - -def test_roundtrip(): - from pybind11_tests import Pickleable - - p = Pickleable("test_value") - p.setExtra1(15) - p.setExtra2(48) - - data = pickle.dumps(p, 2) # Must use pickle protocol >= 2 - p2 = pickle.loads(data) - assert p2.value() == p.value() - assert p2.extra1() == p.extra1() - assert p2.extra2() == p.extra2() - - -def test_roundtrip_with_dict(): - from pybind11_tests import PickleableWithDict - - p = PickleableWithDict("test_value") - p.extra = 15 - p.dynamic = "Attribute" - - data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL) - p2 = pickle.loads(data) - assert p2.value == p.value - assert p2.extra == p.extra - assert p2.dynamic == p.dynamic diff --git a/stormpy/resources/pybind11/tests/test_python_types.cpp b/stormpy/resources/pybind11/tests/test_python_types.cpp deleted file mode 100755 index 30fa3c795..000000000 --- a/stormpy/resources/pybind11/tests/test_python_types.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* - tests/test_python_types.cpp -- singleton design pattern, static functions and - variables, passing and interacting with Python types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" -#include - -#ifdef _WIN32 -# include -# include -#endif - -class ExamplePythonTypes { -public: - static ExamplePythonTypes *new_instance() { - auto *ptr = new ExamplePythonTypes(); - print_created(ptr, "via new_instance"); - return ptr; - } - ~ExamplePythonTypes() { print_destroyed(this); } - - /* Create and return a Python dictionary */ - py::dict get_dict() { - py::dict dict; - dict[py::str("key")] = py::str("value"); - return dict; - } - - /* Create and return a Python set */ - py::set get_set() { - py::set set; - set.add(py::str("key1")); - set.add(py::str("key2")); - return set; - } - - /* Create and return a C++ dictionary */ - std::map get_dict_2() { - std::map result; - result["key"] = "value"; - return result; - } - - /* Create and return a C++ set */ - std::set get_set_2() { - std::set result; - result.insert("key1"); - result.insert("key2"); - return result; - } - - /* Create, manipulate, and return a Python list */ - py::list get_list() { - py::list list; - list.append(py::str("value")); - py::print("Entry at position 0:", list[0]); - list[0] = py::str("overwritten"); - return list; - } - - /* C++ STL data types are automatically casted */ - std::vector get_list_2() { - std::vector list; - list.push_back(L"value"); - return list; - } - - /* C++ STL data types are automatically casted */ - std::array get_array() { - return std::array {{ "array entry 1" , "array entry 2"}}; - } - - /* Easily iterate over a dictionary using a C++11 range-based for loop */ - void print_dict(py::dict dict) { - for (auto item : dict) - py::print("key: {}, value={}"_s.format(item.first, item.second)); - } - - /* Easily iterate over a set using a C++11 range-based for loop */ - void print_set(py::set set) { - for (auto item : set) - py::print("key:", item); - } - - /* Easily iterate over a list using a C++11 range-based for loop */ - void print_list(py::list list) { - int index = 0; - for (auto item : list) - py::print("list item {}: {}"_s.format(index++, item)); - } - - /* STL data types (such as maps) are automatically casted from Python */ - void print_dict_2(const std::map &dict) { - for (auto item : dict) - py::print("key: {}, value={}"_s.format(item.first, item.second)); - } - - /* STL data types (such as sets) are automatically casted from Python */ - void print_set_2(const std::set &set) { - for (auto item : set) - py::print("key:", item); - } - - /* STL data types (such as vectors) are automatically casted from Python */ - void print_list_2(std::vector &list) { - int index = 0; - for (auto item : list) - py::print("list item {}: {}"_s.format(index++, item)); - } - - /* pybind automatically translates between C++11 and Python tuples */ - std::pair pair_passthrough(std::pair input) { - return std::make_pair(input.second, input.first); - } - - /* pybind automatically translates between C++11 and Python tuples */ - std::tuple tuple_passthrough(std::tuple input) { - return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input)); - } - - /* STL data types (such as arrays) are automatically casted from Python */ - void print_array(std::array &array) { - int index = 0; - for (auto item : array) - py::print("array item {}: {}"_s.format(index++, item)); - } - - void throw_exception() { - throw std::runtime_error("This exception was intentionally thrown."); - } - - py::bytes get_bytes_from_string() { - return (py::bytes) std::string("foo"); - } - - py::bytes get_bytes_from_str() { - return (py::bytes) py::str("bar", 3); - } - - py::str get_str_from_string() { - return (py::str) std::string("baz"); - } - - py::str get_str_from_bytes() { - return (py::str) py::bytes("boo", 3); - } - - void test_print(const py::object& obj) { - py::print(py::str(obj)); - py::print(py::repr(obj)); - } - - static int value; - static const int value2; -}; - -int ExamplePythonTypes::value = 0; -const int ExamplePythonTypes::value2 = 5; - -struct MoveOutContainer { - struct Value { int value; }; - - std::list move_list() const { return {{0}, {1}, {2}}; } -}; - - -test_initializer python_types([](py::module &m) { - /* No constructor is explicitly defined below. An exception is raised when - trying to construct it directly from Python */ - py::class_(m, "ExamplePythonTypes", "Example 2 documentation") - .def("get_dict", &ExamplePythonTypes::get_dict, "Return a Python dictionary") - .def("get_dict_2", &ExamplePythonTypes::get_dict_2, "Return a C++ dictionary") - .def("get_list", &ExamplePythonTypes::get_list, "Return a Python list") - .def("get_list_2", &ExamplePythonTypes::get_list_2, "Return a C++ list") - .def("get_set", &ExamplePythonTypes::get_set, "Return a Python set") - .def("get_set2", &ExamplePythonTypes::get_set_2, "Return a C++ set") - .def("get_array", &ExamplePythonTypes::get_array, "Return a C++ array") - .def("print_dict", &ExamplePythonTypes::print_dict, "Print entries of a Python dictionary") - .def("print_dict_2", &ExamplePythonTypes::print_dict_2, "Print entries of a C++ dictionary") - .def("print_set", &ExamplePythonTypes::print_set, "Print entries of a Python set") - .def("print_set_2", &ExamplePythonTypes::print_set_2, "Print entries of a C++ set") - .def("print_list", &ExamplePythonTypes::print_list, "Print entries of a Python list") - .def("print_list_2", &ExamplePythonTypes::print_list_2, "Print entries of a C++ list") - .def("print_array", &ExamplePythonTypes::print_array, "Print entries of a C++ array") - .def("pair_passthrough", &ExamplePythonTypes::pair_passthrough, "Return a pair in reversed order") - .def("tuple_passthrough", &ExamplePythonTypes::tuple_passthrough, "Return a triple in reversed order") - .def("throw_exception", &ExamplePythonTypes::throw_exception, "Throw an exception") - .def("get_bytes_from_string", &ExamplePythonTypes::get_bytes_from_string, "py::bytes from std::string") - .def("get_bytes_from_str", &ExamplePythonTypes::get_bytes_from_str, "py::bytes from py::str") - .def("get_str_from_string", &ExamplePythonTypes::get_str_from_string, "py::str from std::string") - .def("get_str_from_bytes", &ExamplePythonTypes::get_str_from_bytes, "py::str from py::bytes") - .def("test_print", &ExamplePythonTypes::test_print, "test the print function") - .def_static("new_instance", &ExamplePythonTypes::new_instance, "Return an instance") - .def_readwrite_static("value", &ExamplePythonTypes::value, "Static value member") - .def_readonly_static("value2", &ExamplePythonTypes::value2, "Static value member (readonly)") - ; - - m.def("test_print_function", []() { - py::print("Hello, World!"); - py::print(1, 2.0, "three", true, std::string("-- multiple args")); - auto args = py::make_tuple("and", "a", "custom", "separator"); - py::print("*args", *args, "sep"_a="-"); - py::print("no new line here", "end"_a=" -- "); - py::print("next print"); - - auto py_stderr = py::module::import("sys").attr("stderr"); - py::print("this goes to stderr", "file"_a=py_stderr); - - py::print("flush", "flush"_a=true); - - py::print("{a} + {b} = {c}"_s.format("a"_a="py::print", "b"_a="str.format", "c"_a="this")); - }); - - m.def("test_str_format", []() { - auto s1 = "{} + {} = {}"_s.format(1, 2, 3); - auto s2 = "{a} + {b} = {c}"_s.format("a"_a=1, "b"_a=2, "c"_a=3); - return py::make_tuple(s1, s2); - }); - - m.def("test_dict_keyword_constructor", []() { - auto d1 = py::dict("x"_a=1, "y"_a=2); - auto d2 = py::dict("z"_a=3, **d1); - return d2; - }); - - m.def("test_accessor_api", [](py::object o) { - auto d = py::dict(); - - d["basic_attr"] = o.attr("basic_attr"); - - auto l = py::list(); - for (const auto &item : o.attr("begin_end")) { - l.append(item); - } - d["begin_end"] = l; - - d["operator[object]"] = o.attr("d")["operator[object]"_s]; - d["operator[char *]"] = o.attr("d")["operator[char *]"]; - - d["attr(object)"] = o.attr("sub").attr("attr_obj"); - d["attr(char *)"] = o.attr("sub").attr("attr_char"); - try { - o.attr("sub").attr("missing").ptr(); - } catch (const py::error_already_set &) { - d["missing_attr_ptr"] = "raised"_s; - } - try { - o.attr("missing").attr("doesn't matter"); - } catch (const py::error_already_set &) { - d["missing_attr_chain"] = "raised"_s; - } - - d["is_none"] = py::cast(o.attr("basic_attr").is_none()); - - d["operator()"] = o.attr("func")(1); - d["operator*"] = o.attr("func")(*o.attr("begin_end")); - - return d; - }); - - m.def("test_tuple_accessor", [](py::tuple existing_t) { - try { - existing_t[0] = py::cast(1); - } catch (const py::error_already_set &) { - // --> Python system error - // Only new tuples (refcount == 1) are mutable - auto new_t = py::tuple(3); - for (size_t i = 0; i < new_t.size(); ++i) { - new_t[i] = py::cast(i); - } - return new_t; - } - return py::tuple(); - }); - - m.def("test_accessor_assignment", []() { - auto l = py::list(1); - l[0] = py::cast(0); - - auto d = py::dict(); - d["get"] = l[0]; - auto var = l[0]; - d["deferred_get"] = var; - l[0] = py::cast(1); - d["set"] = l[0]; - var = py::cast(99); // this assignment should not overwrite l[0] - d["deferred_set"] = l[0]; - d["var"] = var; - - return d; - }); - - bool has_optional = false, has_exp_optional = false; -#ifdef PYBIND11_HAS_OPTIONAL - has_optional = true; - using opt_int = std::optional; - m.def("double_or_zero", [](const opt_int& x) -> int { - return x.value_or(0) * 2; - }); - m.def("half_or_none", [](int x) -> opt_int { - return x ? opt_int(x / 2) : opt_int(); - }); - m.def("test_nullopt", [](opt_int x) { - return x.value_or(42); - }, py::arg_v("x", std::nullopt, "None")); -#endif - -#ifdef PYBIND11_HAS_EXP_OPTIONAL - has_exp_optional = true; - using opt_int = std::experimental::optional; - m.def("double_or_zero_exp", [](const opt_int& x) -> int { - return x.value_or(0) * 2; - }); - m.def("half_or_none_exp", [](int x) -> opt_int { - return x ? opt_int(x / 2) : opt_int(); - }); - m.def("test_nullopt_exp", [](opt_int x) { - return x.value_or(42); - }, py::arg_v("x", std::experimental::nullopt, "None")); -#endif - - m.attr("has_optional") = py::cast(has_optional); - m.attr("has_exp_optional") = py::cast(has_exp_optional); - - m.def("test_default_constructors", []() { - return py::dict( - "str"_a=py::str(), - "bool"_a=py::bool_(), - "int"_a=py::int_(), - "float"_a=py::float_(), - "tuple"_a=py::tuple(), - "list"_a=py::list(), - "dict"_a=py::dict(), - "set"_a=py::set() - ); - }); - - m.def("test_converting_constructors", [](py::dict d) { - return py::dict( - "str"_a=py::str(d["str"]), - "bool"_a=py::bool_(d["bool"]), - "int"_a=py::int_(d["int"]), - "float"_a=py::float_(d["float"]), - "tuple"_a=py::tuple(d["tuple"]), - "list"_a=py::list(d["list"]), - "dict"_a=py::dict(d["dict"]), - "set"_a=py::set(d["set"]), - "memoryview"_a=py::memoryview(d["memoryview"]) - ); - }); - - m.def("test_cast_functions", [](py::dict d) { - // When converting between Python types, obj.cast() should be the same as T(obj) - return py::dict( - "str"_a=d["str"].cast(), - "bool"_a=d["bool"].cast(), - "int"_a=d["int"].cast(), - "float"_a=d["float"].cast(), - "tuple"_a=d["tuple"].cast(), - "list"_a=d["list"].cast(), - "dict"_a=d["dict"].cast(), - "set"_a=d["set"].cast(), - "memoryview"_a=d["memoryview"].cast() - ); - }); - - py::class_(m, "MoveOutContainerValue") - .def_readonly("value", &MoveOutContainer::Value::value); - - py::class_(m, "MoveOutContainer") - .def(py::init<>()) - .def_property_readonly("move_list", &MoveOutContainer::move_list); -}); diff --git a/stormpy/resources/pybind11/tests/test_python_types.py b/stormpy/resources/pybind11/tests/test_python_types.py deleted file mode 100755 index dcd5d6245..000000000 --- a/stormpy/resources/pybind11/tests/test_python_types.py +++ /dev/null @@ -1,371 +0,0 @@ -import pytest - -from pybind11_tests import ExamplePythonTypes, ConstructorStats, has_optional, has_exp_optional - - -def test_static(): - ExamplePythonTypes.value = 15 - assert ExamplePythonTypes.value == 15 - assert ExamplePythonTypes.value2 == 5 - - with pytest.raises(AttributeError) as excinfo: - ExamplePythonTypes.value2 = 15 - assert str(excinfo.value) == "can't set attribute" - - -def test_instance(capture): - with pytest.raises(TypeError) as excinfo: - ExamplePythonTypes() - assert str(excinfo.value) == "pybind11_tests.ExamplePythonTypes: No constructor defined!" - - instance = ExamplePythonTypes.new_instance() - - with capture: - dict_result = instance.get_dict() - dict_result['key2'] = 'value2' - instance.print_dict(dict_result) - assert capture.unordered == """ - key: key, value=value - key: key2, value=value2 - """ - with capture: - dict_result = instance.get_dict_2() - dict_result['key2'] = 'value2' - instance.print_dict_2(dict_result) - assert capture.unordered == """ - key: key, value=value - key: key2, value=value2 - """ - with capture: - set_result = instance.get_set() - set_result.add('key3') - instance.print_set(set_result) - assert capture.unordered == """ - key: key1 - key: key2 - key: key3 - """ - with capture: - set_result = instance.get_set2() - set_result.add('key3') - instance.print_set_2(set_result) - assert capture.unordered == """ - key: key1 - key: key2 - key: key3 - """ - with capture: - list_result = instance.get_list() - list_result.append('value2') - instance.print_list(list_result) - assert capture.unordered == """ - Entry at position 0: value - list item 0: overwritten - list item 1: value2 - """ - with capture: - list_result = instance.get_list_2() - list_result.append('value2') - instance.print_list_2(list_result) - assert capture.unordered == """ - list item 0: value - list item 1: value2 - """ - with capture: - list_result = instance.get_list_2() - list_result.append('value2') - instance.print_list_2(tuple(list_result)) - assert capture.unordered == """ - list item 0: value - list item 1: value2 - """ - array_result = instance.get_array() - assert array_result == ['array entry 1', 'array entry 2'] - with capture: - instance.print_array(array_result) - assert capture.unordered == """ - array item 0: array entry 1 - array item 1: array entry 2 - """ - with pytest.raises(RuntimeError) as excinfo: - instance.throw_exception() - assert str(excinfo.value) == "This exception was intentionally thrown." - - assert instance.pair_passthrough((True, "test")) == ("test", True) - assert instance.tuple_passthrough((True, "test", 5)) == (5, "test", True) - - assert instance.get_bytes_from_string().decode() == "foo" - assert instance.get_bytes_from_str().decode() == "bar" - assert instance.get_str_from_string().encode().decode() == "baz" - assert instance.get_str_from_bytes().encode().decode() == "boo" - - class A(object): - def __str__(self): - return "this is a str" - - def __repr__(self): - return "this is a repr" - - with capture: - instance.test_print(A()) - assert capture == """ - this is a str - this is a repr - """ - - cstats = ConstructorStats.get(ExamplePythonTypes) - assert cstats.alive() == 1 - del instance - assert cstats.alive() == 0 - - -def test_docs(doc): - assert doc(ExamplePythonTypes) == "Example 2 documentation" - assert doc(ExamplePythonTypes.get_dict) == """ - get_dict(self: m.ExamplePythonTypes) -> dict - - Return a Python dictionary - """ - assert doc(ExamplePythonTypes.get_dict_2) == """ - get_dict_2(self: m.ExamplePythonTypes) -> Dict[str, str] - - Return a C++ dictionary - """ - assert doc(ExamplePythonTypes.get_list) == """ - get_list(self: m.ExamplePythonTypes) -> list - - Return a Python list - """ - assert doc(ExamplePythonTypes.get_list_2) == """ - get_list_2(self: m.ExamplePythonTypes) -> List[str] - - Return a C++ list - """ - assert doc(ExamplePythonTypes.get_dict) == """ - get_dict(self: m.ExamplePythonTypes) -> dict - - Return a Python dictionary - """ - assert doc(ExamplePythonTypes.get_set) == """ - get_set(self: m.ExamplePythonTypes) -> set - - Return a Python set - """ - assert doc(ExamplePythonTypes.get_set2) == """ - get_set2(self: m.ExamplePythonTypes) -> Set[str] - - Return a C++ set - """ - assert doc(ExamplePythonTypes.get_array) == """ - get_array(self: m.ExamplePythonTypes) -> List[str[2]] - - Return a C++ array - """ - assert doc(ExamplePythonTypes.print_dict) == """ - print_dict(self: m.ExamplePythonTypes, arg0: dict) -> None - - Print entries of a Python dictionary - """ - assert doc(ExamplePythonTypes.print_dict_2) == """ - print_dict_2(self: m.ExamplePythonTypes, arg0: Dict[str, str]) -> None - - Print entries of a C++ dictionary - """ - assert doc(ExamplePythonTypes.print_set) == """ - print_set(self: m.ExamplePythonTypes, arg0: set) -> None - - Print entries of a Python set - """ - assert doc(ExamplePythonTypes.print_set_2) == """ - print_set_2(self: m.ExamplePythonTypes, arg0: Set[str]) -> None - - Print entries of a C++ set - """ - assert doc(ExamplePythonTypes.print_list) == """ - print_list(self: m.ExamplePythonTypes, arg0: list) -> None - - Print entries of a Python list - """ - assert doc(ExamplePythonTypes.print_list_2) == """ - print_list_2(self: m.ExamplePythonTypes, arg0: List[str]) -> None - - Print entries of a C++ list - """ - assert doc(ExamplePythonTypes.print_array) == """ - print_array(self: m.ExamplePythonTypes, arg0: List[str[2]]) -> None - - Print entries of a C++ array - """ - assert doc(ExamplePythonTypes.pair_passthrough) == """ - pair_passthrough(self: m.ExamplePythonTypes, arg0: Tuple[bool, str]) -> Tuple[str, bool] - - Return a pair in reversed order - """ - assert doc(ExamplePythonTypes.tuple_passthrough) == """ - tuple_passthrough(self: m.ExamplePythonTypes, arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool] - - Return a triple in reversed order - """ - assert doc(ExamplePythonTypes.throw_exception) == """ - throw_exception(self: m.ExamplePythonTypes) -> None - - Throw an exception - """ - assert doc(ExamplePythonTypes.new_instance) == """ - new_instance() -> m.ExamplePythonTypes - - Return an instance - """ - - -def test_module(): - import pybind11_tests - - assert pybind11_tests.__name__ == "pybind11_tests" - assert ExamplePythonTypes.__name__ == "ExamplePythonTypes" - assert ExamplePythonTypes.__module__ == "pybind11_tests" - assert ExamplePythonTypes.get_set.__name__ == "get_set" - assert ExamplePythonTypes.get_set.__module__ == "pybind11_tests" - - -def test_print(capture): - from pybind11_tests import test_print_function - - with capture: - test_print_function() - assert capture == """ - Hello, World! - 1 2.0 three True -- multiple args - *args-and-a-custom-separator - no new line here -- next print - flush - py::print + str.format = this - """ - assert capture.stderr == "this goes to stderr" - - -def test_str_api(): - from pybind11_tests import test_str_format - - s1, s2 = test_str_format() - assert s1 == "1 + 2 = 3" - assert s1 == s2 - - -def test_dict_api(): - from pybind11_tests import test_dict_keyword_constructor - - assert test_dict_keyword_constructor() == {"x": 1, "y": 2, "z": 3} - - -def test_accessors(): - from pybind11_tests import test_accessor_api, test_tuple_accessor, test_accessor_assignment - - class SubTestObject: - attr_obj = 1 - attr_char = 2 - - class TestObject: - basic_attr = 1 - begin_end = [1, 2, 3] - d = {"operator[object]": 1, "operator[char *]": 2} - sub = SubTestObject() - - def func(self, x, *args): - return self.basic_attr + x + sum(args) - - d = test_accessor_api(TestObject()) - assert d["basic_attr"] == 1 - assert d["begin_end"] == [1, 2, 3] - assert d["operator[object]"] == 1 - assert d["operator[char *]"] == 2 - assert d["attr(object)"] == 1 - assert d["attr(char *)"] == 2 - assert d["missing_attr_ptr"] == "raised" - assert d["missing_attr_chain"] == "raised" - assert d["is_none"] is False - assert d["operator()"] == 2 - assert d["operator*"] == 7 - - assert test_tuple_accessor(tuple()) == (0, 1, 2) - - d = test_accessor_assignment() - assert d["get"] == 0 - assert d["deferred_get"] == 0 - assert d["set"] == 1 - assert d["deferred_set"] == 1 - assert d["var"] == 99 - - -@pytest.mark.skipif(not has_optional, reason='no ') -def test_optional(): - from pybind11_tests import double_or_zero, half_or_none, test_nullopt - - assert double_or_zero(None) == 0 - assert double_or_zero(42) == 84 - pytest.raises(TypeError, double_or_zero, 'foo') - - assert half_or_none(0) is None - assert half_or_none(42) == 21 - pytest.raises(TypeError, half_or_none, 'foo') - - assert test_nullopt() == 42 - assert test_nullopt(None) == 42 - assert test_nullopt(42) == 42 - assert test_nullopt(43) == 43 - - -@pytest.mark.skipif(not has_exp_optional, reason='no ') -def test_exp_optional(): - from pybind11_tests import double_or_zero_exp, half_or_none_exp, test_nullopt_exp - - assert double_or_zero_exp(None) == 0 - assert double_or_zero_exp(42) == 84 - pytest.raises(TypeError, double_or_zero_exp, 'foo') - - assert half_or_none_exp(0) is None - assert half_or_none_exp(42) == 21 - pytest.raises(TypeError, half_or_none_exp, 'foo') - - assert test_nullopt_exp() == 42 - assert test_nullopt_exp(None) == 42 - assert test_nullopt_exp(42) == 42 - assert test_nullopt_exp(43) == 43 - - -def test_constructors(): - """C++ default and converting constructors are equivalent to type calls in Python""" - from pybind11_tests import (test_default_constructors, test_converting_constructors, - test_cast_functions) - - types = [str, bool, int, float, tuple, list, dict, set] - expected = {t.__name__: t() for t in types} - assert test_default_constructors() == expected - - data = { - str: 42, - bool: "Not empty", - int: "42", - float: "+1e3", - tuple: range(3), - list: range(3), - dict: [("two", 2), ("one", 1), ("three", 3)], - set: [4, 4, 5, 6, 6, 6], - memoryview: b'abc' - } - inputs = {k.__name__: v for k, v in data.items()} - expected = {k.__name__: k(v) for k, v in data.items()} - assert test_converting_constructors(inputs) == expected - assert test_cast_functions(inputs) == expected - - -def test_move_out_container(): - """Properties use the `reference_internal` policy by default. If the underlying function - returns an rvalue, the policy is automatically changed to `move` to avoid referencing - a temporary. In case the return value is a container of user-defined types, the policy - also needs to be applied to the elements, not just the container.""" - from pybind11_tests import MoveOutContainer - - c = MoveOutContainer() - moved_out_list = c.move_list - assert [x.value for x in moved_out_list] == [0, 1, 2] diff --git a/stormpy/resources/pybind11/tests/test_sequences_and_iterators.cpp b/stormpy/resources/pybind11/tests/test_sequences_and_iterators.cpp deleted file mode 100755 index 323b4bf00..000000000 --- a/stormpy/resources/pybind11/tests/test_sequences_and_iterators.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - tests/test_sequences_and_iterators.cpp -- supporting Pythons' sequence protocol, iterators, - etc. - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" -#include -#include - -class Sequence { -public: - Sequence(size_t size) : m_size(size) { - print_created(this, "of size", m_size); - m_data = new float[size]; - memset(m_data, 0, sizeof(float) * size); - } - - Sequence(const std::vector &value) : m_size(value.size()) { - print_created(this, "of size", m_size, "from std::vector"); - m_data = new float[m_size]; - memcpy(m_data, &value[0], sizeof(float) * m_size); - } - - Sequence(const Sequence &s) : m_size(s.m_size) { - print_copy_created(this); - m_data = new float[m_size]; - memcpy(m_data, s.m_data, sizeof(float)*m_size); - } - - Sequence(Sequence &&s) : m_size(s.m_size), m_data(s.m_data) { - print_move_created(this); - s.m_size = 0; - s.m_data = nullptr; - } - - ~Sequence() { - print_destroyed(this); - delete[] m_data; - } - - Sequence &operator=(const Sequence &s) { - if (&s != this) { - delete[] m_data; - m_size = s.m_size; - m_data = new float[m_size]; - memcpy(m_data, s.m_data, sizeof(float)*m_size); - } - - print_copy_assigned(this); - - return *this; - } - - Sequence &operator=(Sequence &&s) { - if (&s != this) { - delete[] m_data; - m_size = s.m_size; - m_data = s.m_data; - s.m_size = 0; - s.m_data = nullptr; - } - - print_move_assigned(this); - - return *this; - } - - bool operator==(const Sequence &s) const { - if (m_size != s.size()) - return false; - for (size_t i=0; i> data) : data_(std::move(data)) {} - const std::pair* begin() const { return data_.data(); } - -private: - std::vector> data_; -}; - -// Interface of a map-like object that isn't (directly) an unordered_map, but provides some basic -// map-like functionality. -class StringMap { -public: - StringMap() = default; - StringMap(std::unordered_map init) - : map(std::move(init)) {} - - void set(std::string key, std::string val) { - map[key] = val; - } - - std::string get(std::string key) const { - return map.at(key); - } - - size_t size() const { - return map.size(); - } - -private: - std::unordered_map map; - -public: - decltype(map.cbegin()) begin() const { return map.cbegin(); } - decltype(map.cend()) end() const { return map.cend(); } -}; - -template -class NonZeroIterator { - const T* ptr_; -public: - NonZeroIterator(const T* ptr) : ptr_(ptr) {} - const T& operator*() const { return *ptr_; } - NonZeroIterator& operator++() { ++ptr_; return *this; } -}; - -class NonZeroSentinel {}; - -template -bool operator==(const NonZeroIterator>& it, const NonZeroSentinel&) { - return !(*it).first || !(*it).second; -} - -test_initializer sequences_and_iterators([](py::module &m) { - - py::class_ seq(m, "Sequence"); - - seq.def(py::init()) - .def(py::init&>()) - /// Bare bones interface - .def("__getitem__", [](const Sequence &s, size_t i) { - if (i >= s.size()) - throw py::index_error(); - return s[i]; - }) - .def("__setitem__", [](Sequence &s, size_t i, float v) { - if (i >= s.size()) - throw py::index_error(); - s[i] = v; - }) - .def("__len__", &Sequence::size) - /// Optional sequence protocol operations - .def("__iter__", [](const Sequence &s) { return py::make_iterator(s.begin(), s.end()); }, - py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def("__contains__", [](const Sequence &s, float v) { return s.contains(v); }) - .def("__reversed__", [](const Sequence &s) -> Sequence { return s.reversed(); }) - /// Slicing protocol (optional) - .def("__getitem__", [](const Sequence &s, py::slice slice) -> Sequence* { - size_t start, stop, step, slicelength; - if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) - throw py::error_already_set(); - Sequence *seq = new Sequence(slicelength); - for (size_t i=0; i map(m, "StringMap"); - - map .def(py::init<>()) - .def(py::init>()) - .def("__getitem__", [](const StringMap &map, std::string key) { - try { return map.get(key); } - catch (const std::out_of_range&) { - throw py::key_error("key '" + key + "' does not exist"); - } - }) - .def("__setitem__", &StringMap::set) - .def("__len__", &StringMap::size) - .def("__iter__", [](const StringMap &map) { return py::make_key_iterator(map.begin(), map.end()); }, - py::keep_alive<0, 1>()) - .def("items", [](const StringMap &map) { return py::make_iterator(map.begin(), map.end()); }, - py::keep_alive<0, 1>()) - ; - - py::class_(m, "IntPairs") - .def(py::init>>()) - .def("nonzero", [](const IntPairs& s) { - return py::make_iterator(NonZeroIterator>(s.begin()), NonZeroSentinel()); - }, py::keep_alive<0, 1>()) - .def("nonzero_keys", [](const IntPairs& s) { - return py::make_key_iterator(NonZeroIterator>(s.begin()), NonZeroSentinel()); - }, py::keep_alive<0, 1>()); - - -#if 0 - // Obsolete: special data structure for exposing custom iterator types to python - // kept here for illustrative purposes because there might be some use cases which - // are not covered by the much simpler py::make_iterator - - struct PySequenceIterator { - PySequenceIterator(const Sequence &seq, py::object ref) : seq(seq), ref(ref) { } - - float next() { - if (index == seq.size()) - throw py::stop_iteration(); - return seq[index++]; - } - - const Sequence &seq; - py::object ref; // keep a reference - size_t index = 0; - }; - - py::class_(seq, "Iterator") - .def("__iter__", [](PySequenceIterator &it) -> PySequenceIterator& { return it; }) - .def("__next__", &PySequenceIterator::next); - - On the actual Sequence object, the iterator would be constructed as follows: - .def("__iter__", [](py::object s) { return PySequenceIterator(s.cast(), s); }) -#endif -}); diff --git a/stormpy/resources/pybind11/tests/test_sequences_and_iterators.py b/stormpy/resources/pybind11/tests/test_sequences_and_iterators.py deleted file mode 100755 index 76b9f43f6..000000000 --- a/stormpy/resources/pybind11/tests/test_sequences_and_iterators.py +++ /dev/null @@ -1,90 +0,0 @@ -import pytest - - -def isclose(a, b, rel_tol=1e-05, abs_tol=0.0): - """Like math.isclose() from Python 3.5""" - return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol) - - -def allclose(a_list, b_list, rel_tol=1e-05, abs_tol=0.0): - return all(isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol) for a, b in zip(a_list, b_list)) - - -def test_generalized_iterators(): - from pybind11_tests import IntPairs - - assert list(IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero()) == [(1, 2), (3, 4)] - assert list(IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero()) == [(1, 2)] - assert list(IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero()) == [] - - assert list(IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero_keys()) == [1, 3] - assert list(IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero_keys()) == [1] - assert list(IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero_keys()) == [] - - -def test_sequence(): - from pybind11_tests import Sequence, ConstructorStats - - cstats = ConstructorStats.get(Sequence) - - s = Sequence(5) - assert cstats.values() == ['of size', '5'] - - assert "Sequence" in repr(s) - assert len(s) == 5 - assert s[0] == 0 and s[3] == 0 - assert 12.34 not in s - s[0], s[3] = 12.34, 56.78 - assert 12.34 in s - assert isclose(s[0], 12.34) and isclose(s[3], 56.78) - - rev = reversed(s) - assert cstats.values() == ['of size', '5'] - - rev2 = s[::-1] - assert cstats.values() == ['of size', '5'] - - expected = [0, 56.78, 0, 0, 12.34] - assert allclose(rev, expected) - assert allclose(rev2, expected) - assert rev == rev2 - - rev[0::2] = Sequence([2.0, 2.0, 2.0]) - assert cstats.values() == ['of size', '3', 'from std::vector'] - - assert allclose(rev, [2, 56.78, 2, 0, 2]) - - assert cstats.alive() == 3 - del s - assert cstats.alive() == 2 - del rev - assert cstats.alive() == 1 - del rev2 - assert cstats.alive() == 0 - - assert cstats.values() == [] - assert cstats.default_constructions == 0 - assert cstats.copy_constructions == 0 - assert cstats.move_constructions >= 1 - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 - - -def test_map_iterator(): - from pybind11_tests import StringMap - - m = StringMap({'hi': 'bye', 'black': 'white'}) - assert m['hi'] == 'bye' - assert len(m) == 2 - assert m['black'] == 'white' - - with pytest.raises(KeyError): - assert m['orange'] - m['orange'] = 'banana' - assert m['orange'] == 'banana' - - expected = {'hi': 'bye', 'black': 'white', 'orange': 'banana'} - for k in m: - assert m[k] == expected[k] - for k, v in m.items(): - assert v == expected[k] diff --git a/stormpy/resources/pybind11/tests/test_smart_ptr.cpp b/stormpy/resources/pybind11/tests/test_smart_ptr.cpp deleted file mode 100755 index 7d50f0dd7..000000000 --- a/stormpy/resources/pybind11/tests/test_smart_ptr.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - tests/test_smart_ptr.cpp -- binding classes with custom reference counting, - implicit conversions between types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "object.h" - -/// Custom object with builtin reference counting (see 'object.h' for the implementation) -class MyObject1 : public Object { -public: - MyObject1(int value) : value(value) { - print_created(this, toString()); - } - - std::string toString() const { - return "MyObject1[" + std::to_string(value) + "]"; - } - -protected: - virtual ~MyObject1() { - print_destroyed(this); - } - -private: - int value; -}; - -/// Object managed by a std::shared_ptr<> -class MyObject2 { -public: - MyObject2(int value) : value(value) { - print_created(this, toString()); - } - - std::string toString() const { - return "MyObject2[" + std::to_string(value) + "]"; - } - - virtual ~MyObject2() { - print_destroyed(this); - } - -private: - int value; -}; - -/// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<> -class MyObject3 : public std::enable_shared_from_this { -public: - MyObject3(int value) : value(value) { - print_created(this, toString()); - } - - std::string toString() const { - return "MyObject3[" + std::to_string(value) + "]"; - } - - virtual ~MyObject3() { - print_destroyed(this); - } - -private: - int value; -}; - -class MyObject4 { -public: - MyObject4(int value) : value{value} { - print_created(this); - } - int value; -private: - ~MyObject4() { - print_destroyed(this); - } -}; - -/// Make pybind aware of the ref-counted wrapper type (s) -PYBIND11_DECLARE_HOLDER_TYPE(T, ref); // Required for custom holder type -PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); // Not required any more for std::shared_ptr, - // but it should compile without error - -Object *make_object_1() { return new MyObject1(1); } -ref make_object_2() { return new MyObject1(2); } - -MyObject1 *make_myobject1_1() { return new MyObject1(4); } -ref make_myobject1_2() { return new MyObject1(5); } - -MyObject2 *make_myobject2_1() { return new MyObject2(6); } -std::shared_ptr make_myobject2_2() { return std::make_shared(7); } - -MyObject3 *make_myobject3_1() { return new MyObject3(8); } -std::shared_ptr make_myobject3_2() { return std::make_shared(9); } - -void print_object_1(const Object *obj) { py::print(obj->toString()); } -void print_object_2(ref obj) { py::print(obj->toString()); } -void print_object_3(const ref &obj) { py::print(obj->toString()); } -void print_object_4(const ref *obj) { py::print((*obj)->toString()); } - -void print_myobject1_1(const MyObject1 *obj) { py::print(obj->toString()); } -void print_myobject1_2(ref obj) { py::print(obj->toString()); } -void print_myobject1_3(const ref &obj) { py::print(obj->toString()); } -void print_myobject1_4(const ref *obj) { py::print((*obj)->toString()); } - -void print_myobject2_1(const MyObject2 *obj) { py::print(obj->toString()); } -void print_myobject2_2(std::shared_ptr obj) { py::print(obj->toString()); } -void print_myobject2_3(const std::shared_ptr &obj) { py::print(obj->toString()); } -void print_myobject2_4(const std::shared_ptr *obj) { py::print((*obj)->toString()); } - -void print_myobject3_1(const MyObject3 *obj) { py::print(obj->toString()); } -void print_myobject3_2(std::shared_ptr obj) { py::print(obj->toString()); } -void print_myobject3_3(const std::shared_ptr &obj) { py::print(obj->toString()); } -void print_myobject3_4(const std::shared_ptr *obj) { py::print((*obj)->toString()); } - -test_initializer smart_ptr([](py::module &m) { - py::class_> obj(m, "Object"); - obj.def("getRefCount", &Object::getRefCount); - - py::class_>(m, "MyObject1", obj) - .def(py::init()); - - m.def("make_object_1", &make_object_1); - m.def("make_object_2", &make_object_2); - m.def("make_myobject1_1", &make_myobject1_1); - m.def("make_myobject1_2", &make_myobject1_2); - m.def("print_object_1", &print_object_1); - m.def("print_object_2", &print_object_2); - m.def("print_object_3", &print_object_3); - m.def("print_object_4", &print_object_4); - m.def("print_myobject1_1", &print_myobject1_1); - m.def("print_myobject1_2", &print_myobject1_2); - m.def("print_myobject1_3", &print_myobject1_3); - m.def("print_myobject1_4", &print_myobject1_4); - - py::class_>(m, "MyObject2") - .def(py::init()); - m.def("make_myobject2_1", &make_myobject2_1); - m.def("make_myobject2_2", &make_myobject2_2); - m.def("print_myobject2_1", &print_myobject2_1); - m.def("print_myobject2_2", &print_myobject2_2); - m.def("print_myobject2_3", &print_myobject2_3); - m.def("print_myobject2_4", &print_myobject2_4); - - py::class_>(m, "MyObject3") - .def(py::init()); - m.def("make_myobject3_1", &make_myobject3_1); - m.def("make_myobject3_2", &make_myobject3_2); - m.def("print_myobject3_1", &print_myobject3_1); - m.def("print_myobject3_2", &print_myobject3_2); - m.def("print_myobject3_3", &print_myobject3_3); - m.def("print_myobject3_4", &print_myobject3_4); - - py::class_>(m, "MyObject4") - .def(py::init()) - .def_readwrite("value", &MyObject4::value); - - py::implicitly_convertible(); - - // Expose constructor stats for the ref type - m.def("cstats_ref", &ConstructorStats::get); -}); diff --git a/stormpy/resources/pybind11/tests/test_smart_ptr.py b/stormpy/resources/pybind11/tests/test_smart_ptr.py deleted file mode 100755 index 8af2ae8cd..000000000 --- a/stormpy/resources/pybind11/tests/test_smart_ptr.py +++ /dev/null @@ -1,126 +0,0 @@ -from pybind11_tests import ConstructorStats - - -def test_smart_ptr(capture): - # Object1 - from pybind11_tests import (MyObject1, make_object_1, make_object_2, - print_object_1, print_object_2, print_object_3, print_object_4) - - for i, o in enumerate([make_object_1(), make_object_2(), MyObject1(3)], start=1): - assert o.getRefCount() == 1 - with capture: - print_object_1(o) - print_object_2(o) - print_object_3(o) - print_object_4(o) - assert capture == "MyObject1[{i}]\n".format(i=i) * 4 - - from pybind11_tests import (make_myobject1_1, make_myobject1_2, - print_myobject1_1, print_myobject1_2, - print_myobject1_3, print_myobject1_4) - - for i, o in enumerate([make_myobject1_1(), make_myobject1_2(), MyObject1(6), 7], start=4): - print(o) - with capture: - if not isinstance(o, int): - print_object_1(o) - print_object_2(o) - print_object_3(o) - print_object_4(o) - print_myobject1_1(o) - print_myobject1_2(o) - print_myobject1_3(o) - print_myobject1_4(o) - assert capture == "MyObject1[{i}]\n".format(i=i) * (4 if isinstance(o, int) else 8) - - cstats = ConstructorStats.get(MyObject1) - assert cstats.alive() == 0 - expected_values = ['MyObject1[{}]'.format(i) for i in range(1, 7)] + ['MyObject1[7]'] * 4 - assert cstats.values() == expected_values - assert cstats.default_constructions == 0 - assert cstats.copy_constructions == 0 - # assert cstats.move_constructions >= 0 # Doesn't invoke any - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 - - # Object2 - from pybind11_tests import (MyObject2, make_myobject2_1, make_myobject2_2, - make_myobject3_1, make_myobject3_2, - print_myobject2_1, print_myobject2_2, - print_myobject2_3, print_myobject2_4) - - for i, o in zip([8, 6, 7], [MyObject2(8), make_myobject2_1(), make_myobject2_2()]): - print(o) - with capture: - print_myobject2_1(o) - print_myobject2_2(o) - print_myobject2_3(o) - print_myobject2_4(o) - assert capture == "MyObject2[{i}]\n".format(i=i) * 4 - - cstats = ConstructorStats.get(MyObject2) - assert cstats.alive() == 1 - o = None - assert cstats.alive() == 0 - assert cstats.values() == ['MyObject2[8]', 'MyObject2[6]', 'MyObject2[7]'] - assert cstats.default_constructions == 0 - assert cstats.copy_constructions == 0 - # assert cstats.move_constructions >= 0 # Doesn't invoke any - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 - - # Object3 - from pybind11_tests import (MyObject3, print_myobject3_1, print_myobject3_2, - print_myobject3_3, print_myobject3_4) - - for i, o in zip([9, 8, 9], [MyObject3(9), make_myobject3_1(), make_myobject3_2()]): - print(o) - with capture: - print_myobject3_1(o) - print_myobject3_2(o) - print_myobject3_3(o) - print_myobject3_4(o) - assert capture == "MyObject3[{i}]\n".format(i=i) * 4 - - cstats = ConstructorStats.get(MyObject3) - assert cstats.alive() == 1 - o = None - assert cstats.alive() == 0 - assert cstats.values() == ['MyObject3[9]', 'MyObject3[8]', 'MyObject3[9]'] - assert cstats.default_constructions == 0 - assert cstats.copy_constructions == 0 - # assert cstats.move_constructions >= 0 # Doesn't invoke any - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 - - # Object and ref - from pybind11_tests import Object, cstats_ref - - cstats = ConstructorStats.get(Object) - assert cstats.alive() == 0 - assert cstats.values() == [] - assert cstats.default_constructions == 10 - assert cstats.copy_constructions == 0 - # assert cstats.move_constructions >= 0 # Doesn't invoke any - assert cstats.copy_assignments == 0 - assert cstats.move_assignments == 0 - - cstats = cstats_ref() - assert cstats.alive() == 0 - assert cstats.values() == ['from pointer'] * 10 - assert cstats.default_constructions == 30 - assert cstats.copy_constructions == 12 - # assert cstats.move_constructions >= 0 # Doesn't invoke any - assert cstats.copy_assignments == 30 - assert cstats.move_assignments == 0 - - -def test_unique_nodelete(): - from pybind11_tests import MyObject4 - o = MyObject4(23) - assert o.value == 23 - cstats = ConstructorStats.get(MyObject4) - assert cstats.alive() == 1 - del o - cstats = ConstructorStats.get(MyObject4) - assert cstats.alive() == 1 # Leak, but that's intentional diff --git a/stormpy/resources/pybind11/tests/test_stl_binders.cpp b/stormpy/resources/pybind11/tests/test_stl_binders.cpp deleted file mode 100755 index b9b56c15d..000000000 --- a/stormpy/resources/pybind11/tests/test_stl_binders.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - tests/test_stl_binders.cpp -- Usage of stl_binders functions - - Copyright (c) 2016 Sergey Lyskov - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" - -#include -#include -#include -#include - -class El { -public: - El() = delete; - El(int v) : a(v) { } - - int a; -}; - -std::ostream & operator<<(std::ostream &s, El const&v) { - s << "El{" << v.a << '}'; - return s; -} - -/// Issue #487: binding std::vector with E non-copyable -class E_nc { -public: - explicit E_nc(int i) : value{i} {} - E_nc(const E_nc &) = delete; - E_nc &operator=(const E_nc &) = delete; - E_nc(E_nc &&) = default; - E_nc &operator=(E_nc &&) = default; - - int value; -}; - -template Container *one_to_n(int n) { - auto v = new Container(); - for (int i = 1; i <= n; i++) - v->emplace_back(i); - return v; -} - -template Map *times_ten(int n) { - auto m = new Map(); - for (int i = 1; i <= n; i++) - m->emplace(int(i), E_nc(10*i)); - return m; -} - -test_initializer stl_binder_vector([](py::module &m) { - py::class_(m, "El") - .def(py::init()); - - py::bind_vector>(m, "VectorInt"); - py::bind_vector>(m, "VectorBool"); - - py::bind_vector>(m, "VectorEl"); - - py::bind_vector>>(m, "VectorVectorEl"); - -}); - -test_initializer stl_binder_map([](py::module &m) { - py::bind_map>(m, "MapStringDouble"); - py::bind_map>(m, "UnorderedMapStringDouble"); - - py::bind_map>(m, "MapStringDoubleConst"); - py::bind_map>(m, "UnorderedMapStringDoubleConst"); - -}); - -test_initializer stl_binder_noncopyable([](py::module &m) { - py::class_(m, "ENC") - .def(py::init()) - .def_readwrite("value", &E_nc::value); - - py::bind_vector>(m, "VectorENC"); - m.def("get_vnc", &one_to_n>, py::return_value_policy::reference); - - py::bind_vector>(m, "DequeENC"); - m.def("get_dnc", &one_to_n>, py::return_value_policy::reference); - - py::bind_map>(m, "MapENC"); - m.def("get_mnc", ×_ten>, py::return_value_policy::reference); - - py::bind_map>(m, "UmapENC"); - m.def("get_umnc", ×_ten>, py::return_value_policy::reference); -}); - diff --git a/stormpy/resources/pybind11/tests/test_stl_binders.py b/stormpy/resources/pybind11/tests/test_stl_binders.py deleted file mode 100755 index c9bcc7935..000000000 --- a/stormpy/resources/pybind11/tests/test_stl_binders.py +++ /dev/null @@ -1,140 +0,0 @@ -def test_vector_int(): - from pybind11_tests import VectorInt - - v_int = VectorInt([0, 0]) - assert len(v_int) == 2 - assert bool(v_int) is True - - v_int2 = VectorInt([0, 0]) - assert v_int == v_int2 - v_int2[1] = 1 - assert v_int != v_int2 - - v_int2.append(2) - v_int2.append(3) - v_int2.insert(0, 1) - v_int2.insert(0, 2) - v_int2.insert(0, 3) - assert str(v_int2) == "VectorInt[3, 2, 1, 0, 1, 2, 3]" - - v_int.append(99) - v_int2[2:-2] = v_int - assert v_int2 == VectorInt([3, 2, 0, 0, 99, 2, 3]) - del v_int2[1:3] - assert v_int2 == VectorInt([3, 0, 99, 2, 3]) - del v_int2[0] - assert v_int2 == VectorInt([0, 99, 2, 3]) - - -def test_vector_custom(): - from pybind11_tests import El, VectorEl, VectorVectorEl - - v_a = VectorEl() - v_a.append(El(1)) - v_a.append(El(2)) - assert str(v_a) == "VectorEl[El{1}, El{2}]" - - vv_a = VectorVectorEl() - vv_a.append(v_a) - vv_b = vv_a[0] - assert str(vv_b) == "VectorEl[El{1}, El{2}]" - - -def test_vector_bool(): - from pybind11_tests import VectorBool - - vv_c = VectorBool() - for i in range(10): - vv_c.append(i % 2 == 0) - for i in range(10): - assert vv_c[i] == (i % 2 == 0) - assert str(vv_c) == "VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]" - - -def test_map_string_double(): - from pybind11_tests import MapStringDouble, UnorderedMapStringDouble - - m = MapStringDouble() - m['a'] = 1 - m['b'] = 2.5 - - assert list(m) == ['a', 'b'] - assert list(m.items()) == [('a', 1), ('b', 2.5)] - assert str(m) == "MapStringDouble{a: 1, b: 2.5}" - - um = UnorderedMapStringDouble() - um['ua'] = 1.1 - um['ub'] = 2.6 - - assert sorted(list(um)) == ['ua', 'ub'] - assert sorted(list(um.items())) == [('ua', 1.1), ('ub', 2.6)] - assert "UnorderedMapStringDouble" in str(um) - - -def test_map_string_double_const(): - from pybind11_tests import MapStringDoubleConst, UnorderedMapStringDoubleConst - - mc = MapStringDoubleConst() - mc['a'] = 10 - mc['b'] = 20.5 - assert str(mc) == "MapStringDoubleConst{a: 10, b: 20.5}" - - umc = UnorderedMapStringDoubleConst() - umc['a'] = 11 - umc['b'] = 21.5 - - str(umc) - - -def test_noncopyable_vector(): - from pybind11_tests import get_vnc - - vnc = get_vnc(5) - for i in range(0, 5): - assert vnc[i].value == i + 1 - - for i, j in enumerate(vnc, start=1): - assert j.value == i - - -def test_noncopyable_deque(): - from pybind11_tests import get_dnc - - dnc = get_dnc(5) - for i in range(0, 5): - assert dnc[i].value == i + 1 - - i = 1 - for j in dnc: - assert(j.value == i) - i += 1 - - -def test_noncopyable_map(): - from pybind11_tests import get_mnc - - mnc = get_mnc(5) - for i in range(1, 6): - assert mnc[i].value == 10 * i - - vsum = 0 - for k, v in mnc.items(): - assert v.value == 10 * k - vsum += v.value - - assert vsum == 150 - - -def test_noncopyable_unordered_map(): - from pybind11_tests import get_umnc - - mnc = get_umnc(5) - for i in range(1, 6): - assert mnc[i].value == 10 * i - - vsum = 0 - for k, v in mnc.items(): - assert v.value == 10 * k - vsum += v.value - - assert vsum == 150 diff --git a/stormpy/resources/pybind11/tests/test_virtual_functions.cpp b/stormpy/resources/pybind11/tests/test_virtual_functions.cpp deleted file mode 100755 index 0f8ed2afb..000000000 --- a/stormpy/resources/pybind11/tests/test_virtual_functions.cpp +++ /dev/null @@ -1,347 +0,0 @@ -/* - tests/test_virtual_functions.cpp -- overriding virtual functions from Python - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#include "pybind11_tests.h" -#include "constructor_stats.h" -#include - -/* This is an example class that we'll want to be able to extend from Python */ -class ExampleVirt { -public: - ExampleVirt(int state) : state(state) { print_created(this, state); } - ExampleVirt(const ExampleVirt &e) : state(e.state) { print_copy_created(this); } - ExampleVirt(ExampleVirt &&e) : state(e.state) { print_move_created(this); e.state = 0; } - ~ExampleVirt() { print_destroyed(this); } - - virtual int run(int value) { - py::print("Original implementation of " - "ExampleVirt::run(state={}, value={}, str1={}, str2={})"_s.format(state, value, get_string1(), *get_string2())); - return state + value; - } - - virtual bool run_bool() = 0; - virtual void pure_virtual() = 0; - - // Returning a reference/pointer to a type converted from python (numbers, strings, etc.) is a - // bit trickier, because the actual int& or std::string& or whatever only exists temporarily, so - // we have to handle it specially in the trampoline class (see below). - virtual const std::string &get_string1() { return str1; } - virtual const std::string *get_string2() { return &str2; } - -private: - int state; - const std::string str1{"default1"}, str2{"default2"}; -}; - -/* This is a wrapper class that must be generated */ -class PyExampleVirt : public ExampleVirt { -public: - using ExampleVirt::ExampleVirt; /* Inherit constructors */ - - int run(int value) override { - /* Generate wrapping code that enables native function overloading */ - PYBIND11_OVERLOAD( - int, /* Return type */ - ExampleVirt, /* Parent class */ - run, /* Name of function */ - value /* Argument(s) */ - ); - } - - bool run_bool() override { - PYBIND11_OVERLOAD_PURE( - bool, /* Return type */ - ExampleVirt, /* Parent class */ - run_bool, /* Name of function */ - /* This function has no arguments. The trailing comma - in the previous line is needed for some compilers */ - ); - } - - void pure_virtual() override { - PYBIND11_OVERLOAD_PURE( - void, /* Return type */ - ExampleVirt, /* Parent class */ - pure_virtual, /* Name of function */ - /* This function has no arguments. The trailing comma - in the previous line is needed for some compilers */ - ); - } - - // We can return reference types for compatibility with C++ virtual interfaces that do so, but - // note they have some significant limitations (see the documentation). - const std::string &get_string1() override { - PYBIND11_OVERLOAD( - const std::string &, /* Return type */ - ExampleVirt, /* Parent class */ - get_string1, /* Name of function */ - /* (no arguments) */ - ); - } - - const std::string *get_string2() override { - PYBIND11_OVERLOAD( - const std::string *, /* Return type */ - ExampleVirt, /* Parent class */ - get_string2, /* Name of function */ - /* (no arguments) */ - ); - } - -}; - -class NonCopyable { -public: - NonCopyable(int a, int b) : value{new int(a*b)} { print_created(this, a, b); } - NonCopyable(NonCopyable &&o) { value = std::move(o.value); print_move_created(this); } - NonCopyable(const NonCopyable &) = delete; - NonCopyable() = delete; - void operator=(const NonCopyable &) = delete; - void operator=(NonCopyable &&) = delete; - std::string get_value() const { - if (value) return std::to_string(*value); else return "(null)"; - } - ~NonCopyable() { print_destroyed(this); } - -private: - std::unique_ptr value; -}; - -// This is like the above, but is both copy and movable. In effect this means it should get moved -// when it is not referenced elsewhere, but copied if it is still referenced. -class Movable { -public: - Movable(int a, int b) : value{a+b} { print_created(this, a, b); } - Movable(const Movable &m) { value = m.value; print_copy_created(this); } - Movable(Movable &&m) { value = std::move(m.value); print_move_created(this); } - std::string get_value() const { return std::to_string(value); } - ~Movable() { print_destroyed(this); } -private: - int value; -}; - -class NCVirt { -public: - virtual NonCopyable get_noncopyable(int a, int b) { return NonCopyable(a, b); } - virtual Movable get_movable(int a, int b) = 0; - - std::string print_nc(int a, int b) { return get_noncopyable(a, b).get_value(); } - std::string print_movable(int a, int b) { return get_movable(a, b).get_value(); } -}; -class NCVirtTrampoline : public NCVirt { -#if !defined(__INTEL_COMPILER) - NonCopyable get_noncopyable(int a, int b) override { - PYBIND11_OVERLOAD(NonCopyable, NCVirt, get_noncopyable, a, b); - } -#endif - Movable get_movable(int a, int b) override { - PYBIND11_OVERLOAD_PURE(Movable, NCVirt, get_movable, a, b); - } -}; - -int runExampleVirt(ExampleVirt *ex, int value) { - return ex->run(value); -} - -bool runExampleVirtBool(ExampleVirt* ex) { - return ex->run_bool(); -} - -void runExampleVirtVirtual(ExampleVirt *ex) { - ex->pure_virtual(); -} - - -// Inheriting virtual methods. We do two versions here: the repeat-everything version and the -// templated trampoline versions mentioned in docs/advanced.rst. -// -// These base classes are exactly the same, but we technically need distinct -// classes for this example code because we need to be able to bind them -// properly (pybind11, sensibly, doesn't allow us to bind the same C++ class to -// multiple python classes). -class A_Repeat { -#define A_METHODS \ -public: \ - virtual int unlucky_number() = 0; \ - virtual std::string say_something(unsigned times) { \ - std::string s = ""; \ - for (unsigned i = 0; i < times; ++i) \ - s += "hi"; \ - return s; \ - } \ - std::string say_everything() { \ - return say_something(1) + " " + std::to_string(unlucky_number()); \ - } -A_METHODS -}; -class B_Repeat : public A_Repeat { -#define B_METHODS \ -public: \ - int unlucky_number() override { return 13; } \ - std::string say_something(unsigned times) override { \ - return "B says hi " + std::to_string(times) + " times"; \ - } \ - virtual double lucky_number() { return 7.0; } -B_METHODS -}; -class C_Repeat : public B_Repeat { -#define C_METHODS \ -public: \ - int unlucky_number() override { return 4444; } \ - double lucky_number() override { return 888; } -C_METHODS -}; -class D_Repeat : public C_Repeat { -#define D_METHODS // Nothing overridden. -D_METHODS -}; - -// Base classes for templated inheritance trampolines. Identical to the repeat-everything version: -class A_Tpl { A_METHODS }; -class B_Tpl : public A_Tpl { B_METHODS }; -class C_Tpl : public B_Tpl { C_METHODS }; -class D_Tpl : public C_Tpl { D_METHODS }; - - -// Inheritance approach 1: each trampoline gets every virtual method (11 in total) -class PyA_Repeat : public A_Repeat { -public: - using A_Repeat::A_Repeat; - int unlucky_number() override { PYBIND11_OVERLOAD_PURE(int, A_Repeat, unlucky_number, ); } - std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, A_Repeat, say_something, times); } -}; -class PyB_Repeat : public B_Repeat { -public: - using B_Repeat::B_Repeat; - int unlucky_number() override { PYBIND11_OVERLOAD(int, B_Repeat, unlucky_number, ); } - std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, B_Repeat, say_something, times); } - double lucky_number() override { PYBIND11_OVERLOAD(double, B_Repeat, lucky_number, ); } -}; -class PyC_Repeat : public C_Repeat { -public: - using C_Repeat::C_Repeat; - int unlucky_number() override { PYBIND11_OVERLOAD(int, C_Repeat, unlucky_number, ); } - std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, C_Repeat, say_something, times); } - double lucky_number() override { PYBIND11_OVERLOAD(double, C_Repeat, lucky_number, ); } -}; -class PyD_Repeat : public D_Repeat { -public: - using D_Repeat::D_Repeat; - int unlucky_number() override { PYBIND11_OVERLOAD(int, D_Repeat, unlucky_number, ); } - std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, D_Repeat, say_something, times); } - double lucky_number() override { PYBIND11_OVERLOAD(double, D_Repeat, lucky_number, ); } -}; - -// Inheritance approach 2: templated trampoline classes. -// -// Advantages: -// - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one for -// any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes and 11 -// methods (repeat). -// - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and can -// properly inherit constructors. -// -// Disadvantage: -// - the compiler must still generate and compile 14 different methods (more, even, than the 11 -// required for the repeat approach) instead of the 6 required for MI. (If there was no pure -// method (or no pure method override), the number would drop down to the same 11 as the repeat -// approach). -template -class PyA_Tpl : public Base { -public: - using Base::Base; // Inherit constructors - int unlucky_number() override { PYBIND11_OVERLOAD_PURE(int, Base, unlucky_number, ); } - std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, Base, say_something, times); } -}; -template -class PyB_Tpl : public PyA_Tpl { -public: - using PyA_Tpl::PyA_Tpl; // Inherit constructors (via PyA_Tpl's inherited constructors) - int unlucky_number() override { PYBIND11_OVERLOAD(int, Base, unlucky_number, ); } - double lucky_number() override { PYBIND11_OVERLOAD(double, Base, lucky_number, ); } -}; -// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these (we can -// use PyB_Tpl and PyB_Tpl for the trampoline classes instead): -/* -template class PyC_Tpl : public PyB_Tpl { -public: - using PyB_Tpl::PyB_Tpl; -}; -template class PyD_Tpl : public PyC_Tpl { -public: - using PyC_Tpl::PyC_Tpl; -}; -*/ - - -void initialize_inherited_virtuals(py::module &m) { - // Method 1: repeat - py::class_(m, "A_Repeat") - .def(py::init<>()) - .def("unlucky_number", &A_Repeat::unlucky_number) - .def("say_something", &A_Repeat::say_something) - .def("say_everything", &A_Repeat::say_everything); - py::class_(m, "B_Repeat") - .def(py::init<>()) - .def("lucky_number", &B_Repeat::lucky_number); - py::class_(m, "C_Repeat") - .def(py::init<>()); - py::class_(m, "D_Repeat") - .def(py::init<>()); - - // Method 2: Templated trampolines - py::class_>(m, "A_Tpl") - .def(py::init<>()) - .def("unlucky_number", &A_Tpl::unlucky_number) - .def("say_something", &A_Tpl::say_something) - .def("say_everything", &A_Tpl::say_everything); - py::class_>(m, "B_Tpl") - .def(py::init<>()) - .def("lucky_number", &B_Tpl::lucky_number); - py::class_>(m, "C_Tpl") - .def(py::init<>()); - py::class_>(m, "D_Tpl") - .def(py::init<>()); - -}; - - -test_initializer virtual_functions([](py::module &m) { - /* Important: indicate the trampoline class PyExampleVirt using the third - argument to py::class_. The second argument with the unique pointer - is simply the default holder type used by pybind11. */ - py::class_(m, "ExampleVirt") - .def(py::init()) - /* Reference original class in function definitions */ - .def("run", &ExampleVirt::run) - .def("run_bool", &ExampleVirt::run_bool) - .def("pure_virtual", &ExampleVirt::pure_virtual); - - py::class_(m, "NonCopyable") - .def(py::init()); - - py::class_(m, "Movable") - .def(py::init()); - -#if !defined(__INTEL_COMPILER) - py::class_(m, "NCVirt") - .def(py::init<>()) - .def("get_noncopyable", &NCVirt::get_noncopyable) - .def("get_movable", &NCVirt::get_movable) - .def("print_nc", &NCVirt::print_nc) - .def("print_movable", &NCVirt::print_movable); -#endif - - m.def("runExampleVirt", &runExampleVirt); - m.def("runExampleVirtBool", &runExampleVirtBool); - m.def("runExampleVirtVirtual", &runExampleVirtVirtual); - - m.def("cstats_debug", &ConstructorStats::get); - initialize_inherited_virtuals(m); -}); diff --git a/stormpy/resources/pybind11/tests/test_virtual_functions.py b/stormpy/resources/pybind11/tests/test_virtual_functions.py deleted file mode 100755 index eeecc235a..000000000 --- a/stormpy/resources/pybind11/tests/test_virtual_functions.py +++ /dev/null @@ -1,254 +0,0 @@ -import pytest -import pybind11_tests -from pybind11_tests import ConstructorStats - - -def test_override(capture, msg): - from pybind11_tests import (ExampleVirt, runExampleVirt, runExampleVirtVirtual, - runExampleVirtBool) - - class ExtendedExampleVirt(ExampleVirt): - def __init__(self, state): - super(ExtendedExampleVirt, self).__init__(state + 1) - self.data = "Hello world" - - def run(self, value): - print('ExtendedExampleVirt::run(%i), calling parent..' % value) - return super(ExtendedExampleVirt, self).run(value + 1) - - def run_bool(self): - print('ExtendedExampleVirt::run_bool()') - return False - - def get_string1(self): - return "override1" - - def pure_virtual(self): - print('ExtendedExampleVirt::pure_virtual(): %s' % self.data) - - class ExtendedExampleVirt2(ExtendedExampleVirt): - def __init__(self, state): - super(ExtendedExampleVirt2, self).__init__(state + 1) - - def get_string2(self): - return "override2" - - ex12 = ExampleVirt(10) - with capture: - assert runExampleVirt(ex12, 20) == 30 - assert capture == "Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)" - - with pytest.raises(RuntimeError) as excinfo: - runExampleVirtVirtual(ex12) - assert msg(excinfo.value) == 'Tried to call pure virtual function "ExampleVirt::pure_virtual"' - - ex12p = ExtendedExampleVirt(10) - with capture: - assert runExampleVirt(ex12p, 20) == 32 - assert capture == """ - ExtendedExampleVirt::run(20), calling parent.. - Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2) - """ - with capture: - assert runExampleVirtBool(ex12p) is False - assert capture == "ExtendedExampleVirt::run_bool()" - with capture: - runExampleVirtVirtual(ex12p) - assert capture == "ExtendedExampleVirt::pure_virtual(): Hello world" - - ex12p2 = ExtendedExampleVirt2(15) - with capture: - assert runExampleVirt(ex12p2, 50) == 68 - assert capture == """ - ExtendedExampleVirt::run(50), calling parent.. - Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2) - """ - - cstats = ConstructorStats.get(ExampleVirt) - assert cstats.alive() == 3 - del ex12, ex12p, ex12p2 - assert cstats.alive() == 0 - assert cstats.values() == ['10', '11', '17'] - assert cstats.copy_constructions == 0 - assert cstats.move_constructions >= 0 - - -def test_inheriting_repeat(): - from pybind11_tests import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_Tpl, B_Tpl, C_Tpl, D_Tpl - - class AR(A_Repeat): - def unlucky_number(self): - return 99 - - class AT(A_Tpl): - def unlucky_number(self): - return 999 - - obj = AR() - assert obj.say_something(3) == "hihihi" - assert obj.unlucky_number() == 99 - assert obj.say_everything() == "hi 99" - - obj = AT() - assert obj.say_something(3) == "hihihi" - assert obj.unlucky_number() == 999 - assert obj.say_everything() == "hi 999" - - for obj in [B_Repeat(), B_Tpl()]: - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 13 - assert obj.lucky_number() == 7.0 - assert obj.say_everything() == "B says hi 1 times 13" - - for obj in [C_Repeat(), C_Tpl()]: - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 4444 - assert obj.lucky_number() == 888.0 - assert obj.say_everything() == "B says hi 1 times 4444" - - class CR(C_Repeat): - def lucky_number(self): - return C_Repeat.lucky_number(self) + 1.25 - - obj = CR() - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 4444 - assert obj.lucky_number() == 889.25 - assert obj.say_everything() == "B says hi 1 times 4444" - - class CT(C_Tpl): - pass - - obj = CT() - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 4444 - assert obj.lucky_number() == 888.0 - assert obj.say_everything() == "B says hi 1 times 4444" - - class CCR(CR): - def lucky_number(self): - return CR.lucky_number(self) * 10 - - obj = CCR() - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 4444 - assert obj.lucky_number() == 8892.5 - assert obj.say_everything() == "B says hi 1 times 4444" - - class CCT(CT): - def lucky_number(self): - return CT.lucky_number(self) * 1000 - - obj = CCT() - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 4444 - assert obj.lucky_number() == 888000.0 - assert obj.say_everything() == "B says hi 1 times 4444" - - class DR(D_Repeat): - def unlucky_number(self): - return 123 - - def lucky_number(self): - return 42.0 - - for obj in [D_Repeat(), D_Tpl()]: - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 4444 - assert obj.lucky_number() == 888.0 - assert obj.say_everything() == "B says hi 1 times 4444" - - obj = DR() - assert obj.say_something(3) == "B says hi 3 times" - assert obj.unlucky_number() == 123 - assert obj.lucky_number() == 42.0 - assert obj.say_everything() == "B says hi 1 times 123" - - class DT(D_Tpl): - def say_something(self, times): - return "DT says:" + (' quack' * times) - - def unlucky_number(self): - return 1234 - - def lucky_number(self): - return -4.25 - - obj = DT() - assert obj.say_something(3) == "DT says: quack quack quack" - assert obj.unlucky_number() == 1234 - assert obj.lucky_number() == -4.25 - assert obj.say_everything() == "DT says: quack 1234" - - class DT2(DT): - def say_something(self, times): - return "DT2: " + ('QUACK' * times) - - def unlucky_number(self): - return -3 - - class BT(B_Tpl): - def say_something(self, times): - return "BT" * times - - def unlucky_number(self): - return -7 - - def lucky_number(self): - return -1.375 - - obj = BT() - assert obj.say_something(3) == "BTBTBT" - assert obj.unlucky_number() == -7 - assert obj.lucky_number() == -1.375 - assert obj.say_everything() == "BT -7" - - -@pytest.mark.skipif(not hasattr(pybind11_tests, 'NCVirt'), - reason="NCVirt test broken on ICPC") -def test_move_support(): - from pybind11_tests import NCVirt, NonCopyable, Movable - - class NCVirtExt(NCVirt): - def get_noncopyable(self, a, b): - # Constructs and returns a new instance: - nc = NonCopyable(a * a, b * b) - return nc - - def get_movable(self, a, b): - # Return a referenced copy - self.movable = Movable(a, b) - return self.movable - - class NCVirtExt2(NCVirt): - def get_noncopyable(self, a, b): - # Keep a reference: this is going to throw an exception - self.nc = NonCopyable(a, b) - return self.nc - - def get_movable(self, a, b): - # Return a new instance without storing it - return Movable(a, b) - - ncv1 = NCVirtExt() - assert ncv1.print_nc(2, 3) == "36" - assert ncv1.print_movable(4, 5) == "9" - ncv2 = NCVirtExt2() - assert ncv2.print_movable(7, 7) == "14" - # Don't check the exception message here because it differs under debug/non-debug mode - with pytest.raises(RuntimeError): - ncv2.print_nc(9, 9) - - nc_stats = ConstructorStats.get(NonCopyable) - mv_stats = ConstructorStats.get(Movable) - assert nc_stats.alive() == 1 - assert mv_stats.alive() == 1 - del ncv1, ncv2 - assert nc_stats.alive() == 0 - assert mv_stats.alive() == 0 - assert nc_stats.values() == ['4', '9', '9', '9'] - assert mv_stats.values() == ['4', '5', '7', '7'] - assert nc_stats.copy_constructions == 0 - assert mv_stats.copy_constructions == 1 - assert nc_stats.move_constructions >= 0 - assert mv_stats.move_constructions >= 0 diff --git a/stormpy/resources/pybind11/tools/FindEigen3.cmake b/stormpy/resources/pybind11/tools/FindEigen3.cmake deleted file mode 100644 index 9c546a05d..000000000 --- a/stormpy/resources/pybind11/tools/FindEigen3.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# - Try to find Eigen3 lib -# -# This module supports requiring a minimum version, e.g. you can do -# find_package(Eigen3 3.1.2) -# to require version 3.1.2 or newer of Eigen3. -# -# Once done this will define -# -# EIGEN3_FOUND - system has eigen lib with correct version -# EIGEN3_INCLUDE_DIR - the eigen include directory -# EIGEN3_VERSION - eigen version - -# Copyright (c) 2006, 2007 Montel Laurent, -# Copyright (c) 2008, 2009 Gael Guennebaud, -# Copyright (c) 2009 Benoit Jacob -# Redistribution and use is allowed according to the terms of the 2-clause BSD license. - -if(NOT Eigen3_FIND_VERSION) - if(NOT Eigen3_FIND_VERSION_MAJOR) - set(Eigen3_FIND_VERSION_MAJOR 2) - endif(NOT Eigen3_FIND_VERSION_MAJOR) - if(NOT Eigen3_FIND_VERSION_MINOR) - set(Eigen3_FIND_VERSION_MINOR 91) - endif(NOT Eigen3_FIND_VERSION_MINOR) - if(NOT Eigen3_FIND_VERSION_PATCH) - set(Eigen3_FIND_VERSION_PATCH 0) - endif(NOT Eigen3_FIND_VERSION_PATCH) - - set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") -endif(NOT Eigen3_FIND_VERSION) - -macro(_eigen3_check_version) - file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) - - string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") - set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") - set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") - set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") - - set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) - if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - set(EIGEN3_VERSION_OK FALSE) - else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - set(EIGEN3_VERSION_OK TRUE) - endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - - if(NOT EIGEN3_VERSION_OK) - - message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " - "but at least version ${Eigen3_FIND_VERSION} is required") - endif(NOT EIGEN3_VERSION_OK) -endmacro(_eigen3_check_version) - -if (EIGEN3_INCLUDE_DIR) - - # in cache already - _eigen3_check_version() - set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) - -else (EIGEN3_INCLUDE_DIR) - - find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library - PATHS - ${CMAKE_INSTALL_PREFIX}/include - ${KDE4_INCLUDE_DIR} - PATH_SUFFIXES eigen3 eigen - ) - - if(EIGEN3_INCLUDE_DIR) - _eigen3_check_version() - endif(EIGEN3_INCLUDE_DIR) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) - - mark_as_advanced(EIGEN3_INCLUDE_DIR) - -endif(EIGEN3_INCLUDE_DIR) - diff --git a/stormpy/resources/pybind11/tools/FindPythonLibsNew.cmake b/stormpy/resources/pybind11/tools/FindPythonLibsNew.cmake deleted file mode 100755 index dc44a9df5..000000000 --- a/stormpy/resources/pybind11/tools/FindPythonLibsNew.cmake +++ /dev/null @@ -1,194 +0,0 @@ -# - Find python libraries -# This module finds the libraries corresponding to the Python interpeter -# FindPythonInterp provides. -# This code sets the following variables: -# -# PYTHONLIBS_FOUND - have the Python libs been found -# PYTHON_PREFIX - path to the Python installation -# PYTHON_LIBRARIES - path to the python library -# PYTHON_INCLUDE_DIRS - path to where Python.h is found -# PYTHON_MODULE_EXTENSION - lib extension, e.g. '.so' or '.pyd' -# PYTHON_MODULE_PREFIX - lib name prefix: usually an empty string -# PYTHON_SITE_PACKAGES - path to installation site-packages -# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build -# -# Thanks to talljimbo for the patch adding the 'LDVERSION' config -# variable usage. - -#============================================================================= -# Copyright 2001-2009 Kitware, Inc. -# Copyright 2012 Continuum Analytics, Inc. -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# * Neither the names of Kitware, Inc., the Insight Software Consortium, -# nor the names of their contributors may be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#============================================================================= - -if(PYTHONLIBS_FOUND) - return() -endif() - -# Use the Python interpreter to find the libs. -if(PythonLibsNew_FIND_REQUIRED) - find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} REQUIRED) -else() - find_package(PythonInterp ${PythonLibsNew_FIND_VERSION}) -endif() - -if(NOT PYTHONINTERP_FOUND) - set(PYTHONLIBS_FOUND FALSE) - return() -endif() - -# According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter -# testing whether sys has the gettotalrefcount function is a reliable, cross-platform -# way to detect a CPython debug interpreter. -# -# The library suffix is from the config var LDVERSION sometimes, otherwise -# VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows. -execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "from distutils import sysconfig as s;import sys;import struct; -print('.'.join(str(v) for v in sys.version_info)); -print(sys.prefix); -print(s.get_python_inc(plat_specific=True)); -print(s.get_python_lib(plat_specific=True)); -print(s.get_config_var('SO')); -print(hasattr(sys, 'gettotalrefcount')+0); -print(struct.calcsize('@P')); -print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION')); -print(s.get_config_var('LIBDIR') or ''); -print(s.get_config_var('MULTIARCH') or ''); -" - RESULT_VARIABLE _PYTHON_SUCCESS - OUTPUT_VARIABLE _PYTHON_VALUES - ERROR_VARIABLE _PYTHON_ERROR_VALUE) - -if(NOT _PYTHON_SUCCESS MATCHES 0) - if(PythonLibsNew_FIND_REQUIRED) - message(FATAL_ERROR - "Python config failure:\n${_PYTHON_ERROR_VALUE}") - endif() - set(PYTHONLIBS_FOUND FALSE) - return() -endif() - -# Convert the process output into a list -string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES}) -string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES}) -list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST) -list(GET _PYTHON_VALUES 1 PYTHON_PREFIX) -list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR) -list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES) -list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION) -list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG) -list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P) -list(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX) -list(GET _PYTHON_VALUES 8 PYTHON_LIBDIR) -list(GET _PYTHON_VALUES 9 PYTHON_MULTIARCH) - -# Make sure the Python has the same pointer-size as the chosen compiler -# Skip if CMAKE_SIZEOF_VOID_P is not defined -if(CMAKE_SIZEOF_VOID_P AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}")) - if(PythonLibsNew_FIND_REQUIRED) - math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8") - math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8") - message(FATAL_ERROR - "Python config failure: Python is ${_PYTHON_BITS}-bit, " - "chosen compiler is ${_CMAKE_BITS}-bit") - endif() - set(PYTHONLIBS_FOUND FALSE) - return() -endif() - -# The built-in FindPython didn't always give the version numbers -string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST}) -list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR) -list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR) -list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH) - -# Make sure all directory separators are '/' -string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX}) -string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR}) -string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES}) - -if(CMAKE_HOST_WIN32) - set(PYTHON_LIBRARY - "${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib") - - # when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the - # original python installation. They may be found relative to PYTHON_INCLUDE_DIR. - if(NOT EXISTS "${PYTHON_LIBRARY}") - get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY) - set(PYTHON_LIBRARY - "${_PYTHON_ROOT}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib") - endif() - - # raise an error if the python libs are still not found. - if(NOT EXISTS "${PYTHON_LIBRARY}") - message(FATAL_ERROR "Python libraries not found") - endif() - -else() - if(PYTHON_MULTIARCH) - set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}") - else() - set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}") - endif() - #message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}") - # Probably this needs to be more involved. It would be nice if the config - # information the python interpreter itself gave us were more complete. - find_library(PYTHON_LIBRARY - NAMES "python${PYTHON_LIBRARY_SUFFIX}" - PATHS ${_PYTHON_LIBS_SEARCH} - NO_DEFAULT_PATH) - - # If all else fails, just set the name/version and let the linker figure out the path. - if(NOT PYTHON_LIBRARY) - set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX}) - endif() -endif() - -MARK_AS_ADVANCED( - PYTHON_LIBRARY - PYTHON_INCLUDE_DIR -) - -# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the -# cache entries because they are meant to specify the location of a single -# library. We now set the variables listed by the documentation for this -# module. -SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") -SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") -SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}") - -find_package_message(PYTHON - "Found PythonLibs: ${PYTHON_LIBRARY}" - "${PYTHON_EXECUTABLE}${PYTHON_VERSION}") - -set(PYTHONLIBS_FOUND TRUE) diff --git a/stormpy/resources/pybind11/tools/check-style.sh b/stormpy/resources/pybind11/tools/check-style.sh deleted file mode 100755 index 44f4a0ca5..000000000 --- a/stormpy/resources/pybind11/tools/check-style.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# -# Script to check include/test code for common pybind11 code style errors. -# -# This script currently checks for -# -# 1. use of tabs instead of spaces -# 2. trailing spaces -# 3. missing space between keyword and parenthesis, e.g.: for(, if(, while( -# 4. opening brace on its own line. It should always be on the same line as the -# if/while/for/do statment. -# 5. Missing space between right parenthesis and brace, e.g. 'for (...){' -# -# Invoke as: tools/check-style.sh -# - -errors=0 -IFS=$'\n' -found= -# The mt=41 sets a red background for matched tabs: -exec 3< <(GREP_COLORS='mt=41' grep $'\t' include/ tests/*.{cpp,py,h} docs/*.rst -rn --color=always) -while read -u 3 f; do - if [ -z "$found" ]; then - echo -e '\e[31m\e[01mError: found tabs instead of spaces in the following files:\e[0m' - found=1 - errors=1 - fi - - echo " $f" -done - -found= -# The mt=41 sets a red background for matched trailing spaces -exec 3< <(GREP_COLORS='mt=41' grep '\s\+$' include/ tests/*.{cpp,py,h} docs/*.rst -rn --color=always) -while read -u 3 f; do - if [ -z "$found" ]; then - echo -e '\e[31m\e[01mError: found trailing spaces in the following files:\e[0m' - found=1 - errors=1 - fi - - echo " $f" -done - -found= -exec 3< <(GREP_COLORS='mt=41' grep '^\s*{\s*$' include/ docs/*.rst -rn --color=always) -while read -u 3 f; do - if [ -z "$found" ]; then - echo -e '\e[31m\e[01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files: \e[0m' - found=1 - errors=1 - fi - - echo " $f" -done - -found= -exec 3< <(grep '\<\(if\|for\|while\)(\|){' include/ tests/*.{cpp,py,h} -rn --color=always) -while read -u 3 line; do - if [ -z "$found" ]; then - echo -e '\e[31m\e[01mError: found the following coding style problems:\e[0m' - found=1 - errors=1 - fi - - echo " $line" -done - -exit $errors diff --git a/stormpy/resources/pybind11/tools/libsize.py b/stormpy/resources/pybind11/tools/libsize.py deleted file mode 100755 index 5dcb8b0d0..000000000 --- a/stormpy/resources/pybind11/tools/libsize.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import print_function, division -import os -import sys - -# Internal build script for generating debugging test .so size. -# Usage: -# python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the -# size in it, then overwrites save.txt with the new size for future runs. - -if len(sys.argv) != 3: - sys.exit("Invalid arguments: usage: python libsize.py file.so save.txt") - -lib = sys.argv[1] -save = sys.argv[2] - -if not os.path.exists(lib): - sys.exit("Error: requested file ({}) does not exist".format(lib)) - -libsize = os.path.getsize(lib) - -print("------", os.path.basename(lib), "file size:", libsize, end='') - -if os.path.exists(save): - with open(save) as sf: - oldsize = int(sf.readline()) - - if oldsize > 0: - change = libsize - oldsize - if change == 0: - print(" (no change)") - else: - print(" (change of {:+} bytes = {:+.2%})".format(change, change / oldsize)) -else: - print() - -with open(save, 'w') as sf: - sf.write(str(libsize)) - diff --git a/stormpy/resources/pybind11/tools/mkdoc.py b/stormpy/resources/pybind11/tools/mkdoc.py deleted file mode 100644 index 400fb05da..000000000 --- a/stormpy/resources/pybind11/tools/mkdoc.py +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env python3 -# -# Syntax: mkdoc.py [-I ..] [.. a list of header files ..] -# -# Extract documentation from C++ header files to use it in Python bindings -# - -import os -import sys -import platform -import re -import textwrap - -from clang import cindex -from clang.cindex import CursorKind -from collections import OrderedDict -from threading import Thread, Semaphore -from multiprocessing import cpu_count - -RECURSE_LIST = [ - CursorKind.TRANSLATION_UNIT, - CursorKind.NAMESPACE, - CursorKind.CLASS_DECL, - CursorKind.STRUCT_DECL, - CursorKind.ENUM_DECL, - CursorKind.CLASS_TEMPLATE -] - -PRINT_LIST = [ - CursorKind.CLASS_DECL, - CursorKind.STRUCT_DECL, - CursorKind.ENUM_DECL, - CursorKind.ENUM_CONSTANT_DECL, - CursorKind.CLASS_TEMPLATE, - CursorKind.FUNCTION_DECL, - CursorKind.FUNCTION_TEMPLATE, - CursorKind.CONVERSION_FUNCTION, - CursorKind.CXX_METHOD, - CursorKind.CONSTRUCTOR, - CursorKind.FIELD_DECL -] - -CPP_OPERATORS = { - '<=': 'le', '>=': 'ge', '==': 'eq', '!=': 'ne', '[]': 'array', - '+=': 'iadd', '-=': 'isub', '*=': 'imul', '/=': 'idiv', '%=': - 'imod', '&=': 'iand', '|=': 'ior', '^=': 'ixor', '<<=': 'ilshift', - '>>=': 'irshift', '++': 'inc', '--': 'dec', '<<': 'lshift', '>>': - 'rshift', '&&': 'land', '||': 'lor', '!': 'lnot', '~': 'bnot', - '&': 'band', '|': 'bor', '+': 'add', '-': 'sub', '*': 'mul', '/': - 'div', '%': 'mod', '<': 'lt', '>': 'gt', '=': 'assign', '()': 'call' -} - -CPP_OPERATORS = OrderedDict( - sorted(CPP_OPERATORS.items(), key=lambda t: -len(t[0]))) - -job_count = cpu_count() -job_semaphore = Semaphore(job_count) - -registered_names = dict() - - -def d(s): - return s.decode('utf8') - - -def sanitize_name(name): - global registered_names - name = re.sub(r'type-parameter-0-([0-9]+)', r'T\1', name) - for k, v in CPP_OPERATORS.items(): - name = name.replace('operator%s' % k, 'operator_%s' % v) - name = re.sub('<.*>', '', name) - name = ''.join([ch if ch.isalnum() else '_' for ch in name]) - name = re.sub('_$', '', re.sub('_+', '_', name)) - if name in registered_names: - registered_names[name] += 1 - name += '_' + str(registered_names[name]) - else: - registered_names[name] = 1 - return '__doc_' + name - - -def process_comment(comment): - result = '' - - # Remove C++ comment syntax - leading_spaces = float('inf') - for s in comment.expandtabs(tabsize=4).splitlines(): - s = s.strip() - if s.startswith('/*'): - s = s[2:].lstrip('*') - elif s.endswith('*/'): - s = s[:-2].rstrip('*') - elif s.startswith('///'): - s = s[3:] - if s.startswith('*'): - s = s[1:] - if len(s) > 0: - leading_spaces = min(leading_spaces, len(s) - len(s.lstrip())) - result += s + '\n' - - if leading_spaces != float('inf'): - result2 = "" - for s in result.splitlines(): - result2 += s[leading_spaces:] + '\n' - result = result2 - - # Doxygen tags - cpp_group = '([\w:]+)' - param_group = '([\[\w:\]]+)' - - s = result - s = re.sub(r'\\c\s+%s' % cpp_group, r'``\1``', s) - s = re.sub(r'\\a\s+%s' % cpp_group, r'*\1*', s) - s = re.sub(r'\\e\s+%s' % cpp_group, r'*\1*', s) - s = re.sub(r'\\em\s+%s' % cpp_group, r'*\1*', s) - s = re.sub(r'\\b\s+%s' % cpp_group, r'**\1**', s) - s = re.sub(r'\\ingroup\s+%s' % cpp_group, r'', s) - s = re.sub(r'\\param%s?\s+%s' % (param_group, cpp_group), - r'\n\n$Parameter ``\2``:\n\n', s) - s = re.sub(r'\\tparam%s?\s+%s' % (param_group, cpp_group), - r'\n\n$Template parameter ``\2``:\n\n', s) - - for in_, out_ in { - 'return': 'Returns', - 'author': 'Author', - 'authors': 'Authors', - 'copyright': 'Copyright', - 'date': 'Date', - 'remark': 'Remark', - 'sa': 'See also', - 'see': 'See also', - 'extends': 'Extends', - 'throw': 'Throws', - 'throws': 'Throws' - }.items(): - s = re.sub(r'\\%s\s*' % in_, r'\n\n$%s:\n\n' % out_, s) - - s = re.sub(r'\\details\s*', r'\n\n', s) - s = re.sub(r'\\brief\s*', r'', s) - s = re.sub(r'\\short\s*', r'', s) - s = re.sub(r'\\ref\s*', r'', s) - - s = re.sub(r'\\code\s?(.*?)\s?\\endcode', - r"```\n\1\n```\n", s, flags=re.DOTALL) - - # HTML/TeX tags - s = re.sub(r'(.*?)', r'``\1``', s, flags=re.DOTALL) - s = re.sub(r'
(.*?)
', r"```\n\1\n```\n", s, flags=re.DOTALL) - s = re.sub(r'(.*?)', r'*\1*', s, flags=re.DOTALL) - s = re.sub(r'(.*?)', r'**\1**', s, flags=re.DOTALL) - s = re.sub(r'\\f\$(.*?)\\f\$', r'$\1$', s, flags=re.DOTALL) - s = re.sub(r'
  • ', r'\n\n* ', s) - s = re.sub(r'', r'', s) - s = re.sub(r'
  • ', r'\n\n', s) - - s = s.replace('``true``', '``True``') - s = s.replace('``false``', '``False``') - - # Re-flow text - wrapper = textwrap.TextWrapper() - wrapper.expand_tabs = True - wrapper.replace_whitespace = True - wrapper.drop_whitespace = True - wrapper.width = 70 - wrapper.initial_indent = wrapper.subsequent_indent = '' - - result = '' - in_code_segment = False - for x in re.split(r'(```)', s): - if x == '```': - if not in_code_segment: - result += '```\n' - else: - result += '\n```\n\n' - in_code_segment = not in_code_segment - elif in_code_segment: - result += x.strip() - else: - for y in re.split(r'(?: *\n *){2,}', x): - wrapped = wrapper.fill(re.sub(r'\s+', ' ', y).strip()) - if len(wrapped) > 0 and wrapped[0] == '$': - result += wrapped[1:] + '\n' - wrapper.initial_indent = \ - wrapper.subsequent_indent = ' ' * 4 - else: - if len(wrapped) > 0: - result += wrapped + '\n\n' - wrapper.initial_indent = wrapper.subsequent_indent = '' - return result.rstrip().lstrip('\n') - - -def extract(filename, node, prefix, output): - num_extracted = 0 - if not (node.location.file is None or - os.path.samefile(d(node.location.file.name), filename)): - return 0 - if node.kind in RECURSE_LIST: - sub_prefix = prefix - if node.kind != CursorKind.TRANSLATION_UNIT: - if len(sub_prefix) > 0: - sub_prefix += '_' - sub_prefix += d(node.spelling) - for i in node.get_children(): - num_extracted += extract(filename, i, sub_prefix, output) - if num_extracted == 0: - return 0 - if node.kind in PRINT_LIST: - comment = d(node.raw_comment) if node.raw_comment is not None else '' - comment = process_comment(comment) - sub_prefix = prefix - if len(sub_prefix) > 0: - sub_prefix += '_' - if len(node.spelling) > 0: - name = sanitize_name(sub_prefix + d(node.spelling)) - output.append('\nstatic const char *%s =%sR"doc(%s)doc";' % - (name, '\n' if '\n' in comment else ' ', comment)) - num_extracted += 1 - return num_extracted - - -class ExtractionThread(Thread): - def __init__(self, filename, parameters, output): - Thread.__init__(self) - self.filename = filename - self.parameters = parameters - self.output = output - job_semaphore.acquire() - - def run(self): - print('Processing "%s" ..' % self.filename, file=sys.stderr) - try: - index = cindex.Index( - cindex.conf.lib.clang_createIndex(False, True)) - tu = index.parse(self.filename, self.parameters) - extract(self.filename, tu.cursor, '', self.output) - finally: - job_semaphore.release() - -if __name__ == '__main__': - parameters = ['-x', 'c++', '-std=c++11'] - filenames = [] - - if platform.system() == 'Darwin': - dev_path = '/Applications/Xcode.app/Contents/Developer/' - lib_dir = dev_path + 'Toolchains/XcodeDefault.xctoolchain/usr/lib/' - sdk_dir = dev_path + 'Platforms/MacOSX.platform/Developer/SDKs' - libclang = lib_dir + 'libclang.dylib' - - if os.path.exists(libclang): - cindex.Config.set_library_path(os.path.dirname(libclang)) - - if os.path.exists(sdk_dir): - sysroot_dir = os.path.join(sdk_dir, next(os.walk(sdk_dir))[1][0]) - parameters.append('-isysroot') - parameters.append(sysroot_dir) - - for item in sys.argv[1:]: - if item.startswith('-'): - parameters.append(item) - else: - filenames.append(item) - - if len(filenames) == 0: - print('Syntax: %s [.. a list of header files ..]' % sys.argv[0]) - exit(-1) - - print('''/* - This file contains docstrings for the Python bindings. - Do not edit! These were automatically extracted by mkdoc.py - */ - -#define __EXPAND(x) x -#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT -#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) -#define __CAT1(a, b) a ## b -#define __CAT2(a, b) __CAT1(a, b) -#define __DOC1(n1) __doc_##n1 -#define __DOC2(n1, n2) __doc_##n1##_##n2 -#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 -#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 -#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 -#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 -#define __DOC7(n1, n2, n3, n4, n5, n6, n7) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 -#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) - -#if defined(__GNUG__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif -''') - - output = [] - for filename in filenames: - thr = ExtractionThread(filename, parameters, output) - thr.start() - - print('Waiting for jobs to finish ..', file=sys.stderr) - for i in range(job_count): - job_semaphore.acquire() - - output.sort() - for l in output: - print(l) - - print(''' -#if defined(__GNUG__) -#pragma GCC diagnostic pop -#endif -''') diff --git a/stormpy/setup.cfg.in b/stormpy/setup.cfg.in deleted file mode 100644 index b40a9a08e..000000000 --- a/stormpy/setup.cfg.in +++ /dev/null @@ -1,6 +0,0 @@ -[build_ext] -compile_flags=@STORMPY_COMPILE_ARGS@ -use-cln=@STORMPY_USE_CLN@ -include_dirs=@STORMPY_INCLUDE_DIRS@ -library_dirs=@STORMPY_LIBRARY_DIRS@ -rpath=@STORMPY_RPATH@ diff --git a/stormpy/setup.py b/stormpy/setup.py deleted file mode 100755 index 1797dfd84..000000000 --- a/stormpy/setup.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -import os -import re -import sys -import platform -import subprocess - -from setuptools import setup, Extension -from setuptools.command.build_ext import build_ext -from distutils.version import LooseVersion - - -class CMakeExtension(Extension): - def __init__(self, name, sourcedir=''): - Extension.__init__(self, name, sources=[]) - self.sourcedir = os.path.abspath(sourcedir) - - -class CMakeBuild(build_ext): - def run(self): - try: - out = subprocess.check_output(['cmake', '--version']) - except OSError: - raise RuntimeError("CMake must be installed to build the following extensions: " + - ", ".join(e.name for e in self.extensions)) - - for ext in self.extensions: - self.build_extension(ext) - - - def build_extension(self, ext): - extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) - cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, - '-DPYTHON_EXECUTABLE=' + sys.executable] - - cfg = 'Debug' if self.debug else 'Release' - build_args = ['--config', cfg] - - - cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] - build_args += ['--', '-j2'] - - env = os.environ.copy() - env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(env.get('CXXFLAGS', ''), - self.distribution.get_version()) - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env) - try: - subprocess.check_call(['cmake', '--build', '.', '--target', ext.name] + build_args, cwd=self.build_temp) - except subprocess.CalledProcessError as e: - if e.output: - raise RuntimeError("CMake build returned with an error: " + e.output) - - print(e.stdout) - -setup( - name="stormpy", - version="0.9", - author="M. Volk", - author_email="matthias.volk@cs.rwth-aachen.de", - maintainer="S. Junges", - maintainer_email="sebastian.junges@cs.rwth-aachen.de", - url="http://moves.rwth-aachen.de", - description="stormpy - Python Bindings for Storm", - packages=['stormpy', 'stormpy.info', 'stormpy.expressions', 'stormpy.logic', 'stormpy.storage'], - package_dir={'':'lib'}, - ext_package='stormpy', - ext_modules=[CMakeExtension('stormpy.core'), CMakeExtension('stormpy.info'),CMakeExtension('stormpy.expressions'), CMakeExtension('stormpy.logic'), CMakeExtension('stormpy.storage')], - cmdclass=dict(build_ext=CMakeBuild), - zip_safe=False -) diff --git a/stormpy/src/CMakeLists.txt b/stormpy/src/CMakeLists.txt deleted file mode 100644 index 9882d8a91..000000000 --- a/stormpy/src/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -# This is a CMake example for Python - -INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src ${stormpy_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(${pybind11_incdir}) - -FILE(GLOB core_files "core/*.cpp") -#FILE(GLOB info_files "info/*.cpp") -#FILE(GLOB expressions_files "expressions/*.cpp") -FILE(GLOB storage_files "storage/*.cpp") -FILE(GLOB logic_files "logic/*.cpp") -ADD_LIBRARY(stormpy_core SHARED mod_core.cpp ${core_files}) -ADD_LIBRARY(stormpy_info SHARED mod_info.cpp) -ADD_LIBRARY(stormpy_expressions SHARED mod_expressions.cpp) -ADD_LIBRARY(stormpy_storage SHARED mod_storage.cpp ${storage_files}) -ADD_LIBRARY(stormpy_logic SHARED mod_logic.cpp ${logic_files}) - -SET_TARGET_PROPERTIES(stormpy_core PROPERTIES - OUTPUT_NAME core - PREFIX "" - SUFFIX ".so" - LIBRARY_OUTPUT_DIRECTORY ${STORMPY_OUTPUT_DIR}/ -) - -SET_TARGET_PROPERTIES(stormpy_info PROPERTIES - OUTPUT_NAME info - PREFIX "" - SUFFIX ".so" - LIBRARY_OUTPUT_DIRECTORY ${STORMPY_OUTPUT_DIR}/info -) - -SET_TARGET_PROPERTIES(stormpy_expressions PROPERTIES - OUTPUT_NAME expressions - PREFIX "" - SUFFIX ".so" - LIBRARY_OUTPUT_DIRECTORY ${STORMPY_OUTPUT_DIR}/expressions -) - -SET_TARGET_PROPERTIES(stormpy_storage PROPERTIES - OUTPUT_NAME storage - PREFIX "" - SUFFIX ".so" - LIBRARY_OUTPUT_DIRECTORY ${STORMPY_OUTPUT_DIR}/storage -) - -SET_TARGET_PROPERTIES(stormpy_logic PROPERTIES - OUTPUT_NAME logic - PREFIX "" - SUFFIX ".so" - LIBRARY_OUTPUT_DIRECTORY ${STORMPY_OUTPUT_DIR}/logic -) - -TARGET_LINK_LIBRARIES(stormpy_core storm ${PYTHON_LIBRARIES}) -TARGET_LINK_LIBRARIES(stormpy_info storm ${PYTHON_LIBRARIES}) -TARGET_LINK_LIBRARIES(stormpy_expressions storm ${PYTHON_LIBRARIES}) -TARGET_LINK_LIBRARIES(stormpy_storage storm ${PYTHON_LIBRARIES}) -TARGET_LINK_LIBRARIES(stormpy_logic storm ${PYTHON_LIBRARIES}) diff --git a/stormpy/src/common.h b/stormpy/src/common.h deleted file mode 100644 index e81b41784..000000000 --- a/stormpy/src/common.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * common.h - * - * Created on: 15 Apr 2016 - * Author: hbruintjes - */ - -#pragma once - -#include -#include -#include -#include - -namespace py = pybind11; - -#if PY_MAJOR_VERSION >= 3 -#define PY_DIV "__truediv__" -#define PY_RDIV "__rtruediv__" -#else -#define PY_DIV "__div__" -#define PY_RDIV "__rdiv__" -#endif - -PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr) -PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr) - -namespace pybind11 { -namespace detail { -/** - * Dummy type caster for handle, so functions can return pybind11 handles directly - */ -/*template <> class type_caster { -public: - bool load(handle src, bool) { - value = handle(src).inc_ref(); - return true; - } - - static handle cast(handle src, return_value_policy policy, handle parent) { - switch(policy) { - case return_value_policy::automatic: - case return_value_policy::copy: - case return_value_policy::take_ownership: - return handle(src); - case return_value_policy::reference: - return handle(src).inc_ref(); - case return_value_policy::reference_internal: - parent.inc_ref(); - return handle(src); - } - return handle(src); - } - PYBIND11_TYPE_CASTER(handle, _("handle")); -};*/ -/* -template struct tuple_caster { - typedef TupleType type; - template - using type_conv = type_caster::type>; - - bool load(handle src, bool convert) { - pybind11::tuple tup(src, true); - if (!tup.check()) - return false; - - return loadItem<0, Keys...>(tup, convert); - } - - static handle cast(const type &src, return_value_policy policy, handle parent) { - pybind11::tuple tup(sizeof...(Keys)); - if (!castItem<0, Keys...>(tup, src, policy, parent)) { - return handle(); - } - - return tup.release(); - } - -private: - template - bool loadItem(pybind11::tuple& tup, bool convert) { - type_conv conv; - if (!conv.load(tup[N], convert)) - return false; - std::get(value) = static_cast(conv); - return loadItem(tup, convert); - } - - template - bool loadItem(pybind11::tuple& tup, bool convert) { - type_conv conv; - if (!conv.load(tup[N], convert)) - return false; - std::get(value) = static_cast(conv); - return true; - } - - template - static bool castItem(pybind11::tuple& tup, const type &src, return_value_policy policy, handle parent) { - auto obj = type_conv::cast(std::get(src), policy, parent); - object value_ = object(obj, false); - if (!obj) { - return false; - } - return castItem(tup, src, policy, parent); - } - - template - static bool castItem(pybind11::tuple& tu, const type &src, return_value_policy policy, handle parent) { - auto obj = type_conv::cast(std::get(src), policy, parent); - object value_ = object(obj, false); - if (!obj) { - return false; - } - return true; - } -}; - -template struct type_caster> - : tuple_caster, Types...> { }; - -template struct type_caster> - : tuple_caster, Type1, Type2> { }; -*/ - -} -} diff --git a/stormpy/src/core/bisimulation.cpp b/stormpy/src/core/bisimulation.cpp deleted file mode 100644 index 3eafc80d0..000000000 --- a/stormpy/src/core/bisimulation.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "bisimulation.h" - -// Thin wrapper for bisimulation -template -std::shared_ptr> performBisimulation(std::shared_ptr> const& model, std::shared_ptr const& formula, storm::storage::BisimulationType bisimulationType) { - return storm::performBisimulationMinimization>(model, formula, bisimulationType); -} - -// Define python bindings -void define_bisimulation(py::module& m) { - - // Bisimulation - m.def("_perform_bisimulation", &performBisimulation, "Perform bisimulation", py::arg("model"), py::arg("formula"), py::arg("bisimulation_type")); - m.def("_perform_parametric_bisimulation", &performBisimulation, "Perform bisimulation on parametric model", py::arg("model"), py::arg("formula"), py::arg("bisimulation_type")); - - // BisimulationType - py::enum_(m, "BisimulationType", "Types of bisimulation") - .value("STRONG", storm::storage::BisimulationType::Strong) - .value("WEAK", storm::storage::BisimulationType::Weak) - ; - -} diff --git a/stormpy/src/core/bisimulation.h b/stormpy/src/core/bisimulation.h deleted file mode 100644 index d444f40e9..000000000 --- a/stormpy/src/core/bisimulation.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PYTHON_CORE_BISIMULATION_H_ -#define PYTHON_CORE_BISIMULATION_H_ - -#include "common.h" - -void define_bisimulation(py::module& m); - -#endif /* PYTHON_CORE_BISIMULATION_H_ */ diff --git a/stormpy/src/core/common.h b/stormpy/src/core/common.h deleted file mode 100644 index e8466b2bd..000000000 --- a/stormpy/src/core/common.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "src/common.h" -#include "storm/utility/storm.h" -#include diff --git a/stormpy/src/core/core.cpp b/stormpy/src/core/core.cpp deleted file mode 100644 index 98d74dc80..000000000 --- a/stormpy/src/core/core.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "core.h" - -void define_core(py::module& m) { - // Init - m.def("set_up", [](std::string const& args) { - storm::utility::setUp(); - storm::settings::initializeAll("StoRM-Py", "stormpy"); - storm::settings::SettingsManager::manager().setFromString(args); - }, "Initialize Storm", py::arg("arguments")); -} - -void define_parse(py::module& m) { - // Parse formulas - m.def("parse_formulas", &storm::parseFormulasForExplicit, "Parse explicit formulas", py::arg("formula_string")); - m.def("parse_formulas_for_prism_program", &storm::parseFormulasForPrismProgram, "Parse formulas for prism program", py::arg("formula_string"), py::arg("prism_program")); - - // Pair - py::class_(m, "ModelFormulasPair", "Pair of model and formulas") - .def_property_readonly("model", [](storm::storage::ModelFormulasPair const& pair) { - return pair.model; - }, "The model") - .def_property_readonly("formulas", [](storm::storage::ModelFormulasPair const& pair) { - return pair.formulas; - }, "The formulas") - ; - - // Parse explicit models - m.def("parse_explicit_model", &storm::parser::AutoParser<>::parseModel, "Parse explicit model", py::arg("transition_file"), py::arg("labeling_file"), py::arg("state_reward_file") = "", py::arg("transition_reward_file") = "", py::arg("choice_labeling_file") = ""); -} - -// Thin wrapper for model building using one formula as argument -template -std::shared_ptr buildModel(storm::prism::Program const& program, std::shared_ptr const& formula) { - return storm::buildSymbolicModel(program, std::vector>(1,formula)); -} - -template -std::shared_ptr buildSparseModel(storm::prism::Program const& program, std::shared_ptr const& formula, bool onlyInitialStatesRelevant = false) { - return storm::buildSparseModel(program, std::vector>(1,formula), onlyInitialStatesRelevant); -} - -void define_build(py::module& m) { - // Build model - m.def("_build_model", &buildSparseModel, "Build the model", py::arg("program"), py::arg("formula"), py::arg("onlyInitialRelevant") = false); - m.def("_build_parametric_model", &buildSparseModel, "Build the parametric model", py::arg("program"), py::arg("formula"), py::arg("onlyInitialRelevant") = false); - m.def("build_model_from_prism_program", &storm::buildSparseModel, "Build the model", py::arg("program"), py::arg("formulas"), py::arg("onlyInitialRelevant") = false); - m.def("build_parametric_model_from_prism_program", &storm::buildSparseModel, "Build the parametric model", py::arg("program"), py::arg("formulas"), py::arg("onlyInitialRelevant") = false); - -} diff --git a/stormpy/src/core/core.h b/stormpy/src/core/core.h deleted file mode 100644 index ee3b3be7a..000000000 --- a/stormpy/src/core/core.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef PYTHON_CORE_CORE_H_ -#define PYTHON_CORE_CORE_H_ - -#include "common.h" - -void define_core(py::module& m); -void define_parse(py::module& m); -void define_build(py::module& m); - -#endif /* PYTHON_CORE_CORE_H_ */ diff --git a/stormpy/src/core/input.cpp b/stormpy/src/core/input.cpp deleted file mode 100644 index 8c9f915e4..000000000 --- a/stormpy/src/core/input.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "input.h" - -// Define python bindings -void define_input(py::module& m) { - - // Parse prism program - m.def("parse_prism_program", &storm::parseProgram, "Parse prism program", py::arg("path")); - - // PrismType - py::enum_(m, "PrismModelType", "Type of the prism model") - .value("DTMC", storm::prism::Program::ModelType::DTMC) - .value("CTMC", storm::prism::Program::ModelType::CTMC) - .value("MDP", storm::prism::Program::ModelType::MDP) - .value("CTMDP", storm::prism::Program::ModelType::CTMDP) - .value("MA", storm::prism::Program::ModelType::MA) - .value("UNDEFINED", storm::prism::Program::ModelType::UNDEFINED) - ; - - // PrismProgram - py::class_(m, "PrismProgram", "Prism program") - .def_property_readonly("nr_modules", &storm::prism::Program::getNumberOfModules, "Number of modules") - .def_property_readonly("model_type", &storm::prism::Program::getModelType, "Model type") - .def_property_readonly("has_undefined_constants", &storm::prism::Program::hasUndefinedConstants, "Flag if program has undefined constants") - ; - - // SymbolicModelDescription - py::class_(m, "SymbolicModelDescription", "Symbolic description of model") - .def(py::init(), "Construct from Prism program", py::arg("prism_program")) - .def_property_readonly("is_prism_program", &storm::storage::SymbolicModelDescription::isPrismProgram, "Flag if program is in Prism format") - ; - - // PrismProgram can be converted into SymbolicModelDescription - py::implicitly_convertible(); -} diff --git a/stormpy/src/core/input.h b/stormpy/src/core/input.h deleted file mode 100644 index 304dc9a9f..000000000 --- a/stormpy/src/core/input.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PYTHON_CORE_INPUT_H_ -#define PYTHON_CORE_INPUT_H_ - -#include "common.h" - -void define_input(py::module& m); - -#endif /* PYTHON_CORE_INPUT_H_ */ diff --git a/stormpy/src/core/modelchecking.cpp b/stormpy/src/core/modelchecking.cpp deleted file mode 100644 index dd00a281b..000000000 --- a/stormpy/src/core/modelchecking.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "modelchecking.h" - -// Class holding the model checking result -class PmcResult { - public: - storm::RationalFunction resultFunction; - std::unordered_set> constraintsWellFormed; - std::unordered_set> constraintsGraphPreserving; - - storm::RationalFunction getResultFunction() const { - return resultFunction; - } - - std::unordered_set> getConstraintsWellFormed() const { - return constraintsWellFormed; - } - - std::unordered_set> getConstraintsGraphPreserving() const { - return constraintsGraphPreserving; - } - - std::string toString() { - std::stringstream stream; - stream << resultFunction << std::endl; - stream << "Well formed constraints:" << std::endl; - for (auto constraint : constraintsWellFormed) { - stream << constraint << std::endl; - } - stream << "Graph preserving constraints:" << std::endl; - for (auto constraint : constraintsGraphPreserving) { - stream << constraint << std::endl; - } - return stream.str(); - } -}; - -// Thin wrapper for model checking -double modelChecking(std::shared_ptr> model, std::shared_ptr const& formula) { - std::unique_ptr checkResult = storm::verifySparseModel(model, formula); - return checkResult->asExplicitQuantitativeCheckResult()[*model->getInitialStates().begin()]; -} - -// Thin wrapper for model checking for all states -std::vector modelCheckingAll(std::shared_ptr> model, std::shared_ptr const& formula) { - std::unique_ptr checkResult = storm::verifySparseModel(model, formula); - return checkResult->asExplicitQuantitativeCheckResult().getValueVector(); -} - -// Thin wrapper for parametric model checking -std::shared_ptr parametricModelChecking(std::shared_ptr> model, std::shared_ptr const& formula) { - std::unique_ptr checkResult = storm::verifySparseModel(model, formula); - std::shared_ptr result = std::make_shared(); - result->resultFunction = checkResult->asExplicitQuantitativeCheckResult()[*model->getInitialStates().begin()]; - storm::models::sparse::Dtmc::ConstraintCollector constraintCollector(*(model->template as>())); - result->constraintsWellFormed = constraintCollector.getWellformedConstraints(); - result->constraintsGraphPreserving = constraintCollector.getGraphPreservingConstraints(); - return result; -} - -// Define python bindings -void define_modelchecking(py::module& m) { - - // Model checking - m.def("_model_checking", &modelChecking, "Perform model checking", py::arg("model"), py::arg("formula")); - m.def("model_checking_all", &modelCheckingAll, "Perform model checking for all states", py::arg("model"), py::arg("formula")); - m.def("_parametric_model_checking", ¶metricModelChecking, "Perform parametric model checking", py::arg("model"), py::arg("formula")); - - // PmcResult - py::class_>(m, "PmcResult", "Holds the results after parametric model checking") - .def("__str__", &PmcResult::toString) - .def_property_readonly("result_function", &PmcResult::getResultFunction, "Result as rational function") - .def_property_readonly("constraints_well_formed", &PmcResult::getConstraintsWellFormed, "Constraints ensuring well-formed probabilities") - .def_property_readonly("constraints_graph_preserving", &PmcResult::getConstraintsGraphPreserving, "Constraints ensuring graph preservation") - ; - -} diff --git a/stormpy/src/core/modelchecking.h b/stormpy/src/core/modelchecking.h deleted file mode 100644 index 06b1aad3c..000000000 --- a/stormpy/src/core/modelchecking.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PYTHON_CORE_MODELCHECKING_H_ -#define PYTHON_CORE_MODELCHECKING_H_ - -#include "common.h" - -void define_modelchecking(py::module& m); - -#endif /* PYTHON_CORE_MODELCHECKING_H_ */ diff --git a/stormpy/src/helpers.h b/stormpy/src/helpers.h deleted file mode 100644 index ffda72c19..000000000 --- a/stormpy/src/helpers.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * helpers.h - * - * Created on: 16 Apr 2016 - * Author: harold - */ - -#ifndef PYTHON_HELPERS_H_ -#define PYTHON_HELPERS_H_ - -#include -#include - -/** - * Helper function to get a string out of the stream operator. - * Used for __str__ functions. - */ -template -std::string streamToString(T const & t) { - std::stringstream ss; - ss << t; - return ss.str(); -} - -// Be warned: Enabling something like this will break everything about Monomial, -// as to Python the shared_ptr (Arg) IS the Monomial -// //PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); - -#endif /* PYTHON_HELPERS_H_ */ diff --git a/stormpy/src/logic/formulae.cpp b/stormpy/src/logic/formulae.cpp deleted file mode 100644 index f6c892dfd..000000000 --- a/stormpy/src/logic/formulae.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "formulae.h" -#include "storm/logic/Formulas.h" - -void define_formulae(py::module& m) { - - py::enum_(m, "ComparisonType") - .value("LESS", storm::logic::ComparisonType::Less) - .value("LEQ", storm::logic::ComparisonType::LessEqual) - .value("GREATER", storm::logic::ComparisonType::Greater) - .value("GEQ", storm::logic::ComparisonType::GreaterEqual) - ; - - /*py::class_>, void, void>("FormulaVec", "Vector of formulas") - .def(vector_indexing_suite>, true>()) - ;*/ - - py::class_>(m, "Formula", "Generic Storm Formula") - .def("__str__", &storm::logic::Formula::toString) - ; - - // Path Formulae - py::class_>(m, "PathFormula", "Formula about the probability of a set of paths in an automaton", py::base()); - py::class_>(m, "UnaryPathFormula", "Path formula with one operand", py::base()); - py::class_>(m, "EventuallyFormula", "Formula for eventually", py::base()); - py::class_>(m, "GloballyFormula", "Formula for globally", py::base()); - py::class_>(m, "BinaryPathFormula", "Path formula with two operands", py::base()); - py::class_>(m, "BoundedUntilFormula", "Until Formula with either a step or a time bound.", py::base()); - py::class_>(m, "ConditionalFormula", "Formula with the right hand side being a condition.", py::base()); - py::class_>(m, "UntilFormula", "Path Formula for unbounded until", py::base()); - - // Reward Path Formulae - //py::class_(m, "RewardPathFormula", "Formula about the rewards of a set of paths in an automaton", py::base()); - py::class_>(m, "CumulativeRewardFormula", "Summed rewards over a the paths", py::base()); - py::class_>(m ,"InstantaneousRewardFormula", "Instantaneous reward", py::base()); - py::class_>(m, "LongRunAverageRewardFormula", "Long run average reward", py::base()); - //py::class_>(m, "ReachabilityRewardFormula", "Reachability reward", py::base()); - - - // State Formulae - py::class_>(m, "StateFormula", "Formula about a state of an automaton", py::base()); - py::class_>(m, "AtomicExpressionFormula", "Formula with an atomic expression", py::base()); - py::class_>(m, "AtomicLabelFormula", "Formula with an atomic label", py::base()); - py::class_>(m, "BooleanLiteralFormula", "Formula with a boolean literal", py::base()); - py::class_>(m, "UnaryStateFormula", "State formula with one operand", py::base()); - py::class_>(m, "UnaryBooleanStateFormula", "Unary boolean state formula", py::base()); - py::class_>(m, "OperatorFormula", "Operator formula", py::base()) - .def_property_readonly("has_bound", &storm::logic::OperatorFormula::hasBound, "Flag if formula is bounded") - .def_property("threshold", &storm::logic::OperatorFormula::getThreshold, &storm::logic::OperatorFormula::setThreshold, "Threshold of bound") - .def_property("comparison_type", &storm::logic::OperatorFormula::getComparisonType, &storm::logic::OperatorFormula::setComparisonType, "Comparison type of bound") - ; - py::class_>(m, "TimeOperator", "The time operator", py::base()); - py::class_>(m, "LongRunAvarageOperator", "Long run average operator", py::base()); - py::class_>(m, "ProbabilityOperator", "Probability operator", py::base()); - py::class_>(m, "RewardOperator", "Reward operator", py::base()); - py::class_>(m, "BinaryStateFormula", "State formula with two operands", py::base()); - py::class_>(m, "BooleanBinaryStateFormula", "Boolean binary state formula", py::base()); -} diff --git a/stormpy/src/logic/formulae.h b/stormpy/src/logic/formulae.h deleted file mode 100644 index d499685e7..000000000 --- a/stormpy/src/logic/formulae.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PYTHON_LOGIC_FORMULAE_H_ -#define PYTHON_LOGIC_FORMULAE_H_ - -#include "src/common.h" - -void define_formulae(py::module& m); - -#endif /* PYTHON_LOGIC_FORMULAE_H_ */ diff --git a/stormpy/src/mod_core.cpp b/stormpy/src/mod_core.cpp deleted file mode 100644 index b008e40d0..000000000 --- a/stormpy/src/mod_core.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "common.h" - -#include "core/core.h" -#include "core/modelchecking.h" -#include "core/bisimulation.h" -#include "core/input.h" - -PYBIND11_PLUGIN(core) { - py::module m("core"); - define_core(m); - define_parse(m); - define_build(m); - define_modelchecking(m); - define_bisimulation(m); - define_input(m); - return m.ptr(); -} diff --git a/stormpy/src/mod_expressions.cpp b/stormpy/src/mod_expressions.cpp deleted file mode 100644 index ef89106c8..000000000 --- a/stormpy/src/mod_expressions.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "common.h" -#include "helpers.h" -#include "storm/storage/expressions/ExpressionManager.h" - -PYBIND11_PLUGIN(expressions) { - py::module m("expressions", "Storm expressions"); - - py::class_>(m, "ExpressionManager", "Manages variables for expressions") - ; - - py::class_(m, "Expression", "Holds an expression") - .def("__str__", &storm::expressions::Expression::toString) - .def_property_readonly("contains_variables", &storm::expressions::Expression::containsVariables) - .def_property_readonly("has_boolean_type", &storm::expressions::Expression::hasBooleanType) - .def_property_readonly("has_integer_type", &storm::expressions::Expression::hasIntegerType) - .def_property_readonly("has_rational_type", &storm::expressions::Expression::hasRationalType) - - ; - - return m.ptr(); -} diff --git a/stormpy/src/mod_info.cpp b/stormpy/src/mod_info.cpp deleted file mode 100644 index 427b1f893..000000000 --- a/stormpy/src/mod_info.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "common.h" -#include "helpers.h" -#include "storm/utility/storm-version.h" - -PYBIND11_PLUGIN(info) { - py::module m("info", "Storm information"); - py::class_(m, "Version", "Version information for Storm") - .def_property_readonly("short", &storm::utility::StormVersion::shortVersionString, "Storm version in short representation") - .def_property_readonly("long", &storm::utility::StormVersion::longVersionString, "Storm version in long representation") - .def_property_readonly("build_info", &storm::utility::StormVersion::buildInfo, "Build info for Storm") - ; - return m.ptr(); -} diff --git a/stormpy/src/mod_logic.cpp b/stormpy/src/mod_logic.cpp deleted file mode 100644 index 98fcad102..000000000 --- a/stormpy/src/mod_logic.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "common.h" - -#include "logic/formulae.h" - -PYBIND11_PLUGIN(logic) { - py::module m("logic", "Logic module for Storm"); - define_formulae(m); - return m.ptr(); -} diff --git a/stormpy/src/mod_storage.cpp b/stormpy/src/mod_storage.cpp deleted file mode 100644 index 835f1e7b2..000000000 --- a/stormpy/src/mod_storage.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "common.h" - -#include "storage/model.h" -#include "storage/matrix.h" - -PYBIND11_PLUGIN(storage) { - py::module m("storage"); - define_model(m); - define_sparse_matrix(m); - return m.ptr(); -} diff --git a/stormpy/src/storage/common.h b/stormpy/src/storage/common.h deleted file mode 100644 index c9b9b0cb4..000000000 --- a/stormpy/src/storage/common.h +++ /dev/null @@ -1 +0,0 @@ -#include "src/common.h" diff --git a/stormpy/src/storage/matrix.cpp b/stormpy/src/storage/matrix.cpp deleted file mode 100644 index 887a86621..000000000 --- a/stormpy/src/storage/matrix.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "matrix.h" -#include "storm/storage/SparseMatrix.h" - -typedef storm::storage::SparseMatrix::index_type entry_index; -typedef unsigned int row_index; -typedef storm::storage::SparseMatrix::index_type parametric_entry_index; -typedef unsigned int parametric_row_index; - -void define_sparse_matrix(py::module& m) { - - // MatrixEntry - py::class_>(m, "SparseMatrixEntry", "Entry of sparse matrix") - .def("__str__", [](storm::storage::MatrixEntry const& entry) { - std::stringstream stream; - stream << entry; - return stream.str(); - }) - //def_property threw "pointer being freed not allocated" after exiting - .def("value", &storm::storage::MatrixEntry::getValue, "Value") - .def("set_value", &storm::storage::MatrixEntry::setValue, py::arg("value"), "Set value") - .def_property_readonly("column", &storm::storage::MatrixEntry::getColumn, "Column") - ; - - py::class_>(m, "ParametricSparseMatrixEntry", "Entry of parametric sparse matrix") - .def("__str__", [](storm::storage::MatrixEntry const& entry) { - std::stringstream stream; - stream << entry; - return stream.str(); - }) - //def_property threw "pointer being freed not allocated" after exiting - .def("value", &storm::storage::MatrixEntry::getValue, "Value") - .def("set_value", &storm::storage::MatrixEntry::setValue, py::arg("value"), "Set value") - .def_property_readonly("column", &storm::storage::MatrixEntry::getColumn, "Column") - ; - - // SparseMatrix - py::class_>(m, "SparseMatrix", "Sparse matrix") - .def("__iter__", [](storm::storage::SparseMatrix& matrix) { - return py::make_iterator(matrix.begin(), matrix.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def("__str__", [](storm::storage::SparseMatrix const& matrix) { - std::stringstream stream; - stream << matrix; - return stream.str(); - }) - .def_property_readonly("nr_rows", &storm::storage::SparseMatrix::getRowCount, "Number of rows") - .def_property_readonly("nr_columns", &storm::storage::SparseMatrix::getColumnCount, "Number of columns") - .def_property_readonly("nr_entries", &storm::storage::SparseMatrix::getEntryCount, "Number of non-zero entries") - .def_property_readonly("_row_group_indices", &storm::storage::SparseMatrix::getRowGroupIndices, "Starting rows of row groups") - .def("get_row", [](storm::storage::SparseMatrix& matrix, entry_index row) { - return matrix.getRows(row, row+1); - }, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row"), "Get row") - .def("get_rows", [](storm::storage::SparseMatrix& matrix, entry_index start, entry_index end) { - return matrix.getRows(start, end); - }, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row_start"), py::arg("row_end"), "Get rows from start to end") - .def("print_row", [](storm::storage::SparseMatrix const& matrix, entry_index row) { - std::stringstream stream; - auto rows = matrix.getRows(row, row+1); - for (auto transition : rows) { - stream << transition << ", "; - } - return stream.str(); - }, py::arg("row"), "Print row") - // Entry_index lead to problems - .def("row_iter", [](storm::storage::SparseMatrix& matrix, row_index start, row_index end) { - return py::make_iterator(matrix.begin(start), matrix.end(end)); - }, py::keep_alive<0, 1>() /* keep object alive while iterator exists */, py::arg("row_start"), py::arg("row_end"), "Get iterator from start to end") - ; - - py::class_>(m, "ParametricSparseMatrix", "Parametric sparse matrix") - .def("__iter__", [](storm::storage::SparseMatrix& matrix) { - return py::make_iterator(matrix.begin(), matrix.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def("__str__", [](storm::storage::SparseMatrix const& matrix) { - std::stringstream stream; - stream << matrix; - return stream.str(); - }) - .def_property_readonly("nr_rows", &storm::storage::SparseMatrix::getRowCount, "Number of rows") - .def_property_readonly("nr_columns", &storm::storage::SparseMatrix::getColumnCount, "Number of columns") - .def_property_readonly("nr_entries", &storm::storage::SparseMatrix::getEntryCount, "Number of non-zero entries") - .def_property_readonly("_row_group_indices", &storm::storage::SparseMatrix::getRowGroupIndices, "Starting rows of row groups") - .def("get_row", [](storm::storage::SparseMatrix& matrix, parametric_entry_index row) { - return matrix.getRows(row, row+1); - }, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row"), "Get row") - .def("get_rows", [](storm::storage::SparseMatrix& matrix, parametric_entry_index start, parametric_entry_index end) { - return matrix.getRows(start, end); - }, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row_start"), py::arg("row_end"), "Get rows from start to end") - .def("print_row", [](storm::storage::SparseMatrix const& matrix, parametric_entry_index row) { - std::stringstream stream; - auto rows = matrix.getRows(row, row+1); - for (auto transition : rows) { - stream << transition << ", "; - } - return stream.str(); - }, py::arg("row"), "Print row") - // Entry_index lead to problems - .def("row_iter", [](storm::storage::SparseMatrix& matrix, parametric_row_index start, parametric_row_index end) { - return py::make_iterator(matrix.begin(start), matrix.end(end)); - }, py::keep_alive<0, 1>() /* keep object alive while iterator exists */, py::arg("row_start"), py::arg("row_end"), "Get iterator from start to end") - ; - - // Rows - py::class_::rows>(m, "SparseMatrixRows", "Set of rows in a sparse matrix") - .def("__iter__", [](storm::storage::SparseMatrix::rows& rows) { - return py::make_iterator(rows.begin(), rows.end()); - }, py::keep_alive<0, 1>()) - .def("__str__", [](storm::storage::SparseMatrix::const_rows& rows) { - std::stringstream stream; - for (auto transition : rows) { - stream << transition << ", "; - } - return stream.str(); - }) - ; - - py::class_::rows>(m, "ParametricSparseMatrixRows", "Set of rows in a parametric sparse matrix") - .def("__iter__", [](storm::storage::SparseMatrix::rows& rows) { - return py::make_iterator(rows.begin(), rows.end()); - }, py::keep_alive<0, 1>()) - .def("__str__", [](storm::storage::SparseMatrix::const_rows& rows) { - std::stringstream stream; - for (auto transition : rows) { - stream << transition << ", "; - } - return stream.str(); - }) - ; -} diff --git a/stormpy/src/storage/matrix.h b/stormpy/src/storage/matrix.h deleted file mode 100644 index 96e3df676..000000000 --- a/stormpy/src/storage/matrix.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PYTHON_STORAGE_MATRIX_H_ -#define PYTHON_STORAGE_MATRIX_H_ - -#include "common.h" - -void define_sparse_matrix(py::module& m); - -#endif /* PYTHON_STORAGE_MATRIX_H_ */ diff --git a/stormpy/src/storage/model.cpp b/stormpy/src/storage/model.cpp deleted file mode 100644 index 02f32a57a..000000000 --- a/stormpy/src/storage/model.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "model.h" -#include "storm/models/ModelBase.h" -#include "storm/models/sparse/Model.h" -#include "storm/models/sparse/Dtmc.h" -#include "storm/models/sparse/Mdp.h" -#include "storm/models/sparse/StandardRewardModel.h" - -// Thin wrapper for getting initial states -template -std::vector getInitialStates(storm::models::sparse::Model const& model) { - std::vector initialStates; - for (auto entry : model.getInitialStates()) { - initialStates.push_back(entry); - } - return initialStates; -} - -// Thin wrapper for getting transition matrix -template -storm::storage::SparseMatrix& getTransitionMatrix(storm::models::sparse::Model& model) { - return model.getTransitionMatrix(); -} - -// Define python bindings -void define_model(py::module& m) { - - // ModelType - py::enum_(m, "ModelType", "Type of the model") - .value("DTMC", storm::models::ModelType::Dtmc) - .value("MDP", storm::models::ModelType::Mdp) - .value("CTMC", storm::models::ModelType::Ctmc) - .value("MA", storm::models::ModelType::MarkovAutomaton) - ; - - // ModelBase - py::class_>(m, "ModelBase", "Base class for all models") - .def_property_readonly("nr_states", &storm::models::ModelBase::getNumberOfStates, "Number of states") - .def_property_readonly("nr_transitions", &storm::models::ModelBase::getNumberOfTransitions, "Number of transitions") - .def_property_readonly("model_type", &storm::models::ModelBase::getType, "Model type") - .def_property_readonly("supports_parameters", &storm::models::ModelBase::supportsParameters, "Flag whether model supports parameters") - .def_property_readonly("has_parameters", &storm::models::ModelBase::hasParameters, "Flag whether model has parameters") - .def_property_readonly("is_exact", &storm::models::ModelBase::isExact, "Flag whether model is exact") - .def("as_dtmc", &storm::models::ModelBase::as>, "Get model as DTMC") - .def("as_pdtmc", &storm::models::ModelBase::as>, "Get model as pDTMC") - .def("as_mdp", &storm::models::ModelBase::as>, "Get model as MDP") - .def("as_pmdp", &storm::models::ModelBase::as>, "Get model as pMDP") - ; - - // Models - py::class_, std::shared_ptr>>(m, "SparseModel", "A probabilistic model where transitions are represented by doubles and saved in a sparse matrix", py::base()) - .def_property_readonly("labels", [](storm::models::sparse::Model& model) { - return model.getStateLabeling().getLabels(); - }, "Labels") - .def("labels_state", &storm::models::sparse::Model::getLabelsOfState, py::arg("state"), "Get labels of state") - .def_property_readonly("initial_states", &getInitialStates, "Initial states") - .def_property_readonly("transition_matrix", &getTransitionMatrix, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Transition matrix") - ; - py::class_, std::shared_ptr>>(m, "SparseDtmc", "DTMC in sparse representation", py::base>()) - ; - py::class_, std::shared_ptr>>(m, "SparseMdp", "MDP in sparse representation", py::base>()) - ; - - py::class_, std::shared_ptr>>(m, "SparseParametricModel", "A probabilistic model where transitions are represented by rational functions and saved in a sparse matrix", py::base()) - .def("collect_probability_parameters", &storm::models::sparse::getProbabilityParameters, "Collect parameters") - .def_property_readonly("labels", [](storm::models::sparse::Model& model) { - return model.getStateLabeling().getLabels(); - }, "Labels") - .def("labels_state", &storm::models::sparse::Model::getLabelsOfState, py::arg("state"), "Get labels of state") - .def_property_readonly("initial_states", &getInitialStates, "Initial states") - .def_property_readonly("transition_matrix", &getTransitionMatrix, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Transition matrix") - ; - py::class_, std::shared_ptr>>(m, "SparseParametricDtmc", "pDTMC in sparse representation", py::base>()) - ; - py::class_, std::shared_ptr>>(m, "SparseParametricMdp", "pMDP in sparse representation", py::base>()) - ; - -} diff --git a/stormpy/src/storage/model.h b/stormpy/src/storage/model.h deleted file mode 100644 index c779f26e7..000000000 --- a/stormpy/src/storage/model.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PYTHON_STORAGE_MODEL_H_ -#define PYTHON_STORAGE_MODEL_H_ - -#include "common.h" - -void define_model(py::module& m); - -#endif /* PYTHON_STORAGE_MODEL_H_ */ diff --git a/stormpy/tests/.gitignore b/stormpy/tests/.gitignore deleted file mode 100644 index bee8a64b7..000000000 --- a/stormpy/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -__pycache__ diff --git a/stormpy/tests/conftest.py b/stormpy/tests/conftest.py deleted file mode 100644 index 5e85fe646..000000000 --- a/stormpy/tests/conftest.py +++ /dev/null @@ -1,3 +0,0 @@ -import sys -import os -sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers')) diff --git a/stormpy/tests/core/test_bisimulation.py b/stormpy/tests/core/test_bisimulation.py deleted file mode 100644 index 3776f54d2..000000000 --- a/stormpy/tests/core/test_bisimulation.py +++ /dev/null @@ -1,39 +0,0 @@ -import stormpy -import stormpy.logic -from helpers.helper import get_example_path - -class TestBisimulation: - def test_bisimulation(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "crowds5_5.pm")) - assert program.nr_modules == 1 - assert program.model_type == stormpy.PrismModelType.DTMC - prop = "P=? [F \"observe0Greater1\"]" - formulas = stormpy.parse_formulas_for_prism_program(prop, program) - model = stormpy.build_model_from_prism_program(program, formulas) - assert model.nr_states == 7403 - assert model.nr_transitions == 13041 - assert model.model_type == stormpy.ModelType.DTMC - assert not model.supports_parameters - model_bisim = stormpy.perform_bisimulation(model, formulas[0], stormpy.BisimulationType.STRONG) - assert model_bisim.nr_states == 64 - assert model_bisim.nr_transitions == 104 - assert model_bisim.model_type == stormpy.ModelType.DTMC - assert not model_bisim.supports_parameters - - def test_parametric_bisimulation(self): - program = stormpy.parse_prism_program(get_example_path("pdtmc", "crowds3_5.pm")) - assert program.nr_modules == 1 - assert program.model_type == stormpy.PrismModelType.DTMC - assert program.has_undefined_constants - prop = "P=? [F \"observe0Greater1\"]" - formulas = stormpy.parse_formulas_for_prism_program(prop, program) - model = stormpy.build_parametric_model_from_prism_program(program, formulas) - assert model.nr_states == 1367 - assert model.nr_transitions == 2027 - assert model.model_type == stormpy.ModelType.DTMC - assert model.has_parameters - model_bisim = stormpy.perform_bisimulation(model, formulas[0], stormpy.BisimulationType.STRONG) - assert model_bisim.nr_states == 80 - assert model_bisim.nr_transitions == 120 - assert model_bisim.model_type == stormpy.ModelType.DTMC - assert model_bisim.has_parameters diff --git a/stormpy/tests/core/test_core.py b/stormpy/tests/core/test_core.py deleted file mode 100644 index cedd750eb..000000000 --- a/stormpy/tests/core/test_core.py +++ /dev/null @@ -1,14 +0,0 @@ - -class TestCore: - def test_init(self): - import stormpy - - def test_pycarl(self): - import stormpy - import pycarl - import pycarl.formula - import pycarl.parse - pol1 = pycarl.FactorizedPolynomial(32) - pol2 = pycarl.FactorizedPolynomial(2) - rat = pycarl.FactorizedRationalFunction(pol1, pol2) - assert str(rat) == "16" diff --git a/stormpy/tests/core/test_modelchecking.py b/stormpy/tests/core/test_modelchecking.py deleted file mode 100644 index 56ccdc93e..000000000 --- a/stormpy/tests/core/test_modelchecking.py +++ /dev/null @@ -1,45 +0,0 @@ -import stormpy -import stormpy.logic -from helpers.helper import get_example_path - -class TestModelChecking: - def test_model_checking_dtmc(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F \"one\" ]", program) - model = stormpy.build_model(program, formulas[0]) - assert model.nr_states == 13 - assert model.nr_transitions == 20 - result = stormpy.model_checking(model, formulas[0]) - assert result == 0.16666666666666663 - - def test_model_checking_all_dtmc(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F \"one\" ]", program) - model = stormpy.build_model(program, formulas[0]) - assert model.nr_states == 13 - assert model.nr_transitions == 20 - results = stormpy.model_checking_all(model, formulas[0]) - results_orig = [0.16666666666666663, 0.3333333333333333, 0, 0.6666666666666666, 0, 0, 0, 1, 0, 0, 0, 0, 0] - assert results == results_orig - - def test_parametric_state_elimination(self): - import pycarl - import pycarl.formula - program = stormpy.parse_prism_program(get_example_path("pdtmc", "brp16_2.pm")) - prop = "P=? [F s=5]" - formulas = stormpy.parse_formulas_for_prism_program(prop, program) - model = stormpy.build_parametric_model_from_prism_program(program, formulas) - assert model.nr_states == 613 - assert model.nr_transitions == 803 - assert model.model_type == stormpy.ModelType.DTMC - assert model.has_parameters - result = stormpy.model_checking(model, formulas[0]) - func = result.result_function - one = pycarl.FactorizedPolynomial(pycarl.Rational(1)) - assert func.denominator == one - constraints_well_formed = result.constraints_well_formed - for constraint in constraints_well_formed: - assert constraint.rel() == pycarl.formula.Relation.GEQ or constraint.rel() == pycarl.formula.Relation.LEQ - constraints_graph_preserving = result.constraints_graph_preserving - for constraint in constraints_graph_preserving: - assert constraint.rel() == pycarl.formula.Relation.GREATER diff --git a/stormpy/tests/core/test_parse.py b/stormpy/tests/core/test_parse.py deleted file mode 100644 index 83aff42e1..000000000 --- a/stormpy/tests/core/test_parse.py +++ /dev/null @@ -1,32 +0,0 @@ -import stormpy -import stormpy.logic -from helpers.helper import get_example_path - -class TestParse: - def test_parse_prism_program(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - assert program.nr_modules == 1 - assert program.model_type == stormpy.PrismModelType.DTMC - assert not program.has_undefined_constants - - def test_parse_formula(self): - prop = "P=? [F \"one\"]" - formulas = stormpy.parse_formulas(prop) - assert len(formulas) == 1 - assert str(formulas[0]) == prop - - def test_parse_explicit_dtmc(self): - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - assert model.nr_states == 13 - assert model.nr_transitions == 20 - assert model.model_type == stormpy.ModelType.DTMC - assert not model.supports_parameters - assert type(model) is stormpy.SparseDtmc - - def test_parse_explicit_mdp(self): - model = stormpy.parse_explicit_model(get_example_path("mdp", "two_dice.tra"), get_example_path("mdp", "two_dice.lab")) - assert model.nr_states == 169 - assert model.nr_transitions == 436 - assert model.model_type == stormpy.ModelType.MDP - assert not model.supports_parameters - assert type(model) is stormpy.SparseMdp diff --git a/stormpy/tests/expressions/test_expressions.py b/stormpy/tests/expressions/test_expressions.py deleted file mode 100644 index 823186d62..000000000 --- a/stormpy/tests/expressions/test_expressions.py +++ /dev/null @@ -1,9 +0,0 @@ -import stormpy -from stormpy.expressions import expressions - -class TestExpressions: - def test_expression_manager(self): - manager = expressions.ExpressionManager - - def test_expression(self): - expression = expressions.Expression diff --git a/stormpy/tests/helpers/helper.py b/stormpy/tests/helpers/helper.py deleted file mode 100644 index a7c2d295c..000000000 --- a/stormpy/tests/helpers/helper.py +++ /dev/null @@ -1,5 +0,0 @@ -import os -example_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, "resources", "examples", "testfiles")) - -def get_example_path(*paths): - return os.path.join(example_dir, *paths) diff --git a/stormpy/tests/info/test_info.py b/stormpy/tests/info/test_info.py deleted file mode 100644 index fd91d68d7..000000000 --- a/stormpy/tests/info/test_info.py +++ /dev/null @@ -1,8 +0,0 @@ -import stormpy -from stormpy.info import info - -class TestInfo: - def test_version(self): - s = info.Version.short - s = info.Version.long - s = info.Version.build_info diff --git a/stormpy/tests/logic/test_formulas.py b/stormpy/tests/logic/test_formulas.py deleted file mode 100644 index 1bb697ce3..000000000 --- a/stormpy/tests/logic/test_formulas.py +++ /dev/null @@ -1,51 +0,0 @@ -import pycarl -import stormpy -import stormpy.logic - -class TestFormulas: - - def test_probability_formula(self): - prop = "P=? [F \"one\"]" - formulas = stormpy.parse_formulas(prop) - formula = formulas[0] - assert type(formula) == stormpy.logic.ProbabilityOperator - assert len(formulas) == 1 - assert str(formula) == prop - - def test_reward_formula(self): - prop = "R=? [F \"one\"]" - formulas = stormpy.parse_formulas(prop) - formula = formulas[0] - assert type(formula) == stormpy.logic.RewardOperator - assert len(formulas) == 1 - assert str(formula) == "R[exp]=? [F \"one\"]" - - def test_formula_list(self): - formulas = [] - prop = "=? [F \"one\"]" - forms = stormpy.parse_formulas("P" + prop) - formulas.append(forms[0]) - forms = stormpy.parse_formulas("R" + prop) - formulas.append(forms[0]) - assert len(formulas) == 2 - assert str(formulas[0]) == "P" + prop - assert str(formulas[1]) == "R[exp]" + prop - - def test_bounds(self): - prop = "P=? [F \"one\"]" - formula = stormpy.parse_formulas(prop)[0] - assert not formula.has_bound - prop = "P<0.4 [F \"one\"]" - formula = stormpy.parse_formulas(prop)[0] - assert formula.has_bound - assert formula.threshold == pycarl.Rational("0.4") - assert formula.comparison_type == stormpy.logic.ComparisonType.LESS - - def test_set_bounds(self): - prop = "P<0.4 [F \"one\"]" - formula = stormpy.parse_formulas(prop)[0] - formula.threshold = pycarl.Rational("0.2") - formula.comparison_type = stormpy.logic.ComparisonType.GEQ - assert formula.threshold == pycarl.Rational("0.2") - assert formula.comparison_type == stormpy.logic.ComparisonType.GEQ - assert str(formula) == "P>=1/5 [F \"one\"]" diff --git a/stormpy/tests/storage/test_matrix.py b/stormpy/tests/storage/test_matrix.py deleted file mode 100644 index e6e2e6360..000000000 --- a/stormpy/tests/storage/test_matrix.py +++ /dev/null @@ -1,96 +0,0 @@ -import stormpy -from helpers.helper import get_example_path - -class TestMatrix: - def test_sparse_matrix(self): - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - matrix = model.transition_matrix - assert type(matrix) is stormpy.storage.SparseMatrix - assert matrix.nr_rows == model.nr_states - assert matrix.nr_columns == model.nr_states - assert matrix.nr_entries == 27 #model.nr_transitions - for e in matrix: - assert e.value() == 0.5 or e.value() == 0 or (e.value() == 1 and e.column > 6) - - def test_change_sparse_matrix(self): - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - matrix = model.transition_matrix - for e in matrix: - assert e.value() == 0.5 or e.value() == 0 or e.value() == 1 - i = 0 - for e in matrix: - e.set_value(i) - i += 0.1 - i = 0 - for e in matrix: - assert e.value() == i - i += 0.1 - - def test_change_sparse_matrix_modelchecking(self): - import stormpy.logic - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - matrix = model.transition_matrix - # Check matrix - for e in matrix: - assert e.value() == 0.5 or e.value() == 0 or e.value() == 1 - # First model checking - formulas = stormpy.parse_formulas("P=? [ F \"one\" ]") - result = stormpy.model_checking(model, formulas[0]) - assert result == 0.16666666666666663 - - # Change probabilities - i = 0 - for e in matrix: - if e.value() == 0.5: - if i % 2 == 0: - e.set_value(0.3) - else: - e.set_value(0.7) - i += 1 - for e in matrix: - assert e.value() == 0.3 or e.value() == 0.7 or e.value() == 1 or e.value() == 0 - # Second model checking - result = stormpy.model_checking(model, formulas[0]) - assert result == 0.06923076923076932 - - # Change probabilities again - for state in stormpy.state.State(0, model): - for action in state.actions(): - for transition in action.transitions(): - if transition.value() == 0.3: - transition.set_value(0.8) - elif transition.value() == 0.7: - transition.set_value(0.2) - # Third model checking - result = stormpy.model_checking(model, formulas[0]) - assert result == 0.3555555555555556 or result == 0.3555555555555557 - - def test_change_parametric_sparse_matrix_modelchecking(self): - import stormpy.logic - import pycarl - program = stormpy.parse_prism_program(get_example_path("pdtmc", "brp16_2.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F s=5 ]", program) - model = stormpy.build_parametric_model(program, formulas[0]) - matrix = model.transition_matrix - # Check matrix - one_pol = pycarl.Rational(1) - one_pol = pycarl.FactorizedPolynomial(one_pol) - one = pycarl.FactorizedRationalFunction(one_pol, one_pol) - for e in matrix: - assert e.value() == one or len(e.value().gather_variables()) > 0 - # First model checking - result = stormpy.model_checking(model, formulas[0]) - assert len(result.result_function.gather_variables()) > 0 - - # Change probabilities - two_pol = pycarl.Rational(2) - two_pol = pycarl.FactorizedPolynomial(two_pol) - new_val = pycarl.FactorizedRationalFunction(one_pol, two_pol) - for e in matrix: - if len(e.value().gather_variables()) > 0: - e.set_value(new_val) - for e in matrix: - assert e.value() == new_val or e.value() == one - # Second model checking - result = stormpy.model_checking(model, formulas[0]) - assert len(result.result_function.gather_variables()) == 0 diff --git a/stormpy/tests/storage/test_model.py b/stormpy/tests/storage/test_model.py deleted file mode 100644 index 44a4c9c0e..000000000 --- a/stormpy/tests/storage/test_model.py +++ /dev/null @@ -1,96 +0,0 @@ -import stormpy -import stormpy.logic -from helpers.helper import get_example_path - -class TestModel: - def test_build_dtmc_from_prism_program(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - prop = "P=? [F \"one\"]" - formulas = stormpy.parse_formulas_for_prism_program(prop, program) - model = stormpy.build_model_from_prism_program(program, formulas) - assert model.nr_states == 13 - assert model.nr_transitions == 20 - assert model.model_type == stormpy.ModelType.DTMC - assert not model.supports_parameters - assert type(model) is stormpy.SparseDtmc - - def test_build_parametric_dtmc_from_prism_program(self): - program = stormpy.parse_prism_program(get_example_path("pdtmc", "brp16_2.pm")) - assert program.nr_modules == 5 - assert program.model_type == stormpy.PrismModelType.DTMC - assert program.has_undefined_constants - prop = "P=? [F s=5]" - formulas = stormpy.parse_formulas_for_prism_program(prop, program) - model = stormpy.build_parametric_model_from_prism_program(program, formulas) - assert model.nr_states == 613 - assert model.nr_transitions == 803 - assert model.model_type == stormpy.ModelType.DTMC - assert model.supports_parameters - assert model.has_parameters - assert type(model) is stormpy.SparseParametricDtmc - - def test_build_dtmc(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F \"one\" ]", program) - model = stormpy.build_model(program, formulas[0]) - assert model.nr_states == 13 - assert model.nr_transitions == 20 - assert model.model_type == stormpy.ModelType.DTMC - assert not model.supports_parameters - assert type(model) is stormpy.SparseDtmc - - def test_build_parametric_dtmc(self): - program = stormpy.parse_prism_program(get_example_path("pdtmc", "brp16_2.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F s=5 ]", program) - model = stormpy.build_parametric_model(program, formulas[0]) - assert model.nr_states == 613 - assert model.nr_transitions == 803 - assert model.model_type == stormpy.ModelType.DTMC - assert model.supports_parameters - assert model.has_parameters - assert type(model) is stormpy.SparseParametricDtmc - - def test_build_dtmc_supporting_parameters(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F \"one\" ]", program) - model = stormpy.build_parametric_model(program, formulas[0]) - assert model.nr_states == 13 - assert model.nr_transitions == 20 - assert model.model_type == stormpy.ModelType.DTMC - assert model.supports_parameters - assert not model.has_parameters - assert type(model) is stormpy.SparseParametricDtmc - - def test_label(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F \"one\" ]", program) - model = stormpy.build_model(program, formulas[0]) - labels = model.labels - assert len(labels) == 3 - assert "init" in labels - assert "one" in labels - assert "init" in model.labels_state(0) - assert "one" in model.labels_state(7) - - def test_initial_states(self): - program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F \"one\" ]", program) - model = stormpy.build_model(program, formulas[0]) - initial_states = model.initial_states - assert len(initial_states) == 1 - assert 0 in initial_states - - def test_label_parametric(self): - program = stormpy.parse_prism_program(get_example_path("pdtmc", "brp16_2.pm")) - formulas = stormpy.parse_formulas_for_prism_program("P=? [ F s=5 ]", program) - model = stormpy.build_parametric_model(program, formulas[0]) - labels = model.labels - assert len(labels) == 3 - assert "init" in labels - assert "(s = 5)" in labels - assert "init" in model.labels_state(0) - assert "(s = 5)" in model.labels_state(28) - assert "(s = 5)" in model.labels_state(611) - initial_states = model.initial_states - assert len(initial_states) == 1 - assert 0 in initial_states diff --git a/stormpy/tests/storage/test_model_iterators.py b/stormpy/tests/storage/test_model_iterators.py deleted file mode 100644 index 8023b86d0..000000000 --- a/stormpy/tests/storage/test_model_iterators.py +++ /dev/null @@ -1,82 +0,0 @@ -import stormpy -from helpers.helper import get_example_path - -class TestModelIterators: - def test_states_dtmc(self): - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - s = stormpy.state.State(0, model) - i = 0 - for state in stormpy.state.State(0, model): - assert state.id == i - i += 1 - assert i == model.nr_states - - def test_states_mdp(self): - model = stormpy.parse_explicit_model(get_example_path("mdp", "two_dice.tra"), get_example_path("mdp", "two_dice.lab")) - s = stormpy.state.State(0, model) - i = 0 - for state in stormpy.state.State(0, model): - assert state.id == i - i += 1 - assert i == model.nr_states - - def test_actions_dtmc(self): - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - s = stormpy.state.State(0, model) - for state in stormpy.state.State(0, model): - for action in state.actions(): - assert action.row == 0 - - def test_actions_mdp(self): - model = stormpy.parse_explicit_model(get_example_path("mdp", "two_dice.tra"), get_example_path("mdp", "two_dice.lab")) - s = stormpy.state.State(0, model) - for state in stormpy.state.State(0, model): - for action in state.actions(): - assert action.row == 0 or action.row == 1 - - def test_transitions_dtmc(self): - transitions_orig = [(0, 0, 0), (0, 1, 0.5), (0, 2, 0.5), (1, 1, 0), (1, 3, 0.5), (1, 4, 0.5), - (2, 2, 0), (2, 5, 0.5), (2, 6, 0.5), (3, 1, 0.5), (3, 3, 0), (3, 7, 0.5), - (4, 4, 0), (4, 8, 0.5), (4, 9, 0.5), (5, 5, 0), (5, 10, 0.5), (5, 11, 0.5), - (6, 2, 0.5), (6, 6, 0), (6, 12, 0.5), (7, 7, 1), (8, 8, 1), - (9, 9, 1), (10, 10, 1), (11, 11, 1), (12, 12, 1) - ] - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - s = stormpy.state.State(0, model) - i = 0 - for state in stormpy.state.State(0, model): - for action in state.actions(): - for transition in action.transitions(): - transition_orig = transitions_orig[i] - i += 1 - assert state.id == transition_orig[0] - assert transition.column == transition_orig[1] - assert transition.value() == transition_orig[2] - - def test_transitions_mdp(self): - model = stormpy.parse_explicit_model(get_example_path("mdp", "two_dice.tra"), get_example_path("mdp", "two_dice.lab")) - s = stormpy.state.State(0, model) - for state in stormpy.state.State(0, model): - i = 0 - for action in state.actions(): - i += 1 - for transition in action.transitions(): - assert transition.value() == 0.5 or transition.value() == 1 - assert i == 1 or i == 2 - - def test_row_iterator(self): - transitions_orig = [(0, 0, 0), (0, 1, 0.5), (0, 2, 0.5), (1, 1, 0), (1, 3, 0.5), (1, 4, 0.5), - (2, 2, 0), (2, 5, 0.5), (2, 6, 0.5), (3, 1, 0.5), (3, 3, 0), (3, 7, 0.5), - (4, 4, 0), (4, 8, 0.5), (4, 9, 0.5), (5, 5, 0), (5, 10, 0.5), (5, 11, 0.5), - (6, 2, 0.5), (6, 6, 0), (6, 12, 0.5), (7, 7, 1), (8, 8, 1), - (9, 9, 1), (10, 10, 1), (11, 11, 1), (12, 12, 1) - ] - model = stormpy.parse_explicit_model(get_example_path("dtmc", "die.tra"), get_example_path("dtmc", "die.lab")) - i = 0 - for state in stormpy.state.State(0, model): - for transition in model.transition_matrix.row_iter(state.id, state.id): - transition_orig = transitions_orig[i] - i += 1 - assert state.id == transition_orig[0] - assert transition.column == transition_orig[1] - assert transition.value() == transition_orig[2]